commit b0605a28a9af06cc080aa65f9b1f86071128a40b Author: phlux Date: Wed Oct 8 11:12:59 2025 -0400 First commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..fcd28fd --- /dev/null +++ b/README.md @@ -0,0 +1,207 @@ +# LDAP to OAuth2 Bridge + +A lightweight LDAP server that authenticates users against an OAuth2/OIDC provider (such as Keycloak). This bridge allows legacy applications that only support LDAP authentication to work with modern OAuth2 identity providers. + +## Overview + +This bridge presents an LDAP interface to applications while performing OAuth2 Resource Owner Password Credentials (ROPC) flow authentication against your identity provider in the background. + +**Use Case**: Integrate applications like TheLounge IRC client, which only support LDAP authentication, with Keycloak or other OAuth2/OIDC providers. + +## Features + +- Lightweight Node.js implementation +- Simple LDAP bind operation support +- OAuth2 Resource Owner Password Credentials flow +- Configurable base DN +- Easy integration with Keycloak and other OIDC providers +- FreeBSD service support (includes rc.d script) + +## Requirements + +- Node.js 14+ and npm +- An OAuth2/OIDC provider (Keycloak, Auth0, etc.) +- A client configured with Direct Access Grants enabled + +## Installation + +### 1. Clone the repository + +```bash +git clone https://your-gitea-instance.com/ldap-to-oauth2.git +cd ldap-to-oauth2 +``` + +### 2. Install dependencies + +```bash +npm install +``` + +### 3. Configure OAuth2 Provider + +#### For Keycloak: + +1. Create a new client in your realm +2. Set **Access Type** to `confidential` +3. Enable **Direct Access Grants Enabled** +4. Save and retrieve the client secret from the Credentials tab + +#### For other providers: + +Ensure your OAuth2 provider supports the Resource Owner Password Credentials grant type. + +### 4. Configure the bridge + +Edit `server.js` and update the configuration section: + +```javascript +const LDAP_PORT = 3893; +const KEYCLOAK_URL = 'https://your-keycloak-domain.com'; +const KEYCLOAK_REALM = 'your-realm'; +const KEYCLOAK_CLIENT_ID = 'your-client-id'; +const KEYCLOAK_CLIENT_SECRET = 'your-client-secret'; +const BASE_DN = 'dc=example,dc=com'; +``` + +### 5. Run the server + +```bash +node server.js +``` + +## Testing + +Test authentication using `ldapsearch`: + +```bash +ldapsearch -H ldap://localhost:3893 \ + -D "cn=username,dc=example,dc=com" \ + -W \ + -b "dc=example,dc=com" +``` + +Replace `username` with a valid username from your OAuth2 provider. + +## FreeBSD Service Installation + +### 1. Copy files to system directories + +```bash +# Copy application files +cp -r ldap-to-oauth2 /usr/local/ldap-oauth-bridge + +# Copy RC script +cp ldap_oauth_bridge.rc /usr/local/etc/rc.d/ldap_oauth_bridge +chmod +x /usr/local/etc/rc.d/ldap_oauth_bridge +``` + +### 2. Enable and start service + +```bash +echo 'ldap_oauth_bridge_enable="YES"' >> /etc/rc.conf +service ldap_oauth_bridge start +``` + +### 3. Check service status + +```bash +service ldap_oauth_bridge status +sockstat -l | grep 3893 +``` + +## Configuration Examples + +### TheLounge IRC Client + +In `config.js`: + +```javascript +ldap: { + enable: true, + url: "ldap://your-server:3893", + baseDN: "dc=example,dc=com", + searchDN: { + rootDN: "cn=admin,dc=example,dc=com", + rootPassword: "dummy", + filter: "(|(uid=%s)(cn=%s))" + } +} +``` + +### Generic LDAP Application + +- **LDAP Server**: `ldap://your-server:3893` +- **Base DN**: `dc=example,dc=com` +- **Bind DN Format**: `cn=USERNAME,dc=example,dc=com` + +Users authenticate with their OAuth2 provider username and password. + +## How It Works + +1. Application sends LDAP BIND request with username and password +2. Bridge extracts username from the LDAP DN (e.g., `cn=alice,dc=example,dc=com` → `alice`) +3. Bridge performs OAuth2 password grant flow with the identity provider +4. If OAuth2 authentication succeeds, LDAP BIND succeeds +5. If OAuth2 authentication fails, LDAP BIND fails + +## Security Considerations + +- **Transport Security**: Use LDAPS (LDAP over TLS) in production or ensure the bridge runs on a trusted network +- **Port < 1024**: Requires root privileges on Unix systems. Consider using port 3893 or higher to avoid running as root +- **Password Grant Flow**: The Resource Owner Password Credentials flow passes passwords to the bridge. Ensure secure communication channels +- **Network Isolation**: Run the bridge on the same network as your applications or use VPN/tunneling + +## Limitations + +- Only supports LDAP BIND operations (authentication only) +- Does not provide a full LDAP directory (no user enumeration, group queries, etc.) +- Search operations return empty results +- Requires OAuth2 provider to support Resource Owner Password Credentials grant + +## Troubleshooting + +### Authentication fails + +1. Check server logs for detailed error messages +2. Verify OAuth2 client credentials are correct +3. Ensure Direct Access Grants are enabled in your OAuth2 client +4. Test OAuth2 authentication directly using curl: + +```bash +curl -X POST https://your-keycloak/realms/your-realm/protocol/openid-connect/token \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "grant_type=password" \ + -d "client_id=your-client-id" \ + -d "client_secret=your-client-secret" \ + -d "username=testuser" \ + -d "password=testpass" +``` + +### Connection refused + +- Verify the server is running: `sockstat -l | grep 3893` +- Check firewall rules +- Ensure the application can reach the bridge server + +### DN parsing errors + +- Ensure username is formatted as `cn=username,dc=example,dc=com` or `uid=username,dc=example,dc=com` +- Check server logs for DN parsing details + +## License + +MIT License - See LICENSE file for details + +## Contributing + +Contributions are welcome! Please submit pull requests or open issues on the repository. + +## Author + +Created for use with TheLounge IRC client and Keycloak authentication. + +## Acknowledgments + +- Built with [ldapjs](https://github.com/ldapjs/node-ldapjs) +- OAuth2 requests powered by [axios](https://github.com/axios/axios) diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json new file mode 100644 index 0000000..fd9f3c0 --- /dev/null +++ b/node_modules/.package-lock.json @@ -0,0 +1,516 @@ +{ + "name": "ldap-oauth-bridge", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@ldapjs/asn1": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-2.0.0.tgz", + "integrity": "sha512-G9+DkEOirNgdPmD0I8nu57ygQJKOOgFEMKknEuQvIHbGLwP3ny1mY+OTUYLCbCaGJP4sox5eYgBJRuSUpnAddA==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT" + }, + "node_modules/@ldapjs/attribute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/attribute/-/attribute-1.0.0.tgz", + "integrity": "sha512-ptMl2d/5xJ0q+RgmnqOi3Zgwk/TMJYG7dYMC0Keko+yZU6n+oFM59MjQOUht5pxJeS4FWrImhu/LebX24vJNRQ==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/change": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/change/-/change-1.0.0.tgz", + "integrity": "sha512-EOQNFH1RIku3M1s0OAJOzGfAohuFYXFY4s73wOhRm4KFGhmQQ7MChOh2YtYu9Kwgvuq1B0xKciXVzHCGkB5V+Q==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0" + } + }, + "node_modules/@ldapjs/controls": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/controls/-/controls-2.1.0.tgz", + "integrity": "sha512-2pFdD1yRC9V9hXfAWvCCO2RRWK9OdIEcJIos/9cCVP9O4k72BY1bLDQQ4KpUoJnl4y/JoD4iFgM+YWT3IfITWw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "^1.2.0", + "@ldapjs/protocol": "^1.2.1" + } + }, + "node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-1.2.0.tgz", + "integrity": "sha512-KX/qQJ2xxzvO2/WOvr1UdQ+8P5dVvuOLk/C9b1bIkXxZss8BaR28njXdPgFCpj5aHaf1t8PmuVnea+N9YG9YMw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT" + }, + "node_modules/@ldapjs/dn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/dn/-/dn-1.1.0.tgz", + "integrity": "sha512-R72zH5ZeBj/Fujf/yBu78YzpJjJXG46YHFo5E4W1EqfNpo1UsVPqdLrRMXeKIsJT3x9dJVIfR6OpzgINlKpi0A==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/filter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ldapjs/filter/-/filter-2.1.1.tgz", + "integrity": "sha512-TwPK5eEgNdUO1ABPBUQabcZ+h9heDORE4V9WNZqCtYLKc06+6+UAJ3IAbr0L0bYTnkkWC/JEQD2F+zAFsuikNw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/messages": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ldapjs/messages/-/messages-1.3.0.tgz", + "integrity": "sha512-K7xZpXJ21bj92jS35wtRbdcNrwmxAtPwy4myeh9duy/eR3xQKvikVycbdWVzkYEAVE5Ce520VXNOwCHjomjCZw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.2.0" + } + }, + "node_modules/@ldapjs/protocol": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ldapjs/protocol/-/protocol-1.2.1.tgz", + "integrity": "sha512-O89xFDLW2gBoZWNXuXpBSM32/KealKCTb3JGtJdtUQc7RjAk8XzrRgyz02cPAwGKwKPxy0ivuC7UP9bmN87egQ==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT" + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "license": "MIT", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ldapjs": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-3.0.7.tgz", + "integrity": "sha512-1ky+WrN+4CFMuoekUOv7Y1037XWdjKpu0xAPwSP+9KdvmV9PG+qOKlssDV6a+U32apwxdD3is/BZcWOYzN30cg==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/messages": "^1.3.0", + "@ldapjs/protocol": "^1.2.1", + "abstract-logging": "^2.0.1", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "once": "^1.4.0", + "vasync": "^2.2.1", + "verror": "^1.10.1" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process-warning": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/vasync": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.1.tgz", + "integrity": "sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "verror": "1.10.0" + } + }, + "node_modules/vasync/node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/node_modules/@ldapjs/asn1/.eslintrc b/node_modules/@ldapjs/asn1/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/asn1/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/asn1/.github/workflows/main.yml b/node_modules/@ldapjs/asn1/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/asn1/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/asn1/.taprc.yml b/node_modules/@ldapjs/asn1/.taprc.yml new file mode 100644 index 0000000..ff62386 --- /dev/null +++ b/node_modules/@ldapjs/asn1/.taprc.yml @@ -0,0 +1,6 @@ +reporter: terse +coverage-map: coverage-map.js + +files: + - 'index.test.js' + - 'lib/**/*.test.js' diff --git a/node_modules/@ldapjs/asn1/CONTRIBUTING.md b/node_modules/@ldapjs/asn1/CONTRIBUTING.md new file mode 100644 index 0000000..79e8ce2 --- /dev/null +++ b/node_modules/@ldapjs/asn1/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Contributing + +This repository uses GitHub pull requests for code review. + +See [this primer](https://jrfom.com/posts/2017/03/08/a-primer-on-contributing-to-projects-with-git/) +for instructions on how to make contributions to the project. + +If you're changing something non-trivial or user-facing, you may want to submit +an issue first. diff --git a/node_modules/@ldapjs/asn1/LICENSE b/node_modules/@ldapjs/asn1/LICENSE new file mode 100644 index 0000000..1913201 --- /dev/null +++ b/node_modules/@ldapjs/asn1/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2011 Mark Cavage, All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/asn1/README.md b/node_modules/@ldapjs/asn1/README.md new file mode 100644 index 0000000..a0c2901 --- /dev/null +++ b/node_modules/@ldapjs/asn1/README.md @@ -0,0 +1,43 @@ +# `@ldapjs/asn1` + +`@ldapjs/asn1` is a library for encoding and decoding ASN.1 datatypes in pure +JS. Currently BER encoding is supported. + +### Decoding + +The following reads an ASN.1 sequence with a boolean. + +```js +const { BerReader, BerTypes } = require('@ldapjs/asn1') +const reader = new BerReader(Buffer.from([0x30, 0x03, 0x01, 0x01, 0xff])) + +reader.readSequence() +console.log('Sequence len: ' + reader.length) +if (reader.peek() === BerTypes.Boolean) +console.log(reader.readBoolean()) +``` + +### Encoding + +The following generates the same payload as above. + +```js +const { BerWriter } = require('@ldapjs/asn1'); +const writer = new BerWriter(); + +writer.startSequence(); +writer.writeBoolean(true); +writer.endSequence(); + +console.log(writer.buffer); +``` + +## Installation + +```sh +npm install @ldapjs/asn1 +``` + +## Bugs + +See . diff --git a/node_modules/@ldapjs/asn1/coverage-map.js b/node_modules/@ldapjs/asn1/coverage-map.js new file mode 100644 index 0000000..fc2046a --- /dev/null +++ b/node_modules/@ldapjs/asn1/coverage-map.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = testFile => testFile.replace(/\.test\.js$/, '.js') diff --git a/node_modules/@ldapjs/asn1/index.js b/node_modules/@ldapjs/asn1/index.js new file mode 100644 index 0000000..4fb82ce --- /dev/null +++ b/node_modules/@ldapjs/asn1/index.js @@ -0,0 +1,13 @@ +'use strict' + +const BerReader = require('./lib/ber/reader') +const BerWriter = require('./lib/ber/writer') +const BerTypes = require('./lib/ber/types') +const bufferToHexDump = require('./lib/buffer-to-hex-dump') + +module.exports = { + BerReader, + BerTypes, + BerWriter, + bufferToHexDump +} diff --git a/node_modules/@ldapjs/asn1/index.test.js b/node_modules/@ldapjs/asn1/index.test.js new file mode 100644 index 0000000..172c8b8 --- /dev/null +++ b/node_modules/@ldapjs/asn1/index.test.js @@ -0,0 +1,28 @@ +'use strict' + +const tap = require('tap') +const asn1 = require('./index') + +tap.test('exports BerReader', async t => { + const { BerReader } = asn1 + t.ok(BerReader) + + const reader = new BerReader(Buffer.from([0x00])) + t.type(reader, BerReader) + t.equal(Object.prototype.toString.call(reader), '[object BerReader]') +}) + +tap.test('exports BerTypes', async t => { + const { BerTypes } = asn1 + t.type(BerTypes, Object) + t.equal(BerTypes.LDAPSequence, 0x30) +}) + +tap.test('exports BerWriter', async t => { + const { BerWriter } = asn1 + t.ok(BerWriter) + + const writer = new BerWriter() + t.type(writer, BerWriter) + t.equal(Object.prototype.toString.call(writer), '[object BerWriter]') +}) diff --git a/node_modules/@ldapjs/asn1/lib/ber/index.js b/node_modules/@ldapjs/asn1/lib/ber/index.js new file mode 100644 index 0000000..21a12cd --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/ber/index.js @@ -0,0 +1,24 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +const errors = require('./errors') +const types = require('./types') + +const Reader = require('./reader') +const Writer = require('./writer') + +// --- Exports + +module.exports = { + + Reader, + + Writer + +} + +for (const t in types) { + if (Object.prototype.hasOwnProperty.call(types, t)) { module.exports[t] = types[t] } +} +for (const e in errors) { + if (Object.prototype.hasOwnProperty.call(errors, e)) { module.exports[e] = errors[e] } +} diff --git a/node_modules/@ldapjs/asn1/lib/ber/reader.js b/node_modules/@ldapjs/asn1/lib/ber/reader.js new file mode 100644 index 0000000..1a7be57 --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/ber/reader.js @@ -0,0 +1,502 @@ +'use strict' + +const types = require('./types') +const bufferToHexDump = require('../buffer-to-hex-dump') + +/** + * Given a buffer of ASN.1 data encoded according to Basic Encoding Rules (BER), + * the reader provides methods for iterating that data and decoding it into + * regular JavaScript types. + */ +class BerReader { + /** + * The source buffer as it was passed in when creating the instance. + * + * @type {Buffer} + */ + #buffer + + /** + * The total bytes in the backing buffer. + * + * @type {number} + */ + #size + + /** + * An ASN.1 field consists of a tag, a length, and a value. This property + * records the length of the current field. + * + * @type {number} + */ + #currentFieldLength = 0 + + /** + * Records the offset in the buffer where the most recent {@link readSequence} + * was invoked. This is used to facilitate slicing of whole sequences from + * the buffer as a new {@link BerReader} instance. + * + * @type {number} + */ + #currentSequenceStart = 0 + + /** + * As the BER buffer is read, this property records the current position + * in the buffer. + * + * @type {number} + */ + #offset = 0 + + /** + * @param {Buffer} buffer + */ + constructor (buffer) { + if (Buffer.isBuffer(buffer) === false) { + throw TypeError('Must supply a Buffer instance to read.') + } + + this.#buffer = buffer.subarray(0) + this.#size = this.#buffer.length + } + + get [Symbol.toStringTag] () { return 'BerReader' } + + /** + * Get a buffer that represents the underlying data buffer. + * + * @type {Buffer} + */ + get buffer () { + return this.#buffer.subarray(0) + } + + /** + * The length of the current field being read. + * + * @type {number} + */ + get length () { + return this.#currentFieldLength + } + + /** + * Current read position in the underlying data buffer. + * + * @type {number} + */ + get offset () { + return this.#offset + } + + /** + * The number of bytes remaining in the backing buffer that have not + * been read. + * + * @type {number} + */ + get remain () { + return this.#size - this.#offset + } + + /** + * Read the next byte in the buffer without advancing the offset. + * + * @return {number | null} The next byte or null if not enough data. + */ + peek () { + return this.readByte(true) + } + + /** + * Reads a boolean from the current offset and advances the offset. + * + * @param {number} [tag] The tag number that is expected to be read. + * + * @returns {boolean} True if the tag value represents `true`, otherwise + * `false`. + * + * @throws When there is an error reading the tag. + */ + readBoolean (tag = types.Boolean) { + const intBuffer = this.readTag(tag) + this.#offset += intBuffer.length + const int = parseIntegerBuffer(intBuffer) + + return (int !== 0) + } + + /** + * Reads a single byte and advances offset; you can pass in `true` to make + * this a "peek" operation (i.e. get the byte, but don't advance the offset). + * + * @param {boolean} [peek=false] `true` means don't move the offset. + * @returns {number | null} The next byte, `null` if not enough data. + */ + readByte (peek = false) { + if (this.#size - this.#offset < 1) { + return null + } + + const byte = this.#buffer[this.#offset] & 0xff + + if (peek !== true) { + this.#offset += 1 + } + + return byte + } + + /** + * Reads an enumeration (integer) from the current offset and advances the + * offset. + * + * @returns {number} The integer represented by the next sequence of bytes + * in the buffer from the current offset. The current offset must be at a + * byte whose value is equal to the ASN.1 enumeration tag. + * + * @throws When there is an error reading the tag. + */ + readEnumeration () { + const intBuffer = this.readTag(types.Enumeration) + this.#offset += intBuffer.length + + return parseIntegerBuffer(intBuffer) + } + + /** + * Reads an integer from the current offset and advances the offset. + * + * @param {number} [tag] The tag number that is expected to be read. + * + * @returns {number} The integer represented by the next sequence of bytes + * in the buffer from the current offset. The current offset must be at a + * byte whose value is equal to the ASN.1 integer tag. + * + * @throws When there is an error reading the tag. + */ + readInt (tag = types.Integer) { + const intBuffer = this.readTag(tag) + this.#offset += intBuffer.length + + return parseIntegerBuffer(intBuffer) + } + + /** + * Reads a length value from the BER buffer at the given offset. This + * method is not really meant to be called directly, as callers have to + * manipulate the internal buffer afterwards. + * + * This method does not advance the reader offset. + * + * As a result of this method, the `.length` property can be read for the + * current field until another method invokes `readLength`. + * + * Note: we only support up to 4 bytes to describe the length of a value. + * + * @param {number} [offset] Read a length value starting at the specified + * position in the underlying buffer. + * + * @return {number | null} The position the buffer should be advanced to in + * order for the reader to be at the start of the value for the field. See + * {@link setOffset}. If the offset, or length, exceeds the size of the + * underlying buffer, `null` will be returned. + * + * @throws When an unsupported length value is encountered. + */ + readLength (offset) { + if (offset === undefined) { offset = this.#offset } + + if (offset >= this.#size) { return null } + + let lengthByte = this.#buffer[offset++] & 0xff + // TODO: we are commenting this out because it seems to be unreachable. + // It is not clear to me how we can ever check `lenB === null` as `null` + // is a primitive type, and seemingly cannot be represented by a byte. + // If we find that removal of this line does not affect the larger suite + // of ldapjs tests, we should just completely remove it from the code. + /* if (lenB === null) { return null } */ + + if ((lengthByte & 0x80) === 0x80) { + lengthByte &= 0x7f + + // https://www.rfc-editor.org/rfc/rfc4511.html#section-5.1 prohibits + // indefinite form (0x80). + if (lengthByte === 0) { throw Error('Indefinite length not supported.') } + + // We only support up to 4 bytes to describe encoding length. So the only + // valid indicators are 0x81, 0x82, 0x83, and 0x84. + if (lengthByte > 4) { throw Error('Encoding too long.') } + + if (this.#size - offset < lengthByte) { return null } + + this.#currentFieldLength = 0 + for (let i = 0; i < lengthByte; i++) { + this.#currentFieldLength = (this.#currentFieldLength << 8) + + (this.#buffer[offset++] & 0xff) + } + } else { + // Wasn't a variable length + this.#currentFieldLength = lengthByte + } + + return offset + } + + /** + * At the current offset, read the next tag, length, and value as an + * object identifier (OID) and return the OID string. + * + * @param {number} [tag] The tag number that is expected to be read. + * + * @returns {string | null} Will return `null` if the buffer is an invalid + * length. Otherwise, returns the OID as a string. + */ + readOID (tag = types.OID) { + // See https://web.archive.org/web/20221008202056/https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier?redirectedfrom=MSDN + const oidBuffer = this.readString(tag, true) + if (oidBuffer === null) { return null } + + const values = [] + let value = 0 + + for (let i = 0; i < oidBuffer.length; i++) { + const byte = oidBuffer[i] & 0xff + + value <<= 7 + value += byte & 0x7f + if ((byte & 0x80) === 0) { + values.push(value) + value = 0 + } + } + + value = values.shift() + values.unshift(value % 40) + values.unshift((value / 40) >> 0) + + return values.join('.') + } + + /** + * Get a new {@link Buffer} instance that represents the full set of bytes + * for a BER representation of a specified tag. For example, this is useful + * when construction objects from an incoming LDAP message and the object + * constructor can read a BER representation of itself to create a new + * instance, e.g. when reading the filter section of a "search request" + * message. + * + * @param {number} tag The expected tag that starts the TLV series of bytes. + * @param {boolean} [advanceOffset=true] Indicates if the instance's internal + * offset should be advanced or not after reading the buffer. + * + * @returns {Buffer|null} If there is a problem reading the buffer, e.g. + * the number of bytes indicated by the length do not exist in the value, then + * `null` will be returned. Otherwise, a new {@link Buffer} of bytes that + * represents a full TLV. + */ + readRawBuffer (tag, advanceOffset = true) { + if (Number.isInteger(tag) === false) { + throw Error('must specify an integer tag') + } + + const foundTag = this.peek() + if (foundTag !== tag) { + const expected = tag.toString(16).padStart(2, '0') + const found = foundTag.toString(16).padStart(2, '0') + throw Error(`Expected 0x${expected}: got 0x${found}`) + } + + const currentOffset = this.#offset + const valueOffset = this.readLength(currentOffset + 1) + if (valueOffset === null) { return null } + const valueBytesLength = this.length + + const numTagAndLengthBytes = valueOffset - currentOffset + + // Buffer.subarray is not inclusive. We need to account for the + // tag and length bytes. + const endPos = currentOffset + valueBytesLength + numTagAndLengthBytes + if (endPos > this.buffer.byteLength) { + return null + } + const buffer = this.buffer.subarray(currentOffset, endPos) + if (advanceOffset === true) { + this.setOffset(currentOffset + (valueBytesLength + numTagAndLengthBytes)) + } + + return buffer + } + + /** + * At the current buffer offset, read the next tag as a sequence tag, and + * advance the offset to the position of the tag of the first item in the + * sequence. + * + * @param {number} [tag] The tag number that is expected to be read. + * + * @returns {number|null} The read sequence tag value. Should match the + * function input parameter value. + * + * @throws If the `tag` does not match or if there is an error reading + * the length of the sequence. + */ + readSequence (tag) { + const foundTag = this.peek() + if (tag !== undefined && tag !== foundTag) { + const expected = tag.toString(16).padStart(2, '0') + const found = foundTag.toString(16).padStart(2, '0') + throw Error(`Expected 0x${expected}: got 0x${found}`) + } + + this.#currentSequenceStart = this.#offset + const valueOffset = this.readLength(this.#offset + 1) // stored in `length` + if (valueOffset === null) { return null } + + this.#offset = valueOffset + return foundTag + } + + /** + * At the current buffer offset, read the next value as a string and advance + * the offset. + * + * @param {number} [tag] The tag number that is expected to be read. Should + * be `ASN1.String`. + * @param {boolean} [asBuffer=false] When true, the raw buffer will be + * returned. Otherwise, a native string. + * + * @returns {string | Buffer | null} Will return `null` if the buffer is + * malformed. + * + * @throws If there is a problem reading the length. + */ + readString (tag = types.OctetString, asBuffer = false) { + const tagByte = this.peek() + + if (tagByte !== tag) { + const expected = tag.toString(16).padStart(2, '0') + const found = tagByte.toString(16).padStart(2, '0') + throw Error(`Expected 0x${expected}: got 0x${found}`) + } + + const valueOffset = this.readLength(this.#offset + 1) // stored in `length` + if (valueOffset === null) { return null } + if (this.length > this.#size - valueOffset) { return null } + + this.#offset = valueOffset + + if (this.length === 0) { return asBuffer ? Buffer.alloc(0) : '' } + + const str = this.#buffer.subarray(this.#offset, this.#offset + this.length) + this.#offset += this.length + + return asBuffer ? str : str.toString('utf8') + } + + /** + * At the current buffer offset, read the next set of bytes represented + * by the given tag, and return the resulting buffer. For example, if the + * BER represents a sequence with a string "foo", i.e. + * `[0x30, 0x05, 0x04, 0x03, 0x66, 0x6f, 0x6f]`, and the current offset is + * `0`, then the result of `readTag(0x30)` is the buffer + * `[0x04, 0x03, 0x66, 0x6f, 0x6f]`. + * + * @param {number} tag The tag number that is expected to be read. + * + * @returns {Buffer | null} The buffer representing the tag value, or null if + * the buffer is in some way malformed. + * + * @throws When there is an error interpreting the buffer, or the buffer + * is not formed correctly. + */ + readTag (tag) { + if (tag == null) { + throw Error('Must supply an ASN.1 tag to read.') + } + + const byte = this.peek() + if (byte !== tag) { + const tagString = tag.toString(16).padStart(2, '0') + const byteString = byte.toString(16).padStart(2, '0') + throw Error(`Expected 0x${tagString}: got 0x${byteString}`) + } + + const fieldOffset = this.readLength(this.#offset + 1) // stored in `length` + if (fieldOffset === null) { return null } + + if (this.length > this.#size - fieldOffset) { return null } + this.#offset = fieldOffset + + return this.#buffer.subarray(this.#offset, this.#offset + this.length) + } + + /** + * Returns the current sequence as a new {@link BerReader} instance. This + * method relies on {@link readSequence} having been invoked first. If it has + * not been invoked, the returned reader will represent an undefined portion + * of the underlying buffer. + * + * @returns {BerReader} + */ + sequenceToReader () { + // Represents the number of bytes that constitute the "length" portion + // of the TLV tuple. + const lengthValueLength = this.#offset - this.#currentSequenceStart + const buffer = this.#buffer.subarray( + this.#currentSequenceStart, + this.#currentSequenceStart + (lengthValueLength + this.#currentFieldLength) + ) + return new BerReader(buffer) + } + + /** + * Set the internal offset to a given position in the underlying buffer. + * This method is to support manual advancement of the reader. + * + * @param {number} position + * + * @throws If the given `position` is not an integer. + */ + setOffset (position) { + if (Number.isInteger(position) === false) { + throw Error('Must supply an integer position.') + } + this.#offset = position + } + + /** + * @param {HexDumpParams} params The `buffer` parameter will be ignored. + * + * @see bufferToHexDump + */ + toHexDump (params) { + bufferToHexDump({ + ...params, + buffer: this.buffer + }) + } +} + +/** + * Given a buffer that represents an integer TLV, parse it and return it + * as a decimal value. This accounts for signedness. + * + * @param {Buffer} integerBuffer + * + * @returns {number} + */ +function parseIntegerBuffer (integerBuffer) { + let value = 0 + let i + for (i = 0; i < integerBuffer.length; i++) { + value <<= 8 + value |= (integerBuffer[i] & 0xff) + } + + if ((integerBuffer[0] & 0x80) === 0x80 && i !== 4) { value -= (1 << (i * 8)) } + + return value >> 0 +} + +module.exports = BerReader diff --git a/node_modules/@ldapjs/asn1/lib/ber/reader.test.js b/node_modules/@ldapjs/asn1/lib/ber/reader.test.js new file mode 100644 index 0000000..db30459 --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/ber/reader.test.js @@ -0,0 +1,671 @@ +'use strict' + +const tap = require('tap') +const { Writable } = require('stream') +const BerReader = require('./reader') + +// A sequence (0x30), 5 bytes (0x05) long, which consists of +// a string (0x04), 3 bytes (0x03) long, representing "foo". +const fooSequence = [0x30, 0x05, 0x04, 0x03, 0x66, 0x6f, 0x6f] + +// ClientID certificate request example from +// https://web.archive.org/web/20221008202056/https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier?redirectedfrom=MSDN +const microsoftOID = [ + 0x06, 0x09, // OID; 9 bytes + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x14, // 1.3.6.1.4.1.311.21.20 + 0x31, 0x4a, // Set; 4 bytes + 0x30, 0x48, // Sequence; 48 bytes + 0x02, 0x01, 0x09, // Integer; 1 bytes; 9 + 0x0c, 0x23, // UTF8 String; 23 bytes + 0x76, 0x69, 0x63, 0x68, 0x33, 0x64, 0x2e, 0x6a, // vich3d.j + 0x64, 0x64, 0x6d, 0x63, 0x73, 0x63, 0x23, 0x6e, // domcsc.n + 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x6d, 0x69, // ttest.mi + 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x23, // crosoft. + 0x63, 0x64, 0x6d, // com + 0x0c, 0x15, // UTF8 String; 15 bytes + 0x4a, 0x44, 0x4f, 0x4d, 0x43, 0x53, 0x43, 0x5c, // JDOMCSC\ + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, // administ + 0x72, 0x61, 0x74, 0x6f, 0x72, // rator + 0x0c, 0x07, // UTF8 String; 7 bytes + 0x63, 0x65, 0x72, 0x74, 0x72, 0x65, 0x71 // certreq +] + +tap.test('must supply a buffer', async t => { + const expected = TypeError('Must supply a Buffer instance to read.') + t.throws( + () => new BerReader(), + expected + ) + t.throws( + () => new BerReader(''), + expected + ) +}) + +tap.test('has toStringTag', async t => { + const reader = new BerReader(Buffer.from('foo')) + t.equal(Object.prototype.toString.call(reader), '[object BerReader]') +}) + +tap.test('buffer property returns buffer', async t => { + const fooBuffer = Buffer.from(fooSequence) + const reader = new BerReader(fooBuffer) + + t.equal( + fooBuffer.compare(reader.buffer), + 0 + ) +}) + +tap.test('peek reads but does not advance', async t => { + const reader = new BerReader(Buffer.from([0xde])) + const byte = reader.peek() + t.equal(byte, 0xde) + t.equal(reader.offset, 0) +}) + +tap.test('readBoolean', t => { + t.test('read boolean true', async t => { + const reader = new BerReader(Buffer.from([0x01, 0x01, 0xff])) + t.equal(reader.readBoolean(), true, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + }) + + t.test('read boolean false', async t => { + const reader = new BerReader(Buffer.from([0x01, 0x01, 0x00])) + t.equal(reader.readBoolean(), false, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + }) + + t.end() +}) + +tap.test('readByte', t => { + t.test('reads a byte and advances offset', async t => { + const reader = new BerReader(Buffer.from([0xde])) + t.equal(reader.offset, 0) + t.equal(reader.readByte(), 0xde) + t.equal(reader.offset, 1) + }) + + t.test('returns null if buffer exceeded', async t => { + const reader = new BerReader(Buffer.from([0xde])) + reader.readByte() + t.equal(reader.readByte(), null) + }) + + t.test('peek does not advance offset', async t => { + const reader = new BerReader(Buffer.from([0xde])) + const byte = reader.readByte(true) + t.equal(byte, 0xde) + t.equal(reader.offset, 0) + }) + + t.end() +}) + +tap.test('readEnumeration', t => { + t.test('read enumeration', async t => { + const reader = new BerReader(Buffer.from([0x0a, 0x01, 0x20])) + t.equal(reader.readEnumeration(), 0x20, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + }) + + t.end() +}) + +tap.test('readInt', t => { + t.test('read 1 byte int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x01, 0x03])) + t.equal(reader.readInt(), 0x03, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + }) + + t.test('read 2 byte int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x02, 0x7e, 0xde])) + t.equal(reader.readInt(), 0x7ede, 'wrong value') + t.equal(reader.length, 0x02, 'wrong length') + }) + + t.test('read 3 byte int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x03, 0x7e, 0xde, 0x03])) + t.equal(reader.readInt(), 0x7ede03, 'wrong value') + t.equal(reader.length, 0x03, 'wrong length') + }) + + t.test('read 4 byte int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x04, 0x7e, 0xde, 0x03, 0x01])) + t.equal(reader.readInt(), 0x7ede0301, 'wrong value') + t.equal(reader.length, 0x04, 'wrong length') + }) + + t.test('read 1 byte negative int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x01, 0xdc])) + t.equal(reader.readInt(), -36, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + }) + + t.test('read 2 byte negative int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x02, 0xc0, 0x4e])) + t.equal(reader.readInt(), -16306, 'wrong value') + t.equal(reader.length, 0x02, 'wrong length') + }) + + t.test('read 3 byte negative int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x03, 0xff, 0x00, 0x19])) + t.equal(reader.readInt(), -65511, 'wrong value') + t.equal(reader.length, 0x03, 'wrong length') + }) + + t.test('read 4 byte negative int', async t => { + const reader = new BerReader(Buffer.from([0x02, 0x04, 0x91, 0x7c, 0x22, 0x1f])) + t.equal(reader.readInt(), -1854135777, 'wrong value') + t.equal(reader.length, 0x04, 'wrong length') + }) + + t.test('read 4 byte negative int (abandon request tag)', async t => { + // Technically, an abandon request shouldn't ever have a negative + // number, but this lets us test the feature completely. + const reader = new BerReader(Buffer.from([0x80, 0x04, 0x91, 0x7c, 0x22, 0x1f])) + t.equal(reader.readInt(0x80), -1854135777, 'wrong value') + t.equal(reader.length, 0x04, 'wrong length') + }) + + t.test('correctly advances offset', async t => { + const reader = new BerReader(Buffer.from([ + 0x30, 0x06, // sequence; 6 bytes + 0x02, 0x04, 0x91, 0x7c, 0x22, 0x1f // integer; 4 bytes + ])) + const seqBuffer = reader.readTag(0x30) + t.equal( + Buffer.compare( + seqBuffer, + Buffer.from([0x02, 0x04, 0x91, 0x7c, 0x22, 0x1f] + ) + ), + 0 + ) + + t.equal(reader.readInt(), -1854135777, 'wrong value') + t.equal(reader.length, 0x04, 'wrong length') + t.equal(reader.offset, 8) + }) + + t.end() +}) + +tap.test('readLength', t => { + t.test('reads from specified offset', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + const offset = reader.readLength(1) + t.equal(offset, 2) + t.equal(reader.length, 5) + }) + + t.test('returns null if offset exceeds buffer', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + const offset = reader.readLength(10) + t.equal(offset, null) + t.equal(reader.offset, 0) + }) + + t.test('reads from current offset', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + const byte = reader.readByte() + t.equal(byte, 0x30) + + const offset = reader.readLength() + t.equal(offset, 2) + t.equal(reader.length, 5) + }) + + t.test('throws for indefinite length', async t => { + // Buffer would indicate a string of indefinite length. + const reader = new BerReader(Buffer.from([0x04, 0x80])) + t.throws( + () => reader.readLength(1), + Error('Indefinite length not supported.') + ) + }) + + t.test('throws if length too long', async t => { + // Buffer would indicate a string whose length should be indicated + // by the next 5 bytes (omitted). + const reader = new BerReader(Buffer.from([0x04, 0x85])) + t.throws( + () => reader.readLength(1), + Error('Encoding too long.') + ) + }) + + t.test('reads a long (integer) from length', async t => { + const reader = new BerReader(Buffer.from([0x81, 0x94])) + const offset = reader.readLength() + t.equal(offset, 2) + t.equal(reader.length, 148) + }) + + t.test( + 'returns null if long (integer) from length exceeds buffer', + async t => { + const reader = new BerReader(Buffer.from([0x82, 0x03])) + const offset = reader.readLength(0) + t.equal(offset, null) + t.equal(reader.length, 0) + }) + + t.end() +}) + +tap.test('readOID', t => { + t.test('returns null for bad buffer', async t => { + const reader = new BerReader(Buffer.from([0x06, 0x03, 0x0a])) + t.equal(reader.readOID(), null) + }) + + t.test('reads an OID', async t => { + const input = Buffer.from(microsoftOID.slice(0, 11)) + const reader = new BerReader(input) + t.equal(reader.readOID(), '1.3.6.1.4.1.311.21.20') + }) + + t.end() +}) + +tap.test('readRawBuffer', t => { + t.test('requires number tag', async t => { + const reader = new BerReader(Buffer.from([])) + t.throws( + () => reader.readRawBuffer(), + Error('must specify an integer tag') + ) + }) + + t.test('throws if tag does not match', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x00])) + t.throws( + () => reader.readRawBuffer(0x05), + Error('Expected 0x05: got 0x04') + ) + }) + + t.test('reads empty string buffer', async t => { + const buffer = Buffer.from([0x04, 0x00]) + const reader = new BerReader(buffer) + const readBuffer = reader.readRawBuffer(0x04) + t.equal(buffer.compare(readBuffer), 0) + t.equal(reader.offset, 2) + }) + + t.test('returns null for no value byte', async t => { + const reader = new BerReader(Buffer.from([0x04])) + const buffer = reader.readRawBuffer(0x04) + t.equal(buffer, null) + t.equal(reader.offset, 0) + }) + + t.test('returns null if value length exceeds buffer length', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x01])) + const buffer = reader.readRawBuffer(0x04) + t.equal(buffer, null) + t.equal(reader.offset, 0) + }) + + t.test('return only next buffer', async t => { + const buffer = Buffer.from([ + 0x04, 0x03, 0x66, 0x6f, 0x6f, + 0x04, 0x03, 0x62, 0x61, 0x72, + 0x04, 0x03, 0x62, 0x61, 0x7a + ]) + const reader = new BerReader(buffer) + reader.readString() + + const readBuffer = reader.readRawBuffer(0x04) + t.equal(reader.offset, 10) + t.equal(readBuffer.compare(buffer.subarray(5, 10)), 0) + }) + + t.test('does not advance offset', async t => { + const buffer = Buffer.from([ + 0x04, 0x03, 0x66, 0x6f, 0x6f, + 0x04, 0x03, 0x62, 0x61, 0x72, + 0x04, 0x03, 0x62, 0x61, 0x7a + ]) + const reader = new BerReader(buffer) + reader.readString() + + const readBuffer = reader.readRawBuffer(0x04, false) + t.equal(reader.offset, 5) + t.equal(readBuffer.compare(buffer.subarray(5, 10)), 0) + }) + + t.test('reads buffer with multi-byte length', async t => { + // 0x01b3 => 110110011 => 00000001 + 10110011 => 0x01 + 0xb3 => 435 bytes + const bytes = [ + 0x02, 0x01, 0x00, // simple integer + 0x04, 0x82, 0x01, 0xb3 // begin string sequence + ] + for (let i = 1; i <= 435; i += 1) { + // Create a long string of `~` characters + bytes.push(0x7e) + } + // Add a null sequence terminator + Array.prototype.push.apply(bytes, [0x30, 0x00]) + + const buffer = Buffer.from(bytes) + const reader = new BerReader(buffer) + t.equal(reader.readInt(), 0) + t.equal(reader.readString(), '~'.repeat(435)) + t.equal(reader.readSequence(0x30), 0x30) + reader.setOffset(0) + + // Emulate what we would do to read the filter value from an LDAP + // search request that has a very large filter: + reader.readInt() + const tag = reader.peek() + t.equal(tag, 0x04) + const rawBuffer = reader.readRawBuffer(tag) + t.equal(rawBuffer.compare(buffer.subarray(3, bytes.length - 2)), 0) + }) + + t.end() +}) + +tap.test('readSequence', t => { + t.test('throws for tag mismatch', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x00])) + t.throws( + () => reader.readSequence(0x30), + Error('Expected 0x30: got 0x04') + ) + }) + + t.test('returns null when read length is null', async t => { + const reader = new BerReader(Buffer.from([0x30, 0x84, 0x04, 0x03])) + t.equal(reader.readSequence(), null) + }) + + t.test('return read sequence and advances offset', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + const result = reader.readSequence() + t.equal(result, 0x30) + t.equal(reader.offset, 2) + }) + + // Original test + t.test('read sequence', async t => { + const reader = new BerReader(Buffer.from([0x30, 0x03, 0x01, 0x01, 0xff])) + t.ok(reader) + t.equal(reader.readSequence(), 0x30, 'wrong value') + t.equal(reader.length, 0x03, 'wrong length') + t.equal(reader.readBoolean(), true, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + }) + + t.end() +}) + +tap.test('readString', t => { + t.test('throws for tag mismatch', async t => { + const reader = new BerReader(Buffer.from([0x30, 0x00])) + t.throws( + () => reader.readString(), + Error('Expected 0x04: got 0x30') + ) + }) + + t.test('returns null when read length is null', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x84, 0x03, 0x0a])) + t.equal(reader.readString(), null) + }) + + t.test('returns null when value bytes too short', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x03, 0x0a])) + t.equal(reader.readString(), null) + }) + + t.test('returns empty buffer for zero length string', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x00])) + const result = reader.readString(0x04, true) + t.type(result, Buffer) + t.equal(Buffer.compare(result, Buffer.alloc(0)), 0) + }) + + t.test('returns empty string for zero length string', async t => { + const reader = new BerReader(Buffer.from([0x04, 0x00])) + const result = reader.readString() + t.type(result, 'string') + t.equal(result, '') + }) + + t.test('returns string as buffer', async t => { + const reader = new BerReader(Buffer.from(fooSequence.slice(2))) + const result = reader.readString(0x04, true) + t.type(result, Buffer) + + const expected = Buffer.from(fooSequence.slice(4)) + t.equal(Buffer.compare(result, expected), 0) + }) + + t.test('returns string as string', async t => { + const reader = new BerReader(Buffer.from(fooSequence.slice(2))) + const result = reader.readString() + t.type(result, 'string') + t.equal(result, 'foo') + }) + + // Original test + t.test('read string', async t => { + const dn = 'cn=foo,ou=unit,o=test' + const buf = Buffer.alloc(dn.length + 2) + buf[0] = 0x04 + buf[1] = Buffer.byteLength(dn) + buf.write(dn, 2) + const reader = new BerReader(buf) + t.ok(reader) + t.equal(reader.readString(), dn, 'wrong value') + t.equal(reader.length, dn.length, 'wrong length') + }) + + // Orignal test + t.test('long string', async t => { + const buf = Buffer.alloc(256) + const s = + '2;649;CN=Red Hat CS 71GA Demo,O=Red Hat CS 71GA Demo,C=US;' + + 'CN=RHCS Agent - admin01,UID=admin01,O=redhat,C=US [1] This is ' + + 'Teena Vradmin\'s description.' + buf[0] = 0x04 + buf[1] = 0x81 + buf[2] = 0x94 + buf.write(s, 3) + const ber = new BerReader(buf.subarray(0, 3 + s.length)) + t.equal(ber.readString(), s) + }) + + t.end() +}) + +tap.test('readTag', t => { + t.test('throws error for null tag', async t => { + const expected = Error('Must supply an ASN.1 tag to read.') + const reader = new BerReader(Buffer.from(fooSequence)) + + t.throws( + () => reader.readTag(), + expected + ) + }) + + t.test('returns null for null byte tag', { skip: true }) + + t.test('throws error for tag mismatch', async t => { + const expected = Error('Expected 0x40: got 0x30') + const reader = new BerReader(Buffer.from(fooSequence)) + + t.throws( + () => reader.readTag(0x40), + expected + ) + }) + + t.test('returns null if field length is null', async t => { + const reader = new BerReader(Buffer.from([0x05])) + t.equal(reader.readTag(0x05), null) + }) + + t.test('returns null if field length greater than available bytes', async t => { + const reader = new BerReader(Buffer.from([0x30, 0x03, 0x04, 0xa0])) + t.equal(reader.readTag(0x30), null) + }) + + t.test('returns null if field length greater than available bytes', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + const expected = Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f]) + const result = reader.readTag(0x30) + t.equal(Buffer.compare(result, expected), 0) + }) + + t.end() +}) + +tap.test('remain', t => { + t.test('returns the size of the buffer if nothing read', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + t.equal(7, reader.remain) + }) + + t.test('returns accurate remaining bytes', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + t.equal(0x30, reader.readSequence()) + t.equal(5, reader.remain) + }) + + t.end() +}) + +tap.test('setOffset', t => { + t.test('throws if not an integer', async t => { + const expected = Error('Must supply an integer position.') + const reader = new BerReader(Buffer.from(fooSequence)) + + t.throws( + () => reader.setOffset(1.2), + expected + ) + t.throws( + () => reader.setOffset('2'), + expected + ) + }) + + t.test('sets offset', async t => { + const reader = new BerReader(Buffer.from(fooSequence)) + t.equal(reader.offset, 0) + + reader.setOffset(2) + t.equal(reader.offset, 2) + t.equal(reader.peek(), 0x04) + }) + + t.end() +}) + +tap.test('sequenceToReader', t => { + t.test('returns new reader with full sequence', async t => { + const multiSequence = [ + 0x30, 14, + ...fooSequence, + ...fooSequence + ] + const reader = new BerReader(Buffer.from(multiSequence)) + + // Read the intial sequence and verify current position. + t.equal(0x30, reader.readSequence()) + t.equal(2, reader.offset) + + // Advance the buffer to the start of the first sub-sequence value. + t.equal(0x30, reader.readSequence()) + t.equal(4, reader.offset) + t.equal(12, reader.remain) + + // Get a new reader the consists of the first sub-sequence and verify + // that the original reader's position has not changed. + const fooReader = reader.sequenceToReader() + t.equal(fooReader.remain, 7) + t.equal(fooReader.offset, 0) + t.equal(reader.offset, 4) + t.equal(0x30, fooReader.readSequence()) + t.equal('foo', fooReader.readString()) + + // The original reader should advance like normal. + t.equal('foo', reader.readString()) + t.equal(0x30, reader.readSequence()) + t.equal('foo', reader.readString()) + t.equal(0, reader.remain) + t.equal(16, reader.offset) + }) + + t.end() +}) + +tap.test('toHexDump', t => { + t.test('dumps buffer', t => { + const reader = new BerReader( + Buffer.from([0x00, 0x01, 0x02, 0x03]) + ) + const expected = '00010203' + + let found = '' + const destination = new Writable({ + write (chunk, encoding, callback) { + found += chunk.toString() + callback() + } + }) + + destination.on('finish', () => { + t.equal(found, expected) + t.end() + }) + + reader.toHexDump({ + destination, + closeDestination: true + }) + }) + + t.end() +}) + +// Original test +tap.test('anonymous LDAPv3 bind', async t => { + const BIND = Buffer.alloc(14) + BIND[0] = 0x30 // Sequence + BIND[1] = 12 // len + BIND[2] = 0x02 // ASN.1 Integer + BIND[3] = 1 // len + BIND[4] = 0x04 // msgid (make up 4) + BIND[5] = 0x60 // Bind Request + BIND[6] = 7 // len + BIND[7] = 0x02 // ASN.1 Integer + BIND[8] = 1 // len + BIND[9] = 0x03 // v3 + BIND[10] = 0x04 // String (bind dn) + BIND[11] = 0 // len + BIND[12] = 0x80 // ContextSpecific (choice) + BIND[13] = 0 // simple bind + + // Start testing ^^ + const ber = new BerReader(BIND) + t.equal(ber.readSequence(), 48, 'Not an ASN.1 Sequence') + t.equal(ber.length, 12, 'Message length should be 12') + t.equal(ber.readInt(), 4, 'Message id should have been 4') + t.equal(ber.readSequence(), 96, 'Bind Request should have been 96') + t.equal(ber.length, 7, 'Bind length should have been 7') + t.equal(ber.readInt(), 3, 'LDAP version should have been 3') + t.equal(ber.readString(), '', 'Bind DN should have been empty') + t.equal(ber.length, 0, 'string length should have been 0') + t.equal(ber.readByte(), 0x80, 'Should have been ContextSpecific (choice)') + t.equal(ber.readByte(), 0, 'Should have been simple bind') + t.equal(null, ber.readByte(), 'Should be out of data') +}) diff --git a/node_modules/@ldapjs/asn1/lib/ber/types.js b/node_modules/@ldapjs/asn1/lib/ber/types.js new file mode 100644 index 0000000..106d042 --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/ber/types.js @@ -0,0 +1,36 @@ +'use strict' + +module.exports = { + EOC: 0x0, + Boolean: 0x01, + Integer: 0x02, + BitString: 0x03, + OctetString: 0x04, + Null: 0x05, + OID: 0x06, + ObjectDescriptor: 0x07, + External: 0x08, + Real: 0x09, // float + Enumeration: 0x0a, + PDV: 0x0b, + Utf8String: 0x0c, + RelativeOID: 0x0d, + Sequence: 0x10, + Set: 0x11, + NumericString: 0x12, + PrintableString: 0x13, + T61String: 0x14, + VideotexString: 0x15, + IA5String: 0x16, + UTCTime: 0x17, + GeneralizedTime: 0x18, + GraphicString: 0x19, + VisibleString: 0x1a, + GeneralString: 0x1c, + UniversalString: 0x1d, + CharacterString: 0x1e, + BMPString: 0x1f, + Constructor: 0x20, + LDAPSequence: 0x30, + Context: 0x80 +} diff --git a/node_modules/@ldapjs/asn1/lib/ber/writer.js b/node_modules/@ldapjs/asn1/lib/ber/writer.js new file mode 100644 index 0000000..3cd7449 --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/ber/writer.js @@ -0,0 +1,466 @@ +'use strict' + +const types = require('./types') +const bufferToHexDump = require('../buffer-to-hex-dump') + +class BerWriter { + /** + * The source buffer as it was passed in when creating the instance. + * + * @type {Buffer} + */ + #buffer + + /** + * The total bytes in the backing buffer. + * + * @type {number} + */ + #size + + /** + * As the BER buffer is written, this property records the current position + * in the buffer. + * + * @type {number} + */ + #offset = 0 + + /** + * A list of offsets in the buffer where we need to insert sequence tag and + * length pairs. + */ + #sequenceOffsets = [] + + /** + * Coeffecient used when increasing the buffer to accomodate writes that + * exceed the available space left in the buffer. + * + * @type {number} + */ + #growthFactor + + constructor ({ size = 1024, growthFactor = 8 } = {}) { + this.#buffer = Buffer.alloc(size) + this.#size = this.#buffer.length + this.#offset = 0 + this.#growthFactor = growthFactor + } + + get [Symbol.toStringTag] () { return 'BerWriter' } + + get buffer () { + // TODO: handle sequence check + + return this.#buffer.subarray(0, this.#offset) + } + + /** + * The size of the backing buffer. + * + * @return {number} + */ + get size () { + return this.#size + } + + /** + * Append a raw buffer to the current writer instance. No validation to + * determine if the buffer represents a valid BER encoding is performed. + * + * @param {Buffer} buffer The buffer to append. If this is not a valid BER + * sequence of data, it will invalidate the BER represented by the `BerWriter`. + * + * @throws If the input is not an instance of Buffer. + */ + appendBuffer (buffer) { + if (Buffer.isBuffer(buffer) === false) { + throw Error('buffer must be an instance of Buffer') + } + this.#ensureBufferCapacity(buffer.length) + buffer.copy(this.#buffer, this.#offset, 0, buffer.length) + this.#offset += buffer.length + } + + /** + * Complete a sequence started with {@link startSequence}. + * + * @throws When the sequence is too long and would exceed the 4 byte + * length descriptor limitation. + */ + endSequence () { + const sequenceStartOffset = this.#sequenceOffsets.pop() + const start = sequenceStartOffset + 3 + const length = this.#offset - start + + if (length <= 0x7f) { + this.#shift(start, length, -2) + this.#buffer[sequenceStartOffset] = length + } else if (length <= 0xff) { + this.#shift(start, length, -1) + this.#buffer[sequenceStartOffset] = 0x81 + this.#buffer[sequenceStartOffset + 1] = length + } else if (length <= 0xffff) { + this.#buffer[sequenceStartOffset] = 0x82 + this.#buffer[sequenceStartOffset + 1] = length >> 8 + this.#buffer[sequenceStartOffset + 2] = length + } else if (length <= 0xffffff) { + this.#shift(start, length, 1) + this.#buffer[sequenceStartOffset] = 0x83 + this.#buffer[sequenceStartOffset + 1] = length >> 16 + this.#buffer[sequenceStartOffset + 2] = length >> 8 + this.#buffer[sequenceStartOffset + 3] = length + } else { + throw Error('sequence too long') + } + } + + /** + * Write a sequence tag to the buffer and advance the offset to the starting + * position of the value. Sequences must be completed with a subsequent + * invocation of {@link endSequence}. + * + * @param {number} [tag=0x30] The tag to use for the sequence. + * + * @throws When the tag is not a number. + */ + startSequence (tag = (types.Sequence | types.Constructor)) { + if (typeof tag !== 'number') { + throw TypeError('tag must be a Number') + } + + this.writeByte(tag) + this.#sequenceOffsets.push(this.#offset) + this.#ensureBufferCapacity(3) + this.#offset += 3 + } + + /** + * @param {HexDumpParams} params The `buffer` parameter will be ignored. + * + * @see bufferToHexDump + */ + toHexDump (params) { + bufferToHexDump({ + ...params, + buffer: this.buffer + }) + } + + /** + * Write a boolean TLV to the buffer. + * + * @param {boolean} boolValue + * @param {tag} [number=0x01] A custom tag for the boolean. + * + * @throws When a parameter is of the wrong type. + */ + writeBoolean (boolValue, tag = types.Boolean) { + if (typeof boolValue !== 'boolean') { + throw TypeError('boolValue must be a Boolean') + } + if (typeof tag !== 'number') { + throw TypeError('tag must be a Number') + } + + this.#ensureBufferCapacity(3) + this.#buffer[this.#offset++] = tag + this.#buffer[this.#offset++] = 0x01 + this.#buffer[this.#offset++] = boolValue === true ? 0xff : 0x00 + } + + /** + * Write an arbitrary buffer of data to the backing buffer using the given + * tag. + * + * @param {Buffer} buffer + * @param {number} tag The tag to use for the ASN.1 TLV sequence. + * + * @throws When either input parameter is of the wrong type. + */ + writeBuffer (buffer, tag) { + if (typeof tag !== 'number') { + throw TypeError('tag must be a Number') + } + if (Buffer.isBuffer(buffer) === false) { + throw TypeError('buffer must be an instance of Buffer') + } + + this.writeByte(tag) + this.writeLength(buffer.length) + this.#ensureBufferCapacity(buffer.length) + buffer.copy(this.#buffer, this.#offset, 0, buffer.length) + this.#offset += buffer.length + } + + /** + * Write a single byte to the backing buffer and advance the offset. The + * backing buffer will be automatically expanded to accomodate the new byte + * if no room in the buffer remains. + * + * @param {number} byte The byte to be written. + * + * @throws When the passed in parameter is not a `Number` (aka a byte). + */ + writeByte (byte) { + if (typeof byte !== 'number') { + throw TypeError('argument must be a Number') + } + + this.#ensureBufferCapacity(1) + this.#buffer[this.#offset++] = byte + } + + /** + * Write an enumeration TLV to the buffer. + * + * @param {number} value + * @param {number} [tag=0x0a] A custom tag for the enumeration. + * + * @throws When a passed in parameter is not of the correct type, or the + * value requires too many bytes (must be <= 4). + */ + writeEnumeration (value, tag = types.Enumeration) { + if (typeof value !== 'number') { + throw TypeError('value must be a Number') + } + if (typeof tag !== 'number') { + throw TypeError('tag must be a Number') + } + this.writeInt(value, tag) + } + + /** + * Write an, up to 4 byte, integer TLV to the buffer. + * + * @param {number} intToWrite + * @param {number} [tag=0x02] + * + * @throws When either parameter is not of the write type, or if the + * integer consists of too many bytes. + */ + writeInt (intToWrite, tag = types.Integer) { + if (typeof intToWrite !== 'number') { + throw TypeError('intToWrite must be a Number') + } + if (typeof tag !== 'number') { + throw TypeError('tag must be a Number') + } + + let intSize = 4 + while ( + ( + ((intToWrite & 0xff800000) === 0) || + ((intToWrite & 0xff800000) === (0xff800000 >> 0)) + ) && (intSize > 1) + ) { + intSize-- + intToWrite <<= 8 + } + + // TODO: figure out how to cover this in a test. + /* istanbul ignore if: needs test */ + if (intSize > 4) { + throw Error('BER ints cannot be > 0xffffffff') + } + + this.#ensureBufferCapacity(2 + intSize) + this.#buffer[this.#offset++] = tag + this.#buffer[this.#offset++] = intSize + + while (intSize-- > 0) { + this.#buffer[this.#offset++] = ((intToWrite & 0xff000000) >>> 24) + intToWrite <<= 8 + } + } + + /** + * Write a set of length bytes to the backing buffer. Per + * https://www.rfc-editor.org/rfc/rfc4511.html#section-5.1, LDAP message + * BERs prohibit greater than 4 byte lengths. Given we are supporing + * the `ldapjs` module, we limit ourselves to 4 byte lengths. + * + * @param {number} len The length value to write to the buffer. + * + * @throws When the length is not a number or requires too many bytes. + */ + writeLength (len) { + if (typeof len !== 'number') { + throw TypeError('argument must be a Number') + } + + this.#ensureBufferCapacity(4) + + if (len <= 0x7f) { + this.#buffer[this.#offset++] = len + } else if (len <= 0xff) { + this.#buffer[this.#offset++] = 0x81 + this.#buffer[this.#offset++] = len + } else if (len <= 0xffff) { + this.#buffer[this.#offset++] = 0x82 + this.#buffer[this.#offset++] = len >> 8 + this.#buffer[this.#offset++] = len + } else if (len <= 0xffffff) { + this.#buffer[this.#offset++] = 0x83 + this.#buffer[this.#offset++] = len >> 16 + this.#buffer[this.#offset++] = len >> 8 + this.#buffer[this.#offset++] = len + } else { + throw Error('length too long (> 4 bytes)') + } + } + + /** + * Write a NULL tag and value to the buffer. + */ + writeNull () { + this.writeByte(types.Null) + this.writeByte(0x00) + } + + /** + * Given an OID string, e.g. `1.2.840.113549.1.1.1`, split it into + * octets, encode the octets, and write it to the backing buffer. + * + * @param {string} oidString + * @param {number} [tag=0x06] A custom tag to use for the OID. + * + * @throws When the parameters are not of the correct types, or if the + * OID is not in the correct format. + */ + writeOID (oidString, tag = types.OID) { + if (typeof oidString !== 'string') { + throw TypeError('oidString must be a string') + } + if (typeof tag !== 'number') { + throw TypeError('tag must be a Number') + } + + if (/^([0-9]+\.){3,}[0-9]+$/.test(oidString) === false) { + throw Error('oidString is not a valid OID string') + } + + const parts = oidString.split('.') + const bytes = [] + bytes.push(parseInt(parts[0], 10) * 40 + parseInt(parts[1], 10)) + for (const part of parts.slice(2)) { + encodeOctet(bytes, parseInt(part, 10)) + } + + this.#ensureBufferCapacity(2 + bytes.length) + this.writeByte(tag) + this.writeLength(bytes.length) + this.appendBuffer(Buffer.from(bytes)) + + function encodeOctet (bytes, octet) { + if (octet < 128) { + bytes.push(octet) + } else if (octet < 16_384) { + bytes.push((octet >>> 7) | 0x80) + bytes.push(octet & 0x7F) + } else if (octet < 2_097_152) { + bytes.push((octet >>> 14) | 0x80) + bytes.push(((octet >>> 7) | 0x80) & 0xFF) + bytes.push(octet & 0x7F) + } else if (octet < 268_435_456) { + bytes.push((octet >>> 21) | 0x80) + bytes.push(((octet >>> 14) | 0x80) & 0xFF) + bytes.push(((octet >>> 7) | 0x80) & 0xFF) + bytes.push(octet & 0x7F) + } else { + bytes.push(((octet >>> 28) | 0x80) & 0xFF) + bytes.push(((octet >>> 21) | 0x80) & 0xFF) + bytes.push(((octet >>> 14) | 0x80) & 0xFF) + bytes.push(((octet >>> 7) | 0x80) & 0xFF) + bytes.push(octet & 0x7F) + } + } + } + + /** + * Write a string TLV to the buffer. + * + * @param {string} stringToWrite + * @param {number} [tag=0x04] The tag to use. + * + * @throws When either input parameter is of the wrong type. + */ + writeString (stringToWrite, tag = types.OctetString) { + if (typeof stringToWrite !== 'string') { + throw TypeError('stringToWrite must be a string') + } + if (typeof tag !== 'number') { + throw TypeError('tag must be a number') + } + + const toWriteLength = Buffer.byteLength(stringToWrite) + this.writeByte(tag) + this.writeLength(toWriteLength) + if (toWriteLength > 0) { + this.#ensureBufferCapacity(toWriteLength) + this.#buffer.write(stringToWrite, this.#offset) + this.#offset += toWriteLength + } + } + + /** + * Given a set of strings, write each as a string TLV to the buffer. + * + * @param {string[]} strings + * + * @throws When the input is not an array. + */ + writeStringArray (strings) { + if (Array.isArray(strings) === false) { + throw TypeError('strings must be an instance of Array') + } + for (const string of strings) { + this.writeString(string) + } + } + + /** + * Given a number of bytes to be written into the buffer, verify the buffer + * has enough free space. If not, allocate a new buffer, copy the current + * backing buffer into the new buffer, and promote the new buffer to be the + * current backing buffer. + * + * @param {number} numberOfBytesToWrite How many bytes are required to be + * available for writing in the backing buffer. + */ + #ensureBufferCapacity (numberOfBytesToWrite) { + if (this.#size - this.#offset < numberOfBytesToWrite) { + let newSize = this.#size * this.#growthFactor + if (newSize - this.#offset < numberOfBytesToWrite) { + newSize += numberOfBytesToWrite + } + + const newBuffer = Buffer.alloc(newSize) + + this.#buffer.copy(newBuffer, 0, 0, this.#offset) + this.#buffer = newBuffer + this.#size = newSize + } + } + + /** + * Shift a region of the buffer indicated by `start` and `length` a number + * of bytes indicated by `shiftAmount`. + * + * @param {number} start The starting position in the buffer for the region + * of bytes to be shifted. + * @param {number} length The number of bytes that constitutes the region + * of the buffer to be shifted. + * @param {number} shiftAmount The number of bytes to shift the region by. + * This may be negative. + */ + #shift (start, length, shiftAmount) { + // TODO: this leaves garbage behind. We should either zero out the bytes + // left behind, or device a better algorightm that generates a clean + // buffer. + this.#buffer.copy(this.#buffer, start + shiftAmount, start, start + length) + this.#offset += shiftAmount + } +} + +module.exports = BerWriter diff --git a/node_modules/@ldapjs/asn1/lib/ber/writer.test.js b/node_modules/@ldapjs/asn1/lib/ber/writer.test.js new file mode 100644 index 0000000..2f4d6c2 --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/ber/writer.test.js @@ -0,0 +1,749 @@ +'use strict' + +const tap = require('tap') +const { Writable } = require('stream') +const BerWriter = require('./writer') + +tap.test('has toStringTag', async t => { + const writer = new BerWriter() + t.equal(Object.prototype.toString.call(writer), '[object BerWriter]') +}) + +tap.test('#ensureBufferCapacity', t => { + t.test('does not change buffer size if unnecessary', async t => { + const writer = new BerWriter({ size: 1 }) + t.equal(writer.size, 1) + + writer.writeByte(0x01) + t.equal(writer.size, 1) + }) + + t.test('expands buffer to accomodate write skipping growth factor', async t => { + const writer = new BerWriter({ size: 0 }) + t.equal(writer.size, 0) + + writer.writeByte(0x01) + t.equal(writer.size, 1) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x01])), 0) + }) + + t.test('expands buffer to accomodate write with growth factor', async t => { + const writer = new BerWriter({ size: 1 }) + t.equal(writer.size, 1) + + writer.writeByte(0x01) + writer.writeByte(0x02) + t.equal(writer.size, 8) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x01, 0x02])), 0) + }) + + t.end() +}) + +tap.test('appendBuffer', t => { + t.test('throws if input not a buffer', async t => { + const writer = new BerWriter() + t.throws( + () => writer.appendBuffer('foo'), + Error('buffer must be an instance of Buffer') + ) + }) + + t.test('appendBuffer appends a buffer', async t => { + const expected = Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f, 0x66, 0x6f, 0x6f]) + const writer = new BerWriter() + writer.writeString('foo') + writer.appendBuffer(Buffer.from('foo')) + t.equal(Buffer.compare(writer.buffer, expected), 0) + }) + + t.end() +}) + +tap.test('endSequence', t => { + t.test('ends a sequence', async t => { + const writer = new BerWriter({ size: 25 }) + writer.startSequence() + writer.writeString('hello world') + writer.endSequence() + + const ber = writer.buffer + const expected = Buffer.from([ + 0x30, 0x0d, // sequence; 13 bytes + 0x04, 0x0b, // string; 11 bytes + 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, // 'hello ' + 0x77, 0x6f, 0x72, 0x6c, 0x64 // 'world' + ]) + t.equal(Buffer.compare(ber, expected), 0) + }) + + t.test('ends sequence of two byte length', async t => { + const value = Buffer.alloc(0x81, 0x01) + const writer = new BerWriter() + + writer.startSequence() + writer.writeBuffer(value, 0x04) + writer.endSequence() + + const ber = writer.buffer + t.equal( + Buffer.from([0x30, 0x81, 0x84, 0x04, 0x81, value.length]) + .compare(ber.subarray(0, 6)), + 0 + ) + }) + + t.test('ends sequence of three byte length', async t => { + const value = Buffer.alloc(0xfe, 0x01) + const writer = new BerWriter() + + writer.startSequence() + writer.writeBuffer(value, 0x04) + writer.endSequence() + + const ber = writer.buffer + t.equal( + Buffer.from([0x30, 0x82, 0x01, 0x01, 0x04, 0x81, value.length]) + .compare(ber.subarray(0, 7)), + 0 + ) + }) + + t.test('ends sequence of four byte length', async t => { + const value = Buffer.alloc(0xaaaaaa, 0x01) + const writer = new BerWriter() + + writer.startSequence() + writer.writeBuffer(value, 0x04) + writer.endSequence() + + const ber = writer.buffer + t.equal( + Buffer.from([0x30, 0x83, 0xaa, 0xaa, 0xaf, 0x04, 0x83, value.length]) + .compare(ber.subarray(0, 8)), + 0 + ) + }) + + t.test('throws if sequence too long', async t => { + const value = Buffer.alloc(0xaffffff, 0x01) + const writer = new BerWriter() + + writer.startSequence() + writer.writeByte(0x04) + // We can't write the length because it is too long. However, this + // still gives us enough data to generate the error we want to generate. + writer.appendBuffer(value) + t.throws( + () => writer.endSequence(), + Error('sequence too long') + ) + }) + + t.end() +}) + +tap.test('startSequence', t => { + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.startSequence('30'), + Error('tag must be a Number') + ) + }) + + t.test('starts a sequence', async t => { + const writer = new BerWriter({ size: 1 }) + writer.startSequence() + t.equal(writer.size, 8) + + const expected = Buffer.from([0x30, 0x00, 0x00, 0x00]) + t.equal(Buffer.compare(writer.buffer, expected), 0) + }) + + t.end() +}) + +tap.test('toHexDump', t => { + t.test('dumps buffer', t => { + const writer = new BerWriter() + writer.appendBuffer(Buffer.from([0x00, 0x01, 0x02, 0x03])) + const expected = '00010203' + + let found = '' + const destination = new Writable({ + write (chunk, encoding, callback) { + found += chunk.toString() + callback() + } + }) + + destination.on('finish', () => { + t.equal(found, expected) + t.end() + }) + + writer.toHexDump({ + destination, + closeDestination: true + }) + }) + + t.end() +}) + +tap.test('writeBoolean', t => { + t.test('throws if input not a boolean', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeBoolean(1), + Error('boolValue must be a Boolean') + ) + }) + + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeBoolean(true, '5'), + Error('tag must be a Number') + ) + }) + + t.test('writes true', async t => { + const writer = new BerWriter({ size: 1 }) + writer.writeBoolean(true) + t.equal(writer.size, 8) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x01, 0x01, 0xff])), 0) + }) + + t.test('writes false', async t => { + const writer = new BerWriter({ size: 1 }) + writer.writeBoolean(false) + t.equal(writer.size, 8) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x01, 0x01, 0x00])), 0) + }) + + t.test('writes with custom tag', async t => { + const writer = new BerWriter({ size: 1 }) + writer.writeBoolean(true, 0xff) + t.equal(writer.size, 8) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0xff, 0x01, 0xff])), 0) + }) + + // Original test + t.test('write boolean', async t => { + const writer = new BerWriter() + + writer.writeBoolean(true) + writer.writeBoolean(false) + const ber = writer.buffer + + t.equal(ber.length, 6, 'Wrong length') + t.equal(ber[0], 0x01, 'tag wrong') + t.equal(ber[1], 0x01, 'length wrong') + t.equal(ber[2], 0xff, 'value wrong') + t.equal(ber[3], 0x01, 'tag wrong') + t.equal(ber[4], 0x01, 'length wrong') + t.equal(ber[5], 0x00, 'value wrong') + }) + + t.end() +}) + +tap.test('writeBuffer', t => { + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeBuffer(Buffer.alloc(0), '1'), + Error('tag must be a Number') + ) + }) + + t.test('throws if buffer not a Buffer', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeBuffer([0x00], 0x01), + Error('buffer must be an instance of Buffer') + ) + }) + + t.test('write buffer', async t => { + const writer = new BerWriter() + // write some stuff to start with + writer.writeString('hello world') + let ber = writer.buffer + const buf = Buffer.from([0x04, 0x0b, 0x30, 0x09, 0x02, 0x01, 0x0f, 0x01, 0x01, + 0xff, 0x01, 0x01, 0xff]) + writer.writeBuffer(buf.subarray(2, buf.length), 0x04) + ber = writer.buffer + + t.equal(ber.length, 26, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value') + t.equal(ber[13], buf[0], 'wrong tag') + t.equal(ber[14], buf[1], 'wrong length') + for (let i = 13, j = 0; i < ber.length && j < buf.length; i++, j++) { + t.equal(ber[i], buf[j], 'buffer contents not identical') + } + }) + + t.end() +}) + +tap.test('writeByte', t => { + t.test('throws if input not a number', async t => { + const writer = new BerWriter() + t.equal(writer.size, 1024) + + t.throws( + () => writer.writeByte('1'), + Error('argument must be a Number') + ) + }) + + t.test('writes a byte to the backing buffer', async t => { + const writer = new BerWriter() + writer.writeByte(0x01) + + const buffer = writer.buffer + t.equal(buffer.length, 1) + t.equal(Buffer.compare(buffer, Buffer.from([0x01])), 0) + }) + + t.end() +}) + +tap.test('writeEnumeration', async t => { + t.test('throws if value not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeEnumeration('1'), + Error('value must be a Number') + ) + }) + + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeEnumeration(1, '1'), + Error('tag must be a Number') + ) + }) + + t.test('writes an enumeration', async t => { + const writer = new BerWriter({ size: 1 }) + writer.writeEnumeration(0x01) + t.equal(writer.size, 8) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x0a, 0x01, 0x01])), 0) + }) + + t.test('writes an enumeration with custom tag', async t => { + const writer = new BerWriter({ size: 1 }) + writer.writeEnumeration(0x01, 0xff) + t.equal(writer.size, 8) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0xff, 0x01, 0x01])), 0) + }) + + t.end() +}) + +tap.test('writeInt', t => { + t.test('throws if int not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeInt('1'), + Error('intToWrite must be a Number') + ) + }) + + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeInt(1, '1'), + Error('tag must be a Number') + ) + }) + + t.test('write 1 byte int', async t => { + const writer = new BerWriter() + + writer.writeInt(0x7f) + const ber = writer.buffer + + t.equal(ber.length, 3, 'Wrong length for an int: ' + ber.length) + t.equal(ber[0], 0x02, 'ASN.1 tag wrong (2) -> ' + ber[0]) + t.equal(ber[1], 0x01, 'length wrong(1) -> ' + ber[1]) + t.equal(ber[2], 0x7f, 'value wrong(3) -> ' + ber[2]) + }) + + t.test('write 2 byte int', async t => { + const writer = new BerWriter() + + writer.writeInt(0x7ffe) + const ber = writer.buffer + + t.equal(ber.length, 4, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x02, 'length wrong') + t.equal(ber[2], 0x7f, 'value wrong (byte 1)') + t.equal(ber[3], 0xfe, 'value wrong (byte 2)') + }) + + t.test('write 3 byte int', async t => { + const writer = new BerWriter() + + writer.writeInt(0x7ffffe) + const ber = writer.buffer + + t.equal(ber.length, 5, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x03, 'length wrong') + t.equal(ber[2], 0x7f, 'value wrong (byte 1)') + t.equal(ber[3], 0xff, 'value wrong (byte 2)') + t.equal(ber[4], 0xfe, 'value wrong (byte 3)') + }) + + t.test('write 4 byte int', async t => { + const writer = new BerWriter() + + writer.writeInt(0x7ffffffe) + const ber = writer.buffer + + t.equal(ber.length, 6, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x04, 'length wrong') + t.equal(ber[2], 0x7f, 'value wrong (byte 1)') + t.equal(ber[3], 0xff, 'value wrong (byte 2)') + t.equal(ber[4], 0xff, 'value wrong (byte 3)') + t.equal(ber[5], 0xfe, 'value wrong (byte 4)') + }) + + t.test('write 1 byte negative int', async t => { + const writer = new BerWriter() + + writer.writeInt(-128) + const ber = writer.buffer + + t.equal(ber.length, 3, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x01, 'length wrong') + t.equal(ber[2], 0x80, 'value wrong (byte 1)') + }) + + t.test('write 2 byte negative int', async t => { + const writer = new BerWriter() + + writer.writeInt(-22400) + const ber = writer.buffer + + t.equal(ber.length, 4, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x02, 'length wrong') + t.equal(ber[2], 0xa8, 'value wrong (byte 1)') + t.equal(ber[3], 0x80, 'value wrong (byte 2)') + }) + + t.test('write 3 byte negative int', async t => { + const writer = new BerWriter() + + writer.writeInt(-481653) + const ber = writer.buffer + + t.equal(ber.length, 5, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x03, 'length wrong') + t.equal(ber[2], 0xf8, 'value wrong (byte 1)') + t.equal(ber[3], 0xa6, 'value wrong (byte 2)') + t.equal(ber[4], 0x8b, 'value wrong (byte 3)') + }) + + t.test('write 4 byte negative int', async t => { + const writer = new BerWriter() + + writer.writeInt(-1522904131) + const ber = writer.buffer + + t.equal(ber.length, 6, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x04, 'length wrong') + t.equal(ber[2], 0xa5, 'value wrong (byte 1)') + t.equal(ber[3], 0x3a, 'value wrong (byte 2)') + t.equal(ber[4], 0x53, 'value wrong (byte 3)') + t.equal(ber[5], 0xbd, 'value wrong (byte 4)') + }) + + t.test('throws for > 4 byte integer', { skip: true }, async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeInt(0xffffffffff), + Error('BER ints cannot be > 0xffffffff') + ) + }) + + t.end() +}) + +tap.test('writeLength', t => { + t.test('throws if length not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeLength('1'), + Error('argument must be a Number') + ) + }) + + t.test('writes a single byte length', async t => { + const writer = new BerWriter({ size: 4 }) + writer.writeLength(0x7f) + t.equal(writer.buffer.length, 1) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x7f])), 0) + }) + + t.test('writes a two byte length', async t => { + const writer = new BerWriter({ size: 4 }) + writer.writeLength(0xff) + t.equal(writer.buffer.length, 2) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x81, 0xff])), 0) + }) + + t.test('writes a three byte length', async t => { + const writer = new BerWriter({ size: 4 }) + writer.writeLength(0xffff) + t.equal(writer.buffer.length, 3) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x82, 0xff, 0xff])), 0) + }) + + t.test('writes a four byte length', async t => { + const writer = new BerWriter({ size: 4 }) + writer.writeLength(0xffffff) + t.equal(writer.buffer.length, 4) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x83, 0xff, 0xff, 0xff])), 0) + }) + + t.test('throw if byte length is too long', async t => { + const writer = new BerWriter({ size: 4 }) + t.throws( + () => writer.writeLength(0xffffffffff), + Error('length too long (> 4 bytes)') + ) + }) + + t.end() +}) + +tap.test('writeNull', t => { + t.test('writeNull', async t => { + const writer = new BerWriter({ size: 2 }) + writer.writeNull() + t.equal(writer.size, 2) + t.equal(Buffer.compare(writer.buffer, Buffer.from([0x05, 0x00])), 0) + }) + + t.end() +}) + +tap.test('writeOID', t => { + t.test('throws if OID not a string', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeOID(42), + Error('oidString must be a string') + ) + }) + + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeOID('1.2.3', '1'), + Error('tag must be a Number') + ) + }) + + t.test('throws if OID not a valid OID string', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeOID('foo'), + Error('oidString is not a valid OID string') + ) + }) + + t.test('writes an OID', async t => { + const oid = '1.2.840.113549.1.1.1' + const writer = new BerWriter() + writer.writeOID(oid) + + const expected = Buffer.from([0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01]) + const ber = writer.buffer + t.equal(ber.compare(expected), 0) + }) + + t.test('writes OID covering all octet encodings', async t => { + const oid = '1.2.200.17000.2100100.270100100' + const writer = new BerWriter() + writer.writeOID(oid) + + const expected = Buffer.from([ + 0x06, 0x0f, + 0x2a, 0x81, 0x48, 0x81, + 0x84, 0x68, 0x81, 0x80, + 0x97, 0x04, 0x81, 0x80, + 0xe5, 0xcd, 0x04 + ]) + const ber = writer.buffer + t.equal(ber.compare(expected), 0) + }) + + t.end() +}) + +tap.test('writeString', t => { + t.test('throws if non-string supplied', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeString(42), + Error('stringToWrite must be a string') + ) + }) + + t.test('throws if tag not a number', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeString('foo', '1'), + Error('tag must be a number') + ) + }) + + t.test('writes an empty string', async t => { + const writer = new BerWriter() + writer.writeString('') + + const expected = Buffer.from([0x04, 0x00]) + t.equal(Buffer.compare(writer.buffer, expected), 0) + }) + + t.test('writes a string', async t => { + const writer = new BerWriter({ size: 1 }) + writer.writeString('foo') + + const expected = Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f]) + t.equal(Buffer.compare(writer.buffer, expected), 0) + t.equal(writer.size, 8) + }) + + t.end() +}) + +tap.test('writeString', t => { + t.test('throws if non-array supplied', async t => { + const writer = new BerWriter() + t.throws( + () => writer.writeStringArray(42), + Error('strings must be an instance of Array') + ) + }) + + t.test('write string array', async t => { + const writer = new BerWriter() + writer.writeStringArray(['hello world', 'fubar!']) + const ber = writer.buffer + + t.equal(ber.length, 21, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.subarray(2, 13).toString('utf8'), 'hello world', 'wrong value') + + t.equal(ber[13], 0x04, 'wrong tag') + t.equal(ber[14], 6, 'wrong length') + t.equal(ber.subarray(15).toString('utf8'), 'fubar!', 'wrong value') + }) + + t.end() +}) + +tap.test('original tests', t => { + t.test('resize internal buffer', async t => { + const writer = new BerWriter({ size: 2 }) + writer.writeString('hello world') + const ber = writer.buffer + + t.equal(ber.length, 13, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.subarray(2).toString('utf8'), 'hello world', 'wrong value') + }) + + t.test('sequence', async t => { + const writer = new BerWriter({ size: 25 }) + writer.startSequence() + writer.writeString('hello world') + writer.endSequence() + const ber = writer.buffer + + t.equal(ber.length, 15, 'wrong length') + t.equal(ber[0], 0x30, 'wrong tag') + t.equal(ber[1], 13, 'wrong length') + t.equal(ber[2], 0x04, 'wrong tag') + t.equal(ber[3], 11, 'wrong length') + t.equal(ber.subarray(4).toString('utf8'), 'hello world', 'wrong value') + }) + + t.test('nested sequence', async t => { + const writer = new BerWriter({ size: 25 }) + writer.startSequence() + writer.writeString('hello world') + writer.startSequence() + writer.writeString('hello world') + writer.endSequence() + writer.endSequence() + const ber = writer.buffer + + t.equal(ber.length, 30, 'wrong length') + t.equal(ber[0], 0x30, 'wrong tag') + t.equal(ber[1], 28, 'wrong length') + t.equal(ber[2], 0x04, 'wrong tag') + t.equal(ber[3], 11, 'wrong length') + t.equal(ber.subarray(4, 15).toString('utf8'), 'hello world', 'wrong value') + t.equal(ber[15], 0x30, 'wrong tag') + t.equal(ber[16], 13, 'wrong length') + t.equal(ber[17], 0x04, 'wrong tag') + t.equal(ber[18], 11, 'wrong length') + t.equal(ber.subarray(19, 30).toString('utf8'), 'hello world', 'wrong value') + }) + + t.test('LDAP bind message', async t => { + const dn = 'cn=foo,ou=unit,o=test' + const writer = new BerWriter() + writer.startSequence() + writer.writeInt(3) // msgid = 3 + writer.startSequence(0x60) // ldap bind + writer.writeInt(3) // ldap v3 + writer.writeString(dn) + writer.writeByte(0x80) + writer.writeByte(0x00) + writer.endSequence() + writer.endSequence() + const ber = writer.buffer + + t.equal(ber.length, 35, 'wrong length (buffer)') + t.equal(ber[0], 0x30, 'wrong tag') + t.equal(ber[1], 33, 'wrong length') + t.equal(ber[2], 0x02, 'wrong tag') + t.equal(ber[3], 1, 'wrong length') + t.equal(ber[4], 0x03, 'wrong value') + t.equal(ber[5], 0x60, 'wrong tag') + t.equal(ber[6], 28, 'wrong length') + t.equal(ber[7], 0x02, 'wrong tag') + t.equal(ber[8], 1, 'wrong length') + t.equal(ber[9], 0x03, 'wrong value') + t.equal(ber[10], 0x04, 'wrong tag') + t.equal(ber[11], dn.length, 'wrong length') + t.equal(ber.subarray(12, 33).toString('utf8'), dn, 'wrong value') + t.equal(ber[33], 0x80, 'wrong tag') + t.equal(ber[34], 0x00, 'wrong len') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/asn1/lib/buffer-to-hex-dump.js b/node_modules/@ldapjs/asn1/lib/buffer-to-hex-dump.js new file mode 100644 index 0000000..d7048bc --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/buffer-to-hex-dump.js @@ -0,0 +1,74 @@ +'use strict' + +const { createWriteStream } = require('fs') + +/** + * @typedef {object} HexDumpParams + * @property {Buffer} buffer The buffer instance to serialize into a hex dump. + * @property {string} [prefix=''] A string to prefix each byte with, e.g. + * `0x`. + * @property {string} [separator=''] A string to separate each byte with, e.g. + * `, '. + * @property {string[]} [wrapCharacters=[]] A set of characters to wrap the + * output with. For example, `wrapCharacters=['[', ']']` will start the hex + * dump with `[` and end it with `]`. + * @property {number} [width=10] How many bytes to write per line. + * @property {WriteStream | string} [destination=process.stdout] Where to + * write the serialized data. If a string is provided, it is assumed to be + * the path to a file. This file will be completely overwritten. + * @property {boolean} [closeDestination=false] Indicates whether the + * `destination` should be closed when done. This _should_ be `true` when the + * passed in `destination` is a stream that you control. If a string path is + * supplied for the `destination`, this will automatically be handled. + */ + +// We'd like to put this coverage directive after the doc block, +// but that confuses doc tooling (e.g. WebStorm). +/* istanbul ignore next: defaults don't need 100% coverage */ +/** + * Given a buffer of bytes, generate a hex dump that can be loaded later + * or viewed in a hex editor (e.g. [Hex Fiend](https://hexfiend.com)). + * + * @param {HexDumpParams} params + * + * @throws When the destination cannot be accessed. + */ +module.exports = function bufferToHexDump ({ + buffer, + prefix = '', + separator = '', + wrapCharacters = [], + width = 10, + destination = process.stdout, + closeDestination = false +}) { + let closeStream = closeDestination + if (typeof destination === 'string') { + destination = createWriteStream(destination) + closeStream = true + } + + if (wrapCharacters[0]) { + destination.write(wrapCharacters[0]) + } + + for (const [i, byte] of buffer.entries()) { + const outByte = Number(byte).toString(16).padStart(2, '0') + destination.write(prefix + outByte) + if (i !== buffer.byteLength - 1) { + destination.write(separator) + } + if ((i + 1) % width === 0) { + destination.write('\n') + } + } + + if (wrapCharacters[1]) { + destination.write(wrapCharacters[1]) + } + + /* istanbul ignore else */ + if (closeStream === true) { + destination.end() + } +} diff --git a/node_modules/@ldapjs/asn1/lib/buffer-to-hex-dump.test.js b/node_modules/@ldapjs/asn1/lib/buffer-to-hex-dump.test.js new file mode 100644 index 0000000..9d79287 --- /dev/null +++ b/node_modules/@ldapjs/asn1/lib/buffer-to-hex-dump.test.js @@ -0,0 +1,75 @@ +'use strict' + +const tap = require('tap') +const path = require('path') +const { Writable } = require('stream') +const { tmpdir } = require('os') +const { randomUUID } = require('crypto') +const { readFile, rm } = require('fs/promises') +const { setTimeout } = require('timers/promises') +const bufferToHexDump = require('./buffer-to-hex-dump') + +const input = Buffer.from([ + 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c +]) + +tap.test('writes to stream', t => { + const expected = [ + '[0x00, 0x01, 0x02, 0x03, \n', + '0x04, 0x05, 0x06, 0x07, \n', + '0x08, 0x09, 0x0a, 0x0b, \n', + '0x0c]' + ].join('') + + let found = '' + const destination = new Writable({ + write (chunk, encoding, callback) { + found += chunk.toString() + callback() + } + }) + + destination.on('finish', () => { + t.equal(found, expected) + t.end() + }) + + bufferToHexDump({ + buffer: input, + prefix: '0x', + separator: ', ', + wrapCharacters: ['[', ']'], + width: 4, + closeDestination: true, + destination + }) +}) + +tap.test('writes to file', async t => { + const expected = [ + '00010203\n', + '04050607\n', + '08090a0b\n', + '0c' + ].join('') + const destination = path.join(tmpdir(), randomUUID()) + + t.teardown(async () => { + await rm(destination) + }) + + bufferToHexDump({ + buffer: input, + width: 4, + destination + }) + + // Give a little time for the write stream to create and + // close the file. + await setTimeout(100) + + const contents = await readFile(destination) + t.equal(contents.toString(), expected) +}) diff --git a/node_modules/@ldapjs/asn1/package.json b/node_modules/@ldapjs/asn1/package.json new file mode 100644 index 0000000..afd7285 --- /dev/null +++ b/node_modules/@ldapjs/asn1/package.json @@ -0,0 +1,40 @@ +{ + "originalAuthor": "Joyent (joyent.com)", + "contributors": [ + "Mark Cavage ", + "David Gwynne ", + "Yunong Xiao ", + "Alex Wilson " + ], + "name": "@ldapjs/asn1", + "description": "Contains parsers and serializers for ASN.1 (currently BER only)", + "version": "2.0.0", + "repository": { + "type": "git", + "url": "git://github.com/ldapjs/asn1.git" + }, + "main": "index.js", + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.34.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.4" + }, + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report", + "test:cov": "tap", + "test:cov:html": "tap --coverage-report=html", + "test:watch": "tap -w --no-coverage-report" + }, + "license": "MIT", + "pre-commit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/attribute/.eslintrc b/node_modules/@ldapjs/attribute/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/attribute/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/attribute/.github/workflows/main.yml b/node_modules/@ldapjs/attribute/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/attribute/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/attribute/.taprc.yaml b/node_modules/@ldapjs/attribute/.taprc.yaml new file mode 100644 index 0000000..4e21f6f --- /dev/null +++ b/node_modules/@ldapjs/attribute/.taprc.yaml @@ -0,0 +1,5 @@ +reporter: terse +coverage-map: coverage-map.js + +files: + - 'index.test.js' diff --git a/node_modules/@ldapjs/attribute/CHANGES.md b/node_modules/@ldapjs/attribute/CHANGES.md new file mode 100644 index 0000000..2f92b54 --- /dev/null +++ b/node_modules/@ldapjs/attribute/CHANGES.md @@ -0,0 +1,54 @@ +# ldap-filter + +> ### Important +> This file is no longer maintained. For changes, please read +> the releases page: https://github.com/ldapjs/filter/releases + +## 0.3.3 + +- Assert that NOT filters are closed by a parentheses + +## 0.3.2 + +- Perform better checks for trailing characters +- Improve test coverage +- Change \*Filter.json to work recursively for child filters +- Bump assert-plus dependency to 1.0.0 + +## 0.3.1 + +- Tolerate underscores in attribute names + +## 0.3.0 + +- Enforce stricter output escaping for buffer values +- **BREAKING** Rename `NotFilter.addfilter` to `NotFilter.setFilter` +- **BREAKING** Rewrite filter parser to be more strict about input. + This _significantly_ changes the sort of filters which the parser files + acceptable. While the old parser would tolerate unescaped characters in + the `()\*` set, the new parser requires them to be escaped via the `\XX` + hex notation. This is in keeping with + [RFC 4514](http://tools.ietf.org/search/rfc4515) +- Perform better escaping for values which are not UTF-8 + +## 0.2.3 +- Update dev dependencies +- Clean up asserts and prototypes + +## 0.2.2 + +- Fix nested paren handling in parser + +## 0.2.1 + +- Fix AndFilter per RFC4526 + +## 0.2.0 + +- Add 'attribute' accessor for ExtFilter matchType +- Improve API for custom match functions +- Support other value types in EqualityFilter + +## 0.1.0 + +- Initial import from ldapjs diff --git a/node_modules/@ldapjs/attribute/LICENSE b/node_modules/@ldapjs/attribute/LICENSE new file mode 100644 index 0000000..923d87e --- /dev/null +++ b/node_modules/@ldapjs/attribute/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Patrick Mooney. All rights reserved. +Copyright (c) 2014 Mark Cavage, Inc. All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/attribute/README.md b/node_modules/@ldapjs/attribute/README.md new file mode 100644 index 0000000..a56bf20 --- /dev/null +++ b/node_modules/@ldapjs/attribute/README.md @@ -0,0 +1,8 @@ +# @ldapjs/attribute + +Provides a class for representing LDAP entry attributes as described in +[RFC 4512 §2.5](https://www.rfc-editor.org/rfc/rfc4512#section-2.5). + +## License + +MIT. diff --git a/node_modules/@ldapjs/attribute/coverage-map.js b/node_modules/@ldapjs/attribute/coverage-map.js new file mode 100644 index 0000000..fc2046a --- /dev/null +++ b/node_modules/@ldapjs/attribute/coverage-map.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = testFile => testFile.replace(/\.test\.js$/, '.js') diff --git a/node_modules/@ldapjs/attribute/index.js b/node_modules/@ldapjs/attribute/index.js new file mode 100644 index 0000000..396d5b1 --- /dev/null +++ b/node_modules/@ldapjs/attribute/index.js @@ -0,0 +1,344 @@ +'use strict' + +const { core: { LBER_SET } } = require('@ldapjs/protocol') +const { + BerTypes, + BerReader, + BerWriter +} = require('@ldapjs/asn1') +const warning = require('./lib/deprecations') + +/** + * Represents an LDAP attribute and its associated values as defined by + * https://www.rfc-editor.org/rfc/rfc4512#section-2.5. + */ +class Attribute { + #buffers = [] + #type + + /** + * @param {object} options + * @param {string} [options.type=''] The name of the attribute, e.g. "cn" for + * the common name attribute. For binary attributes, include the `;binary` + * option, e.g. `foo;binary`. + * @param {string|string[]} [options.values] Either a single value for the + * attribute, or a set of values for the attribute. + */ + constructor (options = {}) { + if (options.type && typeof (options.type) !== 'string') { + throw TypeError('options.type must be a string') + } + this.type = options.type || '' + + const values = options.values || options.vals || [] + if (options.vals) { + warning.emit('LDAP_ATTRIBUTE_DEP_001') + } + this.values = values + } + + get [Symbol.toStringTag] () { + return 'LdapAttribute' + } + + /** + * A copy of the buffers that represent the values for the attribute. + * + * @returns {Buffer[]} + */ + get buffers () { + return this.#buffers.slice(0) + } + + /** + * Serializes the attribute to a plain JavaScript object representation. + * + * @returns {object} + */ + get pojo () { + return { + type: this.type, + values: this.values + } + } + + /** + * The attribute name as provided during construction. + * + * @returns {string} + */ + get type () { + return this.#type + } + + /** + * Set the attribute name. + * + * @param {string} name + */ + set type (name) { + this.#type = name + } + + /** + * The set of attribute values as strings. + * + * @returns {string[]} + */ + get values () { + const encoding = _bufferEncoding(this.#type) + return this.#buffers.map(function (v) { + return v.toString(encoding) + }) + } + + /** + * Set the attribute's associated values. This will replace any values set + * at construction time. + * + * @param {string|string[]} vals + */ + set values (vals) { + if (Array.isArray(vals) === false) { + return this.addValue(vals) + } + for (const value of vals) { + this.addValue(value) + } + } + + /** + * Use {@link values} instead. + * + * @deprecated + * @returns {string[]} + */ + get vals () { + warning.emit('LDAP_ATTRIBUTE_DEP_003') + return this.values + } + + /** + * Use {@link values} instead. + * + * @deprecated + * @param {string|string[]} values + */ + set vals (values) { + warning.emit('LDAP_ATTRIBUTE_DEP_003') + this.values = values + } + + /** + * Append a new value, or set of values, to the current set of values + * associated with the attributes. + * + * @param {string|string[]} value + */ + addValue (value) { + if (Buffer.isBuffer(value)) { + this.#buffers.push(value) + } else { + this.#buffers.push( + Buffer.from(value + '', _bufferEncoding(this.#type)) + ) + } + } + + /** + * Replaces instance properties with those found in a given BER. + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @deprecated Use {@link fromBer} instead. + */ + parse (ber) { + const attr = Attribute.fromBer(ber) + this.#type = attr.type + this.values = attr.values + } + + /** + * Convert the {@link Attribute} instance to a {@link BerReader} capable of + * being used in an LDAP message. + * + * @returns {BerReader} + */ + toBer () { + const ber = new BerWriter() + + ber.startSequence() + ber.writeString(this.type) + ber.startSequence(LBER_SET) + + if (this.#buffers.length > 0) { + for (const buffer of this.#buffers) { + ber.writeByte(BerTypes.OctetString) + ber.writeLength(buffer.length) + ber.appendBuffer(buffer) + } + } else { + ber.writeStringArray([]) + } + ber.endSequence() + ber.endSequence() + + return new BerReader(ber.buffer) + } + + toJSON () { + return this.pojo + } + + /** + * Given two {@link Attribute} instances, determine if they are equal or + * different. + * + * @param {Attribute} attr1 The first object to compare. + * @param {Attribute} attr2 The second object to compare. + * + * @returns {number} `0` if the attributes are equal in value, `-1` if + * `attr1` should come before `attr2` when sorted, and `1` if `attr2` should + * come before `attr1` when sorted. + * + * @throws When either input object is not an {@link Attribute}. + */ + static compare (attr1, attr2) { + if (Attribute.isAttribute(attr1) === false || Attribute.isAttribute(attr2) === false) { + throw TypeError('can only compare Attribute instances') + } + + if (attr1.type < attr2.type) return -1 + if (attr1.type > attr2.type) return 1 + + const aValues = attr1.values + const bValues = attr2.values + if (aValues.length < bValues.length) return -1 + if (aValues.length > bValues.length) return 1 + + for (let i = 0; i < aValues.length; i++) { + if (aValues[i] < bValues[i]) return -1 + if (aValues[i] > bValues[i]) return 1 + } + + return 0 + } + + /** + * Read a BER representation of an attribute, and its values, and + * create a new {@link Attribute} instance. The BER must start + * at the beginning of a sequence. + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {Attribute} + */ + static fromBer (ber) { + ber.readSequence() + + const type = ber.readString() + const values = [] + + // If the next byte represents a BER "SET" sequence... + if (ber.peek() === LBER_SET) { + // .. read that sequence ... + /* istanbul ignore else */ + if (ber.readSequence(LBER_SET)) { + const end = ber.offset + ber.length + // ... and read all values in that set. + while (ber.offset < end) { + values.push( + ber.readString(BerTypes.OctetString, true) + ) + } + } + } + + const result = new Attribute({ + type, + values + }) + return result + } + + /** + * Given an object of attribute types mapping to attribute values, construct + * a set of Attributes. + * + * @param {object} obj Each key is an attribute type, and each value is an + * attribute value or set of values. + * + * @returns {Attribute[]} + * + * @throws If an attribute cannot be constructed correctly. + */ + static fromObject (obj) { + const attributes = [] + for (const [key, value] of Object.entries(obj)) { + if (Array.isArray(value) === true) { + attributes.push(new Attribute({ + type: key, + values: value + })) + } else { + attributes.push(new Attribute({ + type: key, + values: [value] + })) + } + } + return attributes + } + + /** + * Determine if an object represents an {@link Attribute}. + * + * @param {object} attr The object to check. It can be an instance of + * {@link Attribute} or a plain JavaScript object that looks like an + * {@link Attribute} and can be passed to the constructor to create one. + * + * @returns {boolean} + */ + static isAttribute (attr) { + if (typeof attr !== 'object') { + return false + } + + if (Object.prototype.toString.call(attr) === '[object LdapAttribute]') { + return true + } + + const typeOk = typeof attr.type === 'string' + let valuesOk = Array.isArray(attr.values) + if (valuesOk === true) { + for (const val of attr.values) { + if (typeof val !== 'string' && Buffer.isBuffer(val) === false) { + valuesOk = false + break + } + } + } + if (typeOk === true && valuesOk === true) { + return true + } + + return false + } +} + +module.exports = Attribute + +/** + * Determine the encoding for values based upon whether the binary + * option is set on the attribute. + * + * @param {string} type + * + * @returns {string} Either "utf8" for a plain string value, or "base64" for + * a binary attribute. + * + * @private + */ +function _bufferEncoding (type) { + return /;binary$/.test(type) ? 'base64' : 'utf8' +} diff --git a/node_modules/@ldapjs/attribute/index.test.js b/node_modules/@ldapjs/attribute/index.test.js new file mode 100644 index 0000000..f007f40 --- /dev/null +++ b/node_modules/@ldapjs/attribute/index.test.js @@ -0,0 +1,403 @@ +'use strict' + +const tap = require('tap') +const { + BerReader, + BerWriter +} = require('@ldapjs/asn1') +const { core: { LBER_SET } } = require('@ldapjs/protocol') +const warning = require('./lib/deprecations') +const Attribute = require('./') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +tap.test('constructor', t => { + t.test('new no args', async t => { + t.ok(new Attribute()) + // TODO: verify attributes + }) + + t.test('new with args', async t => { + let attr = new Attribute({ + type: 'cn', + values: ['foo', 'bar'] + }) + + t.ok(attr) + + attr.addValue('baz') + t.equal(attr.type, 'cn') + const values = attr.values + t.equal(values.length, 3) + t.equal(values[0], 'foo') + t.equal(values[1], 'bar') + t.equal(values[2], 'baz') + + t.throws(function () { + const typeThatIsNotAString = 1 + attr = new Attribute({ + type: typeThatIsNotAString + }) + }) + }) + + t.test('supports binary attributes', async t => { + const attr = new Attribute({ + type: 'foo;binary', + values: ['bar'] + }) + t.strictSame(attr.pojo, { + type: 'foo;binary', + values: ['bao='] + }) + }) + + t.test('warns for vals', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_001', false) + }) + + const attr = new Attribute({ + type: 'foo', + vals: ['bar'] + }) + t.ok(attr) + + function handler (error) { + t.equal( + error.message, + 'options.vals is deprecated. Use options.values instead.' + ) + t.end() + } + }) + + t.end() +}) + +tap.test('.values', t => { + t.test('adds an array of strings', async t => { + const attr = new Attribute({ type: 'foo' }) + attr.values = ['bar', 'baz'] + t.strictSame(attr.pojo, { + type: 'foo', + values: ['bar', 'baz'] + }) + }) + + t.test('adds a single string', async t => { + const attr = new Attribute({ type: 'foo' }) + attr.values = 'bar' + t.strictSame(attr.pojo, { + type: 'foo', + values: ['bar'] + }) + }) + + t.end() +}) + +tap.test('.vals', t => { + t.beforeEach(async t => { + process.on('warning', handler) + t.context.handler = handler + + function handler (error) { + t.equal( + error.message, + 'Instance property .vals is deprecated. Use property .values instead.' + ) + t.end() + } + }) + + t.afterEach(async (t) => { + process.removeListener('warning', t.context.handler) + warning.emitted.set('LDAP_ATTRIBUTE_DEP_003', false) + }) + + t.test('adds an array of strings', async t => { + const attr = new Attribute({ type: 'foo' }) + attr.vals = ['bar', 'baz'] + t.strictSame(attr.pojo, { + type: 'foo', + values: ['bar', 'baz'] + }) + }) + + t.test('adds a single string', async t => { + const attr = new Attribute({ type: 'foo' }) + attr.vals = 'bar' + t.strictSame(attr.pojo, { + type: 'foo', + values: ['bar'] + }) + }) + + t.end() +}) + +tap.test('.buffers', t => { + t.test('returns underlying buffers', async t => { + const attr = new Attribute({ + type: 'foo', + values: ['bar', 'baz'] + }) + const buffers = attr.buffers + + t.equal(buffers.length, 2) + + let expected = Buffer.from('bar', 'utf8') + t.equal(expected.compare(buffers[0]), 0) + + expected = Buffer.from('baz', 'utf8') + t.equal(expected.compare(buffers[1]), 0) + }) + + t.end() +}) + +tap.test('.type', t => { + t.test('gets and sets', async t => { + const attr = new Attribute(({ + type: 'foo', + values: ['bar'] + })) + + t.equal(attr.type, 'foo') + attr.type = 'bar' + t.equal(attr.type, 'bar') + }) + + t.end() +}) + +tap.test('toBer', async t => { + t.test('renders type with values', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['foo', 'bar'] + }) + const reader = attr.toBer() + t.ok(reader.readSequence()) + t.equal(reader.readString(), 'cn') + t.equal(reader.readSequence(LBER_SET), LBER_SET) + t.equal(reader.readString(), 'foo') + t.equal(reader.readString(), 'bar') + }) + + t.test('renders type without values', async t => { + const attr = new Attribute({ type: 'cn' }) + const reader = attr.toBer() + t.ok(reader.readSequence()) + t.equal(reader.readString(), 'cn') + t.equal(reader.readSequence(LBER_SET), LBER_SET) + t.equal(reader.remain, 0) + }) +}) + +tap.test('parse', t => { + t.beforeEach(async t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_002', false) + }) + + function handler (error) { + t.equal( + error.message, + 'Instance method .parse is deprecated. Use static .fromBer instead.' + ) + t.end() + } + }) + + t.test('parse', async t => { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('cn') + ber.startSequence(0x31) + ber.writeStringArray(['foo', 'bar']) + ber.endSequence() + ber.endSequence() + + const attr = new Attribute() + attr.parse(new BerReader(ber.buffer)) + + t.equal(attr.type, 'cn') + t.equal(attr.vals.length, 2) + t.equal(attr.vals[0], 'foo') + t.equal(attr.vals[1], 'bar') + }) + + t.test('parse - without 0x31', async t => { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('sn') + ber.endSequence() + + const attr = new Attribute() + attr.parse(new BerReader(ber.buffer)) + + t.equal(attr.type, 'sn') + t.equal(attr.vals.length, 0) + }) + + t.end() +}) + +tap.test('pojo / toJSON', t => { + t.test('returns an object', async t => { + const expected = { + type: 'foo', + values: ['bar'] + } + const attr = new Attribute(expected) + + t.strictSame(attr.pojo, expected) + t.strictSame(JSON.stringify(attr), JSON.stringify(expected)) + }) + + t.end() +}) + +tap.test('#fromBer', t => { + const attributeWithValuesBytes = [ + 0x30, 0x1c, // start first attribute sequence, 28 bytes + + 0x04, 0x0b, // string, 11 bytes + 0x6f, 0x62, 0x6a, 0x65, // "objectClass" + 0x63, 0x74, 0x43, 0x6c, + 0x61, 0x73, 0x73, + 0x31, 0x0d, // start value sequence, 13 bytes + 0x04, 0x03, 0x74, 0x6f, 0x70, // string: "top" + 0x04, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e // string: "domain" + ] + + t.test('parses an attribute with values', async t => { + const ber = new BerReader(Buffer.from(attributeWithValuesBytes)) + const attr = Attribute.fromBer(ber) + + t.equal(attr.type, 'objectClass') + t.equal(attr.vals[0], 'top') + t.equal(attr.vals[1], 'domain') + }) + + t.test('parses an attribute without values', async t => { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('sn') + ber.endSequence() + + const attr = Attribute.fromBer(new BerReader(ber.buffer)) + t.equal(attr.type, 'sn') + t.strictSame(attr.vals, []) + }) + + t.end() +}) + +tap.test('#fromObject', t => { + t.test('handles basic object', async t => { + const attrs = Attribute.fromObject({ + foo: ['foo'], + bar: 'bar', + 'baz;binary': Buffer.from([0x00]) + }) + for (const attr of attrs) { + t.equal(Object.prototype.toString.call(attr), '[object LdapAttribute]') + } + }) + + t.end() +}) + +tap.test('#isAttribute', t => { + t.test('rejects non-object', async t => { + t.equal(Attribute.isAttribute(42), false) + }) + + t.test('accepts Attribute instances', async t => { + const input = new Attribute({ + type: 'cn', + values: ['foo'] + }) + t.equal(Attribute.isAttribute(input), true) + }) + + t.test('accepts attribute-like objects', async t => { + const input = { + type: 'cn', + values: [ + 'foo', + Buffer.from('bar') + ] + } + t.equal(Attribute.isAttribute(input), true) + }) + + t.test('rejects non-attribute-like objects', async t => { + let input = { + foo: 'foo', + values: 'bar' + } + t.equal(Attribute.isAttribute(input), false) + + input = { + type: 'cn', + values: [42] + } + t.equal(Attribute.isAttribute(input), false) + }) + + t.end() +}) + +tap.test('compare', async t => { + const comp = Attribute.compare + let a = new Attribute({ + type: 'foo', + values: ['bar'] + }) + const b = new Attribute({ + type: 'foo', + values: ['bar'] + }) + const notAnAttribute = 'this is not an attribute' + + t.throws( + () => comp(a, notAnAttribute), + Error('can only compare Attribute instances') + ) + t.throws( + () => comp(notAnAttribute, b), + Error('can only compare Attribute instances') + ) + + t.equal(comp(a, b), 0) + + // Different types + a = new Attribute({ type: 'boo' }) + t.equal(comp(a, b), -1) + t.equal(comp(b, a), 1) + + // Different value counts + a = new Attribute({ + type: 'foo', + values: ['bar', 'bar'] + }) + t.equal(comp(a, b), 1) + t.equal(comp(b, a), -1) + + // Different value contents (same count) + a = new Attribute({ + type: 'foo', + values: ['baz'] + }) + t.equal(comp(a, b), 1) + t.equal(comp(b, a), -1) +}) diff --git a/node_modules/@ldapjs/attribute/lib/deprecations.js b/node_modules/@ldapjs/attribute/lib/deprecations.js new file mode 100644 index 0000000..98874e0 --- /dev/null +++ b/node_modules/@ldapjs/attribute/lib/deprecations.js @@ -0,0 +1,10 @@ +'use strict' + +const warning = require('process-warning')() +const clazz = 'LdapjsAttributeWarning' + +warning.create(clazz, 'LDAP_ATTRIBUTE_DEP_001', 'options.vals is deprecated. Use options.values instead.') +warning.create(clazz, 'LDAP_ATTRIBUTE_DEP_002', 'Instance method .parse is deprecated. Use static .fromBer instead.') +warning.create(clazz, 'LDAP_ATTRIBUTE_DEP_003', 'Instance property .vals is deprecated. Use property .values instead.') + +module.exports = warning diff --git a/node_modules/@ldapjs/attribute/package.json b/node_modules/@ldapjs/attribute/package.json new file mode 100644 index 0000000..7867908 --- /dev/null +++ b/node_modules/@ldapjs/attribute/package.json @@ -0,0 +1,47 @@ +{ + "originalAuthor": "Patrick Mooney", + "originalContributors": [ + "Mark Cavage ", + "Cody Peter Mello " + ], + "name": "@ldapjs/attribute", + "homepage": "https://github.com/ldapjs/attribute", + "description": "API for handling LDAP entry attributes", + "version": "1.0.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:ldapjs/attribute.git" + }, + "main": "index.js", + "directories": { + "lib": "./lib" + }, + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + }, + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.34.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.4" + }, + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report", + "test:cov": "tap", + "test:cov:html": "tap --coverage-report=html", + "test:watch": "tap -w --no-coverage-report" + }, + "precommit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/change/.eslintrc b/node_modules/@ldapjs/change/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/change/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/change/.github/workflows/main.yml b/node_modules/@ldapjs/change/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/change/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/change/.taprc.yaml b/node_modules/@ldapjs/change/.taprc.yaml new file mode 100644 index 0000000..7735e1e --- /dev/null +++ b/node_modules/@ldapjs/change/.taprc.yaml @@ -0,0 +1,6 @@ +reporter: terse +coverage-map: coverage-map.js + +files: + - 'index.test.js' +# - 'lib/**/*.test.js' diff --git a/node_modules/@ldapjs/change/LICENSE b/node_modules/@ldapjs/change/LICENSE new file mode 100644 index 0000000..923d87e --- /dev/null +++ b/node_modules/@ldapjs/change/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Patrick Mooney. All rights reserved. +Copyright (c) 2014 Mark Cavage, Inc. All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/change/README.md b/node_modules/@ldapjs/change/README.md new file mode 100644 index 0000000..bccbf82 --- /dev/null +++ b/node_modules/@ldapjs/change/README.md @@ -0,0 +1,8 @@ +# change + +Provides objects for managing changes as described in +[RFC 4511 §4.6](https://www.rfc-editor.org/rfc/rfc4511.html#section-4.6). + +## License + +MIT. diff --git a/node_modules/@ldapjs/change/coverage-map.js b/node_modules/@ldapjs/change/coverage-map.js new file mode 100644 index 0000000..fc2046a --- /dev/null +++ b/node_modules/@ldapjs/change/coverage-map.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = testFile => testFile.replace(/\.test\.js$/, '.js') diff --git a/node_modules/@ldapjs/change/index.js b/node_modules/@ldapjs/change/index.js new file mode 100644 index 0000000..ac440a2 --- /dev/null +++ b/node_modules/@ldapjs/change/index.js @@ -0,0 +1,320 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const Attribute = require('@ldapjs/attribute') + +/** + * Implements an LDAP CHANGE sequence as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.6. + */ +class Change { + #operation + #modification + + /** + * @typedef {object} ChangeParameters + * @property {string | number} operation One of `add` (0), `delete` (1), or + * `replace` (2). Default: `add`. + * @property {object | import('@ldapjs/attribute')} modification An attribute + * instance or an object that is shaped like an attribute. + */ + + /** + * @param {ChangeParameters} input + * + * @throws When the `modification` parameter is invalid. + */ + constructor ({ operation = 'add', modification }) { + this.operation = operation + this.modification = modification + } + + get [Symbol.toStringTag] () { + return 'LdapChange' + } + + /** + * The attribute that will be modified by the {@link Change}. + * + * @returns {import('@ldapjs/attribute')} + */ + get modification () { + return this.#modification + } + + /** + * Define the attribute to be modified by the {@link Change}. + * + * @param {object|import('@ldapjs/attribute')} mod + * + * @throws When `mod` is not an instance of `Attribute` or is not an + * `Attribute` shaped object. + */ + set modification (mod) { + if (Attribute.isAttribute(mod) === false) { + throw Error('modification must be an Attribute') + } + if (Object.prototype.toString.call(mod) !== '[object LdapAttribute]') { + mod = new Attribute(mod) + } + this.#modification = mod + } + + /** + * Get a plain JavaScript object representation of the change. + * + * @returns {object} + */ + get pojo () { + return { + operation: this.operation, + modification: this.modification.pojo + } + } + + /** + * The string name of the operation that will be performed. + * + * @returns {string} One of `add`, `delete`, or `replace`. + */ + get operation () { + switch (this.#operation) { + case 0x00: { + return 'add' + } + + case 0x01: { + return 'delete' + } + + case 0x02: { + return 'replace' + } + } + } + + /** + * Define the operation that the {@link Change} represents. + * + * @param {string|number} op May be one of `add` (0), `delete` (1), + * or `replace` (2). + * + * @throws When the `op` is not recognized. + */ + set operation (op) { + if (typeof op === 'string') { + op = op.toLowerCase() + } + + switch (op) { + case 0x00: + case 'add': { + this.#operation = 0x00 + break + } + + case 0x01: + case 'delete': { + this.#operation = 0x01 + break + } + + case 0x02: + case 'replace': { + this.#operation = 0x02 + break + } + + default: { + const type = Number.isInteger(op) + ? '0x' + Number(op).toString(16) + : op + throw Error(`invalid operation type: ${type}`) + } + } + } + + /** + * Serialize the instance to a BER. + * + * @returns {import('@ldapjs/asn1').BerReader} + */ + toBer () { + const writer = new BerWriter() + writer.startSequence() + writer.writeEnumeration(this.#operation) + + const attrBer = this.#modification.toBer() + writer.appendBuffer(attrBer.buffer) + writer.endSequence() + + return new BerReader(writer.buffer) + } + + /** + * See {@link pojo}. + * + * @returns {object} + */ + toJSON () { + return this.pojo + } + + /** + * Applies a {@link Change} to a `target` object. + * + * @example + * const change = new Change({ + * operation: 'add', + * modification: { + * type: 'cn', + * values: ['new'] + * } + * }) + * const target = { + * cn: ['old'] + * } + * Change.apply(change, target) + * // target = { cn: ['old', 'new'] } + * + * @param {Change} change The change to apply. + * @param {object} target The object to modify. This object will be mutated + * by the function. It should have properties that match the `modification` + * of the change. + * @param {boolean} scalar When `true`, will convert single-item arrays + * to scalar values. Default: `false`. + * + * @returns {object} The mutated `target`. + * + * @throws When the `change` is not an instance of {@link Change}. + */ + static apply (change, target, scalar = false) { + if (Change.isChange(change) === false) { + throw Error('change must be an instance of Change') + } + + const type = change.modification.type + const values = change.modification.values + + let data = target[type] + if (data === undefined) { + data = [] + } else if (Array.isArray(data) === false) { + data = [data] + } + + switch (change.operation) { + case 'add': { + // Add only new unique entries. + const newValues = values.filter(v => data.indexOf(v) === -1) + Array.prototype.push.apply(data, newValues) + break + } + + case 'delete': { + data = data.filter(v => values.indexOf(v) === -1) + if (data.length === 0) { + // An empty list indicates the attribute should be removed + // completely. + delete target[type] + return target + } + break + } + + case 'replace': { + if (values.length === 0) { + // A new value set that is empty is a delete. + delete target[type] + return target + } + data = values + break + } + } + + if (scalar === true && data.length === 1) { + // Replace array value with a scalar value if the modified set is + // single valued and the operation calls for a scalar. + target[type] = data[0] + } else { + target[type] = data + } + + return target + } + + /** + * Determines if an object is an instance of {@link Change}, or at least + * resembles the shape of a {@link Change} object. A plain object will match + * if it has a `modification` property that matches an `Attribute`, + * an `operation` property that is a string or number, and has a `toBer` + * method. An object that resembles a {@link Change} does not guarantee + * compatibility. A `toString` check is much more accurate. + * + * @param {Change|object} change + * + * @returns {boolean} + */ + static isChange (change) { + if (Object.prototype.toString.call(change) === '[object LdapChange]') { + return true + } + if (Object.prototype.toString.call(change) !== '[object Object]') { + return false + } + if ( + Attribute.isAttribute(change.modification) === true && + (typeof change.operation === 'string' || typeof change.operation === 'number') + ) { + return true + } + return false + } + + /** + * Compares two {@link Change} instance to determine the priority of the + * changes relative to each other. + * + * @param {Change} change1 + * @param {Change} change2 + * + * @returns {number} -1 for lower priority, 1 for higher priority, and 0 + * for equal priority in relation to `change1`, e.g. -1 would mean `change` + * has lower priority than `change2`. + * + * @throws When neither parameter resembles a {@link Change} object. + */ + static compare (change1, change2) { + if (Change.isChange(change1) === false || Change.isChange(change2) === false) { + throw Error('can only compare Change instances') + } + if (change1.operation < change2.operation) { + return -1 + } + if (change1.operation > change2.operation) { + return 1 + } + return Attribute.compare(change1.modification, change2.modification) + } + + /** + * Parse a BER into a new {@link Change} object. + * + * @param {import('@ldapjs/asn1').BerReader} ber The BER to process. It must + * be at an offset that starts a new change sequence. The reader will be + * advanced to the end of the change sequence by this method. + * + * @returns {Change} + * + * @throws When there is an error processing the BER. + */ + static fromBer (ber) { + ber.readSequence() + const operation = ber.readEnumeration() + const modification = Attribute.fromBer(ber) + return new Change({ operation, modification }) + } +} + +module.exports = Change diff --git a/node_modules/@ldapjs/change/index.test.js b/node_modules/@ldapjs/change/index.test.js new file mode 100644 index 0000000..00a08de --- /dev/null +++ b/node_modules/@ldapjs/change/index.test.js @@ -0,0 +1,422 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const Attribute = require('@ldapjs/attribute') +const Change = require('./index') + +tap.test('constructor', t => { + t.test('throws for bad operation', async t => { + t.throws( + () => new Change({ operation: 'bad' }), + Error('invalid operation type: bad') + ) + }) + + t.test('throws for bad modification', async t => { + t.throws( + () => new Change({ modification: 'bad' }), + Error('modification must be an Attribute') + ) + }) + + t.test('creates an instance', async t => { + const change = new Change({ + modification: new Attribute() + }) + t.equal(change.operation, 'add') + t.type(change.modification, Attribute) + t.equal(Object.prototype.toString.call(change), '[object LdapChange]') + }) + + t.end() +}) + +tap.test('modification', t => { + t.test('gets', async t => { + const attr = new Attribute() + const change = new Change({ modification: attr }) + t.equal(change.modification, attr) + }) + + t.test('sets', async t => { + const attr1 = new Attribute() + const attr2 = new Attribute() + const change = new Change({ modification: attr1 }) + t.equal(change.modification, attr1) + change.modification = attr2 + t.equal(change.modification, attr2) + t.not(attr1, attr2) + }) + + t.test('throws if value is not attribute-like', async t => { + const change = new Change({ modification: new Attribute() }) + t.throws( + () => { change.modification = { foo: 'foo' } }, + Error('modification must be an Attribute') + ) + }) + + t.test('converts attribute-like to Attribute', async t => { + const change = new Change({ + modification: { + type: 'dn=foo,dc=example,dc=com', + values: [] + } + }) + t.equal( + Object.prototype.toString.call(change.modification), + '[object LdapAttribute]' + ) + }) + + t.end() +}) + +tap.test('.operation', t => { + const attr = new Attribute() + const change = new Change({ modification: attr }) + + t.test('throws for unrecognized operation', async t => { + t.throws( + () => { change.operation = 'bad' }, + Error('invalid operation type: bad') + ) + t.throws( + () => { change.operation = 0xff }, + Error('invalid operation type: 0xff') + ) + }) + + t.test('sets and gets', async t => { + change.operation = 0 + t.equal(change.operation, 'add') + change.operation = 'add' + t.equal(change.operation, 'add') + + change.operation = 1 + t.equal(change.operation, 'delete') + change.operation = 'delete' + t.equal(change.operation, 'delete') + + change.operation = 2 + t.equal(change.operation, 'replace') + change.operation = 'replace' + t.equal(change.operation, 'replace') + + change.operation = 'Replace' + t.equal(change.operation, 'replace') + }) + + t.end() +}) + +tap.test('.pojo', t => { + t.test('returns a plain object', async t => { + const change = new Change({ + modification: new Attribute() + }) + const expected = { + operation: 'add', + modification: { + type: '', + values: [] + } + } + t.strictSame(change.pojo, expected) + t.strictSame(change.toJSON(), expected) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('serializes to ber', async t => { + const expected = Buffer.from([ + 0x30, 0x15, // sequence, 21 bytes + 0x0a, 0x01, 0x00, // enumerated value 0 + 0x30, 0x10, // sequence, 16 bytes + 0x04, 0x02, // string, 2 bytes + 0x63, 0x6e, // 'cn' + 0x31, 0x0a, // sequence of strings, 10 bytes + 0x04, 0x03, // string, 3 bytes + 0x66, 0x6f, 0x6f, // 'foo' + 0x04, 0x03, // string 3 bytes + 0x62, 0x61, 0x72 + ]) + const change = new Change({ + modification: { + type: 'cn', + values: ['foo', 'bar'] + } + }) + const ber = change.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#apply', t => { + t.test('throws if change is not a Change', async t => { + t.throws( + () => Change.apply({}, {}), + Error('change must be an instance of Change') + ) + }) + + t.test('applies to a target with no type', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new'] + }) + const change = new Change({ modification: attr }) + const target = {} + Change.apply(change, target) + t.strictSame(target, { + cn: ['new'] + }) + }) + + t.test('applies to a target with a scalar type', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new'] + }) + const change = new Change({ modification: attr }) + const target = { cn: 'old' } + Change.apply(change, target) + t.strictSame(target, { + cn: ['old', 'new'] + }) + }) + + t.test('applies to a target with an array type', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new'] + }) + const change = new Change({ modification: attr }) + const target = { cn: ['old'] } + Change.apply(change, target) + t.strictSame(target, { + cn: ['old', 'new'] + }) + }) + + t.test('add operation adds only new values', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new', 'foo'] + }) + const change = new Change({ modification: attr }) + const target = { cn: ['old', 'new'] } + Change.apply(change, target) + t.strictSame(target, { + cn: ['old', 'new', 'foo'] + }) + }) + + t.test('delete operation removes property', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new'] + }) + const change = new Change({ + operation: 'delete', + modification: attr + }) + const target = { cn: ['new'] } + Change.apply(change, target) + t.strictSame(target, {}) + }) + + t.test('delete operation removes values', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['remove_me'] + }) + const change = new Change({ + operation: 'delete', + modification: attr + }) + const target = { cn: ['remove_me', 'keep_me'] } + Change.apply(change, target) + t.strictSame(target, { + cn: ['keep_me'] + }) + }) + + t.test('replace removes empty set', async t => { + const attr = new Attribute({ + type: 'cn', + values: [] + }) + const change = new Change({ + operation: 'replace', + modification: attr + }) + const target = { cn: ['old'] } + Change.apply(change, target) + t.strictSame(target, {}) + }) + + t.test('replace removes values', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new_set'] + }) + const change = new Change({ + operation: 'replace', + modification: attr + }) + const target = { cn: ['old_set'] } + Change.apply(change, target) + t.strictSame(target, { + cn: ['new_set'] + }) + }) + + t.test('scalar option works for new single values', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new'] + }) + const change = new Change({ modification: attr }) + const target = {} + Change.apply(change, target, true) + t.strictSame(target, { + cn: 'new' + }) + }) + + t.test('scalar option is ignored for multiple values', async t => { + const attr = new Attribute({ + type: 'cn', + values: ['new'] + }) + const change = new Change({ modification: attr }) + const target = { + cn: ['old'] + } + Change.apply(change, target, true) + t.strictSame(target, { + cn: ['old', 'new'] + }) + }) + + t.end() +}) + +tap.test('#isChange', t => { + t.test('true for instance', async t => { + const change = new Change({ modification: new Attribute() }) + t.equal(Change.isChange(change), true) + }) + + t.test('false for non-object', async t => { + t.equal(Change.isChange([]), false) + }) + + t.test('true for shape match', async t => { + const change = { + operation: 'add', + modification: { + type: '', + values: [] + } + } + t.equal(Change.isChange(change), true) + + change.operation = 0 + change.modification = new Attribute() + t.equal(Change.isChange(change), true) + }) + + t.test('false for shape mis-match', async t => { + const change = { + operation: 'add', + mod: { + type: '', + values: [] + } + } + t.equal(Change.isChange(change), false) + }) + + t.end() +}) + +tap.test('#compare', t => { + t.test('throws if params are not changes', async t => { + const change = new Change({ modification: new Attribute() }) + const expected = Error('can only compare Change instances') + t.throws( + () => Change.compare({}, change), + expected + ) + t.throws( + () => Change.compare(change, {}), + expected + ) + }) + + t.test('orders add first', async t => { + const change1 = new Change({ modification: new Attribute() }) + const change2 = new Change({ + operation: 'delete', + modification: new Attribute() + }) + + t.equal(Change.compare(change1, change2), -1) + + change2.operation = 'replace' + t.equal(Change.compare(change1, change2), -1) + }) + + t.test('orders delete above add', async t => { + const change1 = new Change({ modification: new Attribute() }) + const change2 = new Change({ + operation: 'delete', + modification: new Attribute() + }) + + t.equal(Change.compare(change2, change1), 1) + }) + + t.test('orders by attribute for same operation', async t => { + const change1 = new Change({ modification: new Attribute() }) + const change2 = new Change({ modification: new Attribute() }) + t.equal(Change.compare(change1, change2), 0) + }) + + t.end() +}) + +tap.test('#fromBer', t => { + t.test('creates instance', async t => { + const bytes = [ + 0x30, 0x15, // sequence, 21 bytes + 0x0a, 0x01, 0x00, // enumerated value 0 + 0x30, 0x10, // sequence, 16 bytes + 0x04, 0x02, // string, 2 bytes + 0x63, 0x6e, // 'cn' + 0x31, 0x0a, // sequence of strings, 10 bytes + 0x04, 0x03, // string, 3 bytes + 0x66, 0x6f, 0x6f, // 'foo' + 0x04, 0x03, // string 3 bytes + 0x62, 0x61, 0x72 + ] + const reader = new BerReader(Buffer.from(bytes)) + const change = Change.fromBer(reader) + t.strictSame(change.pojo, { + operation: 'add', + modification: { + type: 'cn', + values: ['foo', 'bar'] + } + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/change/package.json b/node_modules/@ldapjs/change/package.json new file mode 100644 index 0000000..6bcc722 --- /dev/null +++ b/node_modules/@ldapjs/change/package.json @@ -0,0 +1,43 @@ +{ + "originalAuthor": "Patrick Mooney", + "originalContributors": [ + "Mark Cavage ", + "Cody Peter Mello " + ], + "name": "@ldapjs/change", + "homepage": "https://github.com/ldapjs/change", + "description": "API for handling LDAP change objects", + "version": "1.0.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:ldapjs/change.git" + }, + "main": "index.js", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0" + }, + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.34.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.4" + }, + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report", + "test:cov": "tap", + "test:cov:html": "tap --coverage-report=html", + "test:watch": "tap -w --no-coverage-report" + }, + "precommit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/controls/.eslintrc b/node_modules/@ldapjs/controls/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/controls/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/controls/.github/workflows/main.yml b/node_modules/@ldapjs/controls/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/controls/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/controls/.taprc.yml b/node_modules/@ldapjs/controls/.taprc.yml new file mode 100644 index 0000000..5f38a24 --- /dev/null +++ b/node_modules/@ldapjs/controls/.taprc.yml @@ -0,0 +1,5 @@ +files: + - 'index.test.js' + - 'lib/**/*.test.js' + +coverage-map: coverage-map.js diff --git a/node_modules/@ldapjs/controls/LICENSE b/node_modules/@ldapjs/controls/LICENSE new file mode 100644 index 0000000..1913201 --- /dev/null +++ b/node_modules/@ldapjs/controls/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2011 Mark Cavage, All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/controls/Readme.md b/node_modules/@ldapjs/controls/Readme.md new file mode 100644 index 0000000..4c97fc6 --- /dev/null +++ b/node_modules/@ldapjs/controls/Readme.md @@ -0,0 +1,12 @@ +# @ldapjs/controls + +This package provides implementations of [LDAP controls][controls]. The +primary purpose of this library is to facilitate client and server +implementations in the [`ldapjs`](https://npm.im/ldapjs) package. + +## Docs + +At this time, one must reference the code to learn about the available +controls and their methods. + +[controls]: https://datatracker.ietf.org/doc/html/rfc4511#section-4.1.11 diff --git a/node_modules/@ldapjs/controls/coverage-map.js b/node_modules/@ldapjs/controls/coverage-map.js new file mode 100644 index 0000000..00ca53e --- /dev/null +++ b/node_modules/@ldapjs/controls/coverage-map.js @@ -0,0 +1,13 @@ +module.exports = testFile => { + if (testFile.startsWith('virtual-list-view-request-control') === true) { + // Do not count towards coverage as it is disabled. + return false + } + + if (testFile.startsWith('virtual-list-view-response-control') === true) { + // Do not count towards coverage as it is disabled. + return false + } + + testFile.replace(/\.test\.js$/, '.js') +} diff --git a/node_modules/@ldapjs/controls/index.js b/node_modules/@ldapjs/controls/index.js new file mode 100644 index 0000000..b535c1c --- /dev/null +++ b/node_modules/@ldapjs/controls/index.js @@ -0,0 +1,103 @@ +'use strict' + +const { Ber } = require('@ldapjs/asn1') + +const Control = require('./lib/control') +const EntryChangeNotificationControl = require('./lib/controls/entry-change-notification-control') +const PagedResultsControl = require('./lib/controls/paged-results-control') +const PasswordPolicyControl = require('./lib/controls/password-policy-control') +const PersistentSearchControl = require('./lib/controls/persistent-search-control') +const ServerSideSortingRequestControl = require('./lib/controls/server-side-sorting-request-control') +const ServerSideSortingResponseControl = require('./lib/controls/server-side-sorting-response-control') +const VirtualListViewRequestControl = require('./lib/controls/virtual-list-view-request-control') +const VirtualListViewResponseControl = require('./lib/controls/virtual-list-view-response-control') + +module.exports = { + + getControl: function getControl (ber) { + if (!ber) throw TypeError('ber must be provided') + + if (ber.readSequence() === null) { return null } + + let type + const opts = { + criticality: false, + value: null + } + + /* istanbul ignore else */ + if (ber.length) { + const end = ber.offset + ber.length + + type = ber.readString() + /* istanbul ignore else */ + if (ber.offset < end) { + /* istanbul ignore else */ + if (ber.peek() === Ber.Boolean) { opts.criticality = ber.readBoolean() } + } + + if (ber.offset < end) { opts.value = ber.readString(Ber.OctetString, true) } + } + + let control + switch (type) { + case EntryChangeNotificationControl.OID: { + control = new EntryChangeNotificationControl(opts) + break + } + + case PagedResultsControl.OID: { + control = new PagedResultsControl(opts) + break + } + + case PasswordPolicyControl.OID: { + control = new PasswordPolicyControl(opts) + break + } + + case PersistentSearchControl.OID: { + control = new PersistentSearchControl(opts) + break + } + + case ServerSideSortingRequestControl.OID: { + control = new ServerSideSortingRequestControl(opts) + break + } + + case ServerSideSortingResponseControl.OID: { + control = new ServerSideSortingResponseControl(opts) + break + } + + case VirtualListViewRequestControl.OID: { + control = new VirtualListViewRequestControl(opts) + break + } + + case VirtualListViewResponseControl.OID: { + control = new VirtualListViewResponseControl(opts) + break + } + + default: { + opts.type = type + control = new Control(opts) + break + } + } + + return control + }, + + Control, + EntryChangeNotificationControl, + PagedResultsControl, + PasswordPolicyControl, + PersistentSearchControl, + ServerSideSortingRequestControl, + ServerSideSortingResponseControl, + VirtualListViewRequestControl, + VirtualListViewResponseControl +} diff --git a/node_modules/@ldapjs/controls/index.test.js b/node_modules/@ldapjs/controls/index.test.js new file mode 100644 index 0000000..1762149 --- /dev/null +++ b/node_modules/@ldapjs/controls/index.test.js @@ -0,0 +1,161 @@ +'use strict' + +const tap = require('tap') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const controls = require('.') + +tap.test('#getControl', t => { + t.test('requires a BER to parse', async t => { + try { + controls.getControl() + t.fail('should throw exception') + } catch (error) { + t.match(error, /ber must be provided/) + } + }) + + t.test('returns null for empty BER', async t => { + const result = controls.getControl(new BerReader(Buffer.alloc(0))) + t.equal(result, null) + }) + + t.test('parses a BER (control)', async t => { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('2.16.840.1.113730.3.4.2') + ber.writeBoolean(true) + ber.writeString('foo') + ber.endSequence() + + const control = controls.getControl(new BerReader(ber.buffer)) + + t.ok(control) + t.equal(control.type, '2.16.840.1.113730.3.4.2') + t.ok(control.criticality) + t.equal(control.value.toString('utf8'), 'foo') + t.end() + }) + + t.test('parses BER with no value', function (t) { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('2.16.840.1.113730.3.4.2') + ber.endSequence() + + const control = controls.getControl(new BerReader(ber.buffer)) + + t.ok(control) + t.equal(control.type, '2.16.840.1.113730.3.4.2') + t.equal(control.criticality, false) + t.notOk(control.value, null) + t.end() + }) + + t.test('returns a EntryChangeNotificationControl', async t => { + const ecnc = new controls.EntryChangeNotificationControl({ + type: controls.EntryChangeNotificationControl.OID, + criticality: true, + value: { + changeType: 8, + previousDN: 'cn=foobarbazcar', + changeNumber: 123456789 + } + }) + + const ber = new BerWriter() + ecnc.toBer(ber) + + const c = controls.getControl(new BerReader(ber.buffer)) + t.ok(c) + t.equal(c.type, controls.EntryChangeNotificationControl.OID) + t.ok(c.criticality) + t.equal(c.value.changeType, 8) + t.equal(c.value.previousDN, 'cn=foobarbazcar') + t.equal(c.value.changeNumber, 123456789) + }) + + t.test('returns a PagedResultsControl', async t => { + const prc = new controls.PagedResultsControl({ + type: controls.PagedResultsControl.OID, + criticality: true, + value: { + size: 20, + cookie: Buffer.alloc(0) + } + }) + + const ber = new BerWriter() + prc.toBer(ber) + + const c = controls.getControl(new BerReader(ber.buffer)) + t.ok(c) + t.equal(c.type, controls.PagedResultsControl.OID) + t.ok(c.criticality) + t.equal(c.value.size, 20) + t.equal(Buffer.compare(c.value.cookie, Buffer.alloc(0)), 0) + }) + + t.test('returns a PasswordPolicyControl', async t => { + const ppc = new controls.PasswordPolicyControl({ + type: controls.PasswordPolicyControl.OID, + criticality: true, + value: { + error: 1, + timeBeforeExpiration: 2 + } + }) + + const ber = new BerWriter() + ppc.toBer(ber) + + const c = controls.getControl(new BerReader(ber.buffer)) + t.ok(c) + t.equal(c.type, controls.PasswordPolicyControl.OID) + t.ok(c.criticality) + t.equal(c.value.error, 1) + t.equal(c.value.timeBeforeExpiration, 2) + }) + + t.test('returns a PersistentSearchControl', async t => { + const buf = Buffer.from([ + 0x30, 0x26, 0x04, 0x17, 0x32, 0x2e, 0x31, 0x36, 0x2e, 0x38, 0x34, 0x30, + 0x2e, 0x31, 0x2e, 0x31, 0x31, 0x33, 0x37, 0x33, 0x30, 0x2e, 0x33, 0x2e, + 0x34, 0x2e, 0x33, 0x04, 0x0b, 0x30, 0x09, 0x02, 0x01, 0x0f, 0x01, 0x01, + 0xff, 0x01, 0x01, 0xff]) + + const ber = new BerReader(buf) + const psc = controls.getControl(ber) + t.ok(psc) + t.equal(psc.type, controls.PersistentSearchControl.OID) + t.equal(psc.criticality, false) + t.equal(psc.value.changeTypes, 15) + t.equal(psc.value.changesOnly, true) + t.equal(psc.value.returnECs, true) + }) + + t.test('returns a ServerSideSortingRequestControl', async t => { + const sssc = new controls.ServerSideSortingRequestControl() + const ber = new BerWriter() + sssc.toBer(ber) + + const c = controls.getControl(new BerReader(ber.buffer)) + t.ok(c) + t.equal(c.type, controls.ServerSideSortingRequestControl.OID) + t.equal(c.value.length, 0) + }) + + t.test('returns a ServerSideSortingResponseControl', async t => { + const sssc = new controls.ServerSideSortingResponseControl() + const ber = new BerWriter() + sssc.toBer(ber) + + const c = controls.getControl(new BerReader(ber.buffer)) + t.ok(c) + t.equal(c.type, controls.ServerSideSortingResponseControl.OID) + t.equal(c.criticality, false) + t.notOk(c.value.result) + t.notOk(c.value.failedAttribute) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/control.js b/node_modules/@ldapjs/controls/lib/control.js new file mode 100644 index 0000000..d484b68 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/control.js @@ -0,0 +1,88 @@ +'use strict' + +const { BerWriter } = require('@ldapjs/asn1') + +/** + * Baseline LDAP control object. Implements + * https://tools.ietf.org/html/rfc4511#section-4.1.11 + * + * @class + */ +class Control { + /** + * @typedef {object} ControlParams + * @property {string} [type=''] The dotted decimal control type value. + * @property {boolean} [criticality=false] Criticality value for the control. + * @property {string|Buffer} [value] The value for the control. If this is + * a `string` then it will be written as-is. If it is an instance of `Buffer` + * then it will be written by `value.toString()` when generating a BER + * instance. + */ + + /** + * Create a new baseline LDAP control. + * + * @param {ControlParams} [options] + */ + constructor (options = {}) { + const opts = Object.assign({ type: '', criticality: false, value: null }, options) + this.type = opts.type + this.criticality = opts.criticality + this.value = opts.value + } + + get [Symbol.toStringTag] () { + return 'LdapControl' + } + + /** + * Serializes the control into a plain JavaScript object that can be passed + * to the constructor as an options object. If an instance has a `_pojo(obj)` + * method then the built object will be sent to that method and the resulting + * mutated object returned. + * + * @returns {object} A plain JavaScript object that represents an LDAP control. + */ + get pojo () { + const obj = { + type: this.type, + value: this.value, + criticality: this.criticality + } + + if (typeof this._pojo === 'function') { + this._pojo(obj) + } + + return obj + } + + /** + * Converts the instance into a [BER](http://luca.ntop.org/Teaching/Appunti/asn1.html) + * representation. + * + * @param {BerWriter} [ber] An empty `BerWriter` instance to populate. + * + * @returns {object} A BER object. + */ + toBer (ber = new BerWriter()) { + ber.startSequence() + ber.writeString(this.type || '') + ber.writeBoolean(this.criticality) + + /* istanbul ignore else */ + if (typeof (this._toBer) === 'function') { + this._toBer(ber) + } else if (this.value !== undefined) { + if (typeof this.value === 'string') { + ber.writeString(this.value) + } else if (Buffer.isBuffer(this.value)) { + ber.writeString(this.value.toString()) + } + } + + ber.endSequence() + return ber + } +} +module.exports = Control diff --git a/node_modules/@ldapjs/controls/lib/control.test.js b/node_modules/@ldapjs/controls/lib/control.test.js new file mode 100644 index 0000000..4164eb3 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/control.test.js @@ -0,0 +1,159 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const Control = require('./control') + +tap.test('constructor', t => { + t.test('new no args', function (t) { + t.ok(new Control()) + t.equal(Object.prototype.toString.call(new Control()), '[object LdapControl]') + t.end() + }) + + t.test('new with args', function (t) { + const c = new Control({ + type: '2.16.840.1.113730.3.4.2', + criticality: true + }) + t.ok(c) + t.equal(c.type, '2.16.840.1.113730.3.4.2') + t.ok(c.criticality) + t.end() + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('passes through _pojo', async t => { + class Foo extends Control { + _pojo (obj) { + obj.foo = 'foo' + } + } + const control = new Foo() + t.strictSame(control.pojo, { + type: '', + value: null, + criticality: false, + foo: 'foo' + }) + }) + + t.test('returns basic object', async t => { + const control = new Control({ type: '1.2.3', criticality: false, value: 'foo' }) + t.strictSame(control.pojo, { + type: '1.2.3', + value: 'foo', + criticality: false + }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString('') + target.writeBoolean(false) + target.endSequence() + + const control = new Control() + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString('2.16.840.1.113730.3.4.2') + target.writeBoolean(true) + target.writeString('foo') + target.endSequence() + + const control = new Control({ + type: '2.16.840.1.113730.3.4.2', + criticality: true, + value: Buffer.from('foo', 'utf8') + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts instance to BER (side effect manner)', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString('2.16.840.1.113730.3.4.2') + target.writeBoolean(true) + target.writeString('foo') + target.endSequence() + + const control = new Control({ + type: '2.16.840.1.113730.3.4.2', + criticality: true, + value: Buffer.from('foo', 'utf8') + }) + const ber = new BerWriter() + control.toBer(ber) + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts instance to BER with string value', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString('2.16.840.1.113730.3.4.2') + target.writeBoolean(true) + target.writeString('foo') + target.endSequence() + + const control = new Control({ + type: '2.16.840.1.113730.3.4.2', + criticality: true, + value: 'foo' + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('ignores unrecognized value', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString('2.16.840.1.113730.3.4.2') + target.writeBoolean(true) + target.writeBoolean(false) + target.endSequence() + + const control = new Control({ + type: '2.16.840.1.113730.3.4.2', + criticality: true, + value: false + }) + const ber = control.toBer() + + t.not(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('passes through _toBer', async t => { + t.plan(2) + const target = new BerWriter() + target.startSequence() + target.writeString('') + target.writeBoolean(false) + target.endSequence() + + const control = new Control() + control._toBer = (ber) => t.ok(ber) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/entry-change-notification-control.js b/node_modules/@ldapjs/controls/lib/controls/entry-change-notification-control.js new file mode 100644 index 0000000..d27f2f2 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/entry-change-notification-control.js @@ -0,0 +1,107 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') + +/** + * @typedef {object} EntryChangeNotificationControlValue + * @property {number} changeType One of 1 (add), 2 (delete), 4 (modify), + * or 8 (modifyDN). + * @property {string} previousDN Only set when operation is a modifyDN op. + * @property {number} changeNumber + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-psearch-03.txt#section-5 + * + * @extends Control + */ +class EntryChangeNotificationControl extends Control { + static OID = '2.16.840.1.113730.3.4.7' + + /** + * @typedef {ControlParams} EntryChangeNotificationParams + * @property {EntryChangeNotificationControlValue | Buffer} [value] + */ + + /** + * Creates a new persistent search control. + * + * @param {EntryChangeNotificationParams} [options] + */ + constructor (options = {}) { + options.type = EntryChangeNotificationControl.OID + super(options) + + this._value = { + changeType: 4 + } + + if (hasOwn(options, 'value') === false) { + return + } + + if (Buffer.isBuffer(options.value)) { + this.#parse(options.value) + } else if (isObject(options.value)) { + this._value = options.value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + } + + get value () { + return this._value + } + + set value (obj) { + this._value = Object.assign({}, this._value, obj) + } + + /** + * Given a BER buffer that represents a + * {@link EntryChangeNotificationControlValue}, read that buffer into the + * current instance. + */ + #parse (buffer) { + const ber = new BerReader(buffer) + /* istanbul ignore else */ + if (ber.readSequence()) { + this._value = { + changeType: ber.readInt() + } + + /* istanbul ignore else */ + if (this._value.changeType === 8) { + // If the operation was moddn, then parse the optional previousDN attr. + this._value.previousDN = ber.readString() + } + + this._value.changeNumber = ber.readInt() + } + } + + _toBer (ber) { + const writer = new BerWriter() + writer.startSequence() + writer.writeInt(this._value.changeType) + if (this._value.previousDN) { writer.writeString(this._value.previousDN) } + + if (Object.prototype.hasOwnProperty.call(this._value, 'changeNumber')) { + writer.writeInt(parseInt(this._value.changeNumber, 10)) + } + writer.endSequence() + + ber.writeBuffer(writer.buffer, 0x04) + return ber + } + + _updatePlainObject (obj) { + obj.controlValue = this.value + return obj + } +} +module.exports = EntryChangeNotificationControl diff --git a/node_modules/@ldapjs/controls/lib/controls/entry-change-notification-control.test.js b/node_modules/@ldapjs/controls/lib/controls/entry-change-notification-control.test.js new file mode 100644 index 0000000..e6f09ed --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/entry-change-notification-control.test.js @@ -0,0 +1,133 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const ECNC = require('./entry-change-notification-control') +const Control = require('../control') + +tap.test('contructor', t => { + t.test('new no args', async t => { + const control = new ECNC() + t.ok(control) + t.type(control, ECNC) + t.type(control, Control) + t.equal(control.type, ECNC.OID) + t.same(control.value, { + changeType: 4 + }) + }) + + t.test('new with args', async t => { + const control = new ECNC({ + type: '2.16.840.1.113730.3.4.7', + criticality: true, + value: { + changeType: 1 + } + }) + t.ok(control) + t.equal(control.type, '2.16.840.1.113730.3.4.7') + t.ok(control.criticality) + t.same(control.value, { + changeType: 1 + }) + }) + + t.test('with value buffer', async t => { + const value = new BerWriter() + value.startSequence() + value.writeInt(8) + value.writeString('dn=foo') + value.writeInt(42) + value.endSequence() + + const control = new ECNC({ value: value.buffer }) + t.same(control.value, { + changeType: 8, + previousDN: 'dn=foo', + changeNumber: 42 + }) + }) + + t.test('throws for bad value', async t => { + t.throws(() => new ECNC({ value: 42 })) + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('adds control value', async t => { + const control = new ECNC({ + value: { + changeType: 8, + previousDN: 'dn=foo', + changeNumber: 42 + } + }) + t.strictSame(control.pojo, { + type: ECNC.OID, + criticality: false, + value: { + changeType: 8, + previousDN: 'dn=foo', + changeNumber: 42 + } + }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(ECNC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence() + value.writeInt(4) + // value.writeInt(0) + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new ECNC() + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts instance with full values to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(ECNC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence() + value.writeInt(8) + value.writeString('dn=foo') + value.writeInt(42) + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new ECNC({ + value: { + changeType: 8, + previousDN: 'dn=foo', + changeNumber: 42 + } + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/paged-results-control.js b/node_modules/@ldapjs/controls/lib/controls/paged-results-control.js new file mode 100644 index 0000000..fe7dc5f --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/paged-results-control.js @@ -0,0 +1,103 @@ +'use strict' + +const { Ber, BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') + +/** + * @typedef {object} PagedResultsControlValue + * @property {number} size The requested page size from a client, or the result + * set size estimate from the server. + * @property {Buffer} cookie Identifier for the result set. + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/rfc2696#section-2 + * + * @extends Control + */ +class PagedResultsControl extends Control { + static OID = '1.2.840.113556.1.4.319' + + /** + * @typedef {ControlParams} PagedResultsParams + * @property {PagedResultsControlValue | Buffer} [value] + */ + + /** + * Creates a new paged results control. + * + * @param {PagedResultsParams} [options] + */ + constructor (options = {}) { + options.type = PagedResultsControl.OID + super(options) + + this._value = { + size: 0, + cookie: Buffer.alloc(0) + } + + if (hasOwn(options, 'value') === false) { + return + } + + if (Buffer.isBuffer(options.value)) { + this.#parse(options.value) + } else if (isObject(options.value)) { + this.value = options.value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + } + + get value () { + return this._value + } + + set value (obj) { + this._value = Object.assign({}, this._value, obj) + if (typeof this._value.cookie === 'string') { + this._value.cookie = Buffer.from(this._value.cookie) + } + } + + #parse (buffer) { + const ber = new BerReader(buffer) + + /* istanbul ignore else */ + if (ber.readSequence()) { + this._value = {} + this._value.size = ber.readInt() + this._value.cookie = ber.readString(Ber.OctetString, true) + // readString returns '' instead of a zero-length buffer + if (!this._value.cookie) { + this._value.cookie = Buffer.alloc(0) + } + } + } + + _toBer (ber) { + const writer = new BerWriter() + writer.startSequence() + writer.writeInt(this._value.size) + if (this._value.cookie && this._value.cookie.length > 0) { + writer.writeBuffer(this._value.cookie, Ber.OctetString) + } else { + // writeBuffer rejects zero-length buffers + writer.writeString('') + } + writer.endSequence() + + ber.writeBuffer(writer.buffer, Ber.OctetString) + return ber + } + + _updatePlainObject (obj) { + obj.controlValue = this.value + return obj + } +} +module.exports = PagedResultsControl diff --git a/node_modules/@ldapjs/controls/lib/controls/paged-results-control.test.js b/node_modules/@ldapjs/controls/lib/controls/paged-results-control.test.js new file mode 100644 index 0000000..9bc5b64 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/paged-results-control.test.js @@ -0,0 +1,139 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const PSC = require('./paged-results-control') +const Control = require('../control') + +tap.test('contructor', t => { + t.test('new no args', async t => { + const control = new PSC() + t.ok(control) + t.type(control, PSC) + t.type(control, Control) + t.equal(control.type, PSC.OID) + t.equal(control.value.size, 0) + t.equal(Buffer.alloc(0).compare(control.value.cookie), 0) + }) + + t.test('new with args', async t => { + const control = new PSC({ + type: '1.2.840.113556.1.4.319', + criticality: true, + value: { + size: 1, + cookie: 'foo' + } + }) + t.ok(control) + t.equal(control.type, '1.2.840.113556.1.4.319') + t.ok(control.criticality) + t.equal(control.value.size, 1) + t.equal(Buffer.from('foo').compare(control.value.cookie), 0) + }) + + t.test('with value buffer', async t => { + const value = new BerWriter() + value.startSequence() + value.writeInt(1) + value.writeBuffer(Buffer.from('foo'), 0x04) + value.endSequence() + + const control = new PSC({ value: value.buffer }) + t.equal(control.value.size, 1) + t.equal(Buffer.from('foo').compare(control.value.cookie), 0) + }) + + t.test('with value buffer (empty cookie)', async t => { + const value = new BerWriter() + value.startSequence() + value.writeInt(1) + value.endSequence() + + const control = new PSC({ value: value.buffer }) + t.equal(control.value.size, 1) + t.equal(Buffer.alloc(0).compare(control.value.cookie), 0) + }) + + t.test('throws for bad value', async t => { + t.throws(() => new PSC({ value: 42 })) + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('adds control value', async t => { + const control = new PSC({ + value: { + size: 1, + cookie: 'foo' + } + }) + t.same(control.pojo, { + type: PSC.OID, + criticality: false, + value: { + size: 1, + cookie: Buffer.from('foo') + } + }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(PSC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence() + value.writeInt(1) + value.writeString('foo') + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new PSC({ + value: { + size: 1, + cookie: 'foo' + } + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts empty instance to BER (empty cookie)', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(PSC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence() + value.writeInt(1) + value.writeString('') + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new PSC({ + value: { + size: 1 + } + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/password-policy-control.js b/node_modules/@ldapjs/controls/lib/controls/password-policy-control.js new file mode 100644 index 0000000..b10a083 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/password-policy-control.js @@ -0,0 +1,118 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') + +/** + * @typedef {object} PasswordPolicyResponseControlValue + * @property {number} error One of 0 (passwordExpired), 1 (accountLocked), + * 2 (changeAfterReset), 3 (passwordModNotAllowed), 4 (mustSupplyOldPassword), + * 5 (insufficientPasswordQuality), 6 (passwordTooShort), 7 (passwordTooYoung), + * 8 (passwordInHistory), 9 (passwordTooYoung) + * @property {number} timeBeforeExpiration + * @property {number} graceAuthNsRemaining + */ + +/** + * Implements both request and response controls: + * https://datatracker.ietf.org/doc/html/draft-behera-ldap-password-policy-11#name-controls-used-for-password- + * + * @extends Control + */ +class PasswordPolicyControl extends Control { + static OID = '1.3.6.1.4.1.42.2.27.8.5.1' + + /** + * @typedef {ControlParams} PasswordPolicyResponseParams + * @property {PasswordPolicyResponseControlValue | Buffer} [value] + */ + + /** + * Creates a new password policy control. + * + * @param {PasswordPolicyResponseParams} [options] + */ + constructor (options = {}) { + options.type = PasswordPolicyControl.OID + super(options) + + this._value = {} + + if (hasOwn(options, 'value') === false) { + return + } + + if (Buffer.isBuffer(options.value)) { + this.#parse(options.value) + } else if (isObject(options.value)) { + if (hasOwn(options.value, 'timeBeforeExpiration') === true && hasOwn(options.value, 'graceAuthNsRemaining') === true) { + throw new Error('options.value must contain either timeBeforeExpiration or graceAuthNsRemaining, not both') + } + this._value = options.value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + } + + get value () { + return this._value + } + + set value (obj) { + this._value = Object.assign({}, this._value, obj) + } + + /** + * Given a BER buffer that represents a + * {@link PasswordPolicyResponseControlValue}, read that buffer into the + * current instance. + */ + #parse (buffer) { + const ber = new BerReader(buffer) + if (ber.readSequence()) { + this._value = {} + if (ber.peek() === 0xa0) { + ber.readSequence(0xa0) + if (ber.peek() === 0x80) { + this._value.timeBeforeExpiration = ber._readTag(0x80) + } else if (ber.peek() === 0x81) { + this._value.graceAuthNsRemaining = ber._readTag(0x81) + } + } + if (ber.peek() === 0x81) { + this._value.error = ber._readTag(0x81) + } + } + } + + _toBer (ber) { + if (!this._value || Object.keys(this._value).length === 0) { return } + + const writer = new BerWriter() + writer.startSequence() + if (hasOwn(this._value, 'timeBeforeExpiration')) { + writer.startSequence(0xa0) + writer.writeInt(this._value.timeBeforeExpiration, 0x80) + writer.endSequence() + } else if (hasOwn(this._value, 'graceAuthNsRemaining')) { + writer.startSequence(0xa0) + writer.writeInt(this._value.graceAuthNsRemaining, 0x81) + writer.endSequence() + } + if (hasOwn(this._value, 'error')) { + writer.writeInt(this._value.error, 0x81) + } + writer.endSequence() + + ber.writeBuffer(writer.buffer, 0x04) + return ber + } + + _updatePlainObject (obj) { + obj.controlValue = this.value + return obj + } +} +module.exports = PasswordPolicyControl diff --git a/node_modules/@ldapjs/controls/lib/controls/password-policy-control.test.js b/node_modules/@ldapjs/controls/lib/controls/password-policy-control.test.js new file mode 100644 index 0000000..a55ccfa --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/password-policy-control.test.js @@ -0,0 +1,113 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const PPC = require('./password-policy-control') +const Control = require('../control') + +tap.test('contructor', t => { + t.test('new no args', async t => { + const control = new PPC() + t.ok(control) + t.type(control, PPC) + t.type(control, Control) + t.equal(control.type, PPC.OID) + t.same(control.value, {}) + }) + + t.test('new with args', async t => { + const control = new PPC({ + type: '1.3.6.1.4.1.42.2.27.8.5.1', + criticality: true, + value: { + error: 1, + timeBeforeExpiration: 2 + } + }) + t.ok(control) + t.equal(control.type, '1.3.6.1.4.1.42.2.27.8.5.1') + t.ok(control.criticality) + t.same(control.value, { + error: 1, + timeBeforeExpiration: 2 + }) + }) + + t.test('with value buffer', async t => { + const value = new BerWriter() + value.startSequence() + value.writeInt(5, 0x81) + value.endSequence() + + const control = new PPC({ value: value.buffer }) + t.same(control.value, { + error: 5 + }) + }) + + t.test('throws for bad value', async t => { + t.throws(() => new PPC({ value: 42 })) + t.throws(() => new PPC({ value: { timeBeforeExpiration: 1, graceAuthNsRemaining: 2 } })) + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('adds control value', async t => { + const control = new PPC() + t.same(control.pojo, { + type: PPC.OID, + criticality: false, + value: {} + }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(PPC.OID) + target.writeBoolean(false) // Control.criticality + target.endSequence() + + const control = new PPC() + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts full instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(PPC.OID) + target.writeBoolean(true) // Control.criticality + + const value = new BerWriter() + value.startSequence() + value.startSequence(0xa0) + value.writeInt(2, 0x81) + value.endSequence() + value.writeInt(1, 0x81) + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new PPC({ + criticality: true, + value: { + error: 1, + graceAuthNsRemaining: 2 + } + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/persistent-search-control.js b/node_modules/@ldapjs/controls/lib/controls/persistent-search-control.js new file mode 100644 index 0000000..12cf5ee --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/persistent-search-control.js @@ -0,0 +1,100 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') + +/** + * @typedef {object} PersistentSearchControlValue + * @property {number} changeTypes A bitwise OR of 1 (add), 2 (delete), + * 4 (modify), and 8 (modifyDN). + * @property {boolean} changesOnly + * @property {boolean} returnECs + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-psearch-03.txt + * + * @extends Control + */ +class PersistentSearchControl extends Control { + static OID = '2.16.840.1.113730.3.4.3' + + /** + * @typedef {ControlParams} PersistentSearchParams + * @property {PersistentSearchControlValue | Buffer} [value] + */ + + /** + * Creates a new persistent search control. + * + * @param {PersistentSearchParams} [options] + */ + constructor (options = {}) { + options.type = PersistentSearchControl.OID + super(options) + + this._value = { + changeTypes: 15, + changesOnly: true, + returnECs: true + } + + if (hasOwn(options, 'value') === false) { + return + } + + if (Buffer.isBuffer(options.value)) { + this.#parse(options.value) + } else if (isObject(options.value)) { + this._value = options.value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + } + + get value () { + return this._value + } + + set value (obj) { + this._value = Object.assign({}, this._value, obj) + } + + /** + * Given a BER buffer that represents a {@link PersistentSearchControlValue}, + * read that buffer into the current instance. + */ + #parse (buffer) { + const ber = new BerReader(buffer) + + /* istanbul ignore else */ + if (ber.readSequence()) { + this._value = { + changeTypes: ber.readInt(), + changesOnly: ber.readBoolean(), + returnECs: ber.readBoolean() + } + } + } + + _toBer (ber) { + const writer = new BerWriter() + writer.startSequence() + writer.writeInt(this._value.changeTypes) + writer.writeBoolean(this._value.changesOnly) + writer.writeBoolean(this._value.returnECs) + writer.endSequence() + + ber.writeBuffer(writer.buffer, 0x04) + return ber + } + + _updatePlainObject (obj) { + obj.controlValue = this.value + return obj + } +} +module.exports = PersistentSearchControl diff --git a/node_modules/@ldapjs/controls/lib/controls/persistent-search-control.test.js b/node_modules/@ldapjs/controls/lib/controls/persistent-search-control.test.js new file mode 100644 index 0000000..c3f0bb2 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/persistent-search-control.test.js @@ -0,0 +1,106 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const PSC = require('./persistent-search-control') +const Control = require('../control') + +tap.test('contructor', t => { + t.test('new no args', async t => { + const control = new PSC() + t.ok(control) + t.type(control, PSC) + t.type(control, Control) + t.equal(control.type, PSC.OID) + t.same(control.value, { + changeTypes: 15, + changesOnly: true, + returnECs: true + }) + }) + + t.test('new with args', async t => { + const control = new PSC({ + type: '2.16.840.1.113730.3.4.3', + criticality: true, + value: { + changeTypes: 1, + changesOnly: false, + returnECs: true + } + }) + t.ok(control) + t.equal(control.type, '2.16.840.1.113730.3.4.3') + t.ok(control.criticality) + t.same(control.value, { + changeTypes: 1, + changesOnly: false, + returnECs: true + }) + }) + + t.test('with value buffer', async t => { + const value = new BerWriter() + value.startSequence() + value.writeInt(2) + value.writeBoolean(true) + value.writeBoolean(false) + value.endSequence() + + const control = new PSC({ value: value.buffer }) + t.same(control.value, { + changeTypes: 2, + changesOnly: true, + returnECs: false + }) + }) + + t.test('throws for bad value', async t => { + t.throws(() => new PSC({ value: 42 })) + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('adds control value', async t => { + const control = new PSC() + t.same(control.pojo, { + type: PSC.OID, + criticality: false, + value: { + changeTypes: 15, + changesOnly: true, + returnECs: true + } + }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(PSC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence() + value.writeInt(15) + value.writeBoolean(true) + value.writeBoolean(true) + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new PSC() + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-request-control.js b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-request-control.js new file mode 100644 index 0000000..878fa4f --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-request-control.js @@ -0,0 +1,132 @@ +'use strict' + +const { Ber, BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') + +/** + * @typedef {object} SortKeyItem + * @property {string} attributeType + * @property {string} orderingRule + * @property {boolean} reverseOrder + */ + +/** + * @typedef {SortKeyItem[]} ServerSideSortingRequestControlValue + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-sorting#section-3.1 + * + * @extends Control + */ +class ServerSideSortingRequestControl extends Control { + static OID = '1.2.840.113556.1.4.473' + + /** + * @typedef {ControlParams} ServerSideSortingRequestParams + * @property {ServerSideSortingRequestControlValue | SortKeyItem | Buffer} [value] + */ + + /** + * Creates a new server side sorting request control. + * + * @param {ServerSideSortingRequestParams} [options] + */ + constructor (options = { value: [] }) { + options.type = ServerSideSortingRequestControl.OID + super(options) + + const inputValue = options.value ?? [] + if (Buffer.isBuffer(inputValue)) { + this.#parse(inputValue) + } else if (Array.isArray(inputValue)) { + for (const obj of inputValue) { + if (isObject(obj) === false) { + throw new Error('Control value must be an object') + } + if (hasOwn(obj, 'attributeType') === false) { + throw new Error('Missing required key: attributeType') + } + } + this.value = inputValue + } else if (isObject(inputValue)) { + if (hasOwn(inputValue, 'attributeType') === false) { + throw new Error('Missing required key: attributeType') + } + this.value = [inputValue] + } else { + throw new TypeError('options.value must be a Buffer, Array or Object') + } + } + + get value () { + return this._value + } + + set value (items) { + if (Buffer.isBuffer(items) === true) return + if (Array.isArray(items) === false) { + this._value = [items] + return + } + this._value = items + } + + #parse (buffer) { + const ber = new BerReader(buffer) + let item + /* istanbul ignore else */ + if (ber.readSequence(0x30)) { + this.value = [] + + while (ber.readSequence(0x30)) { + item = {} + item.attributeType = ber.readString(Ber.OctetString) + /* istanbul ignore else */ + if (ber.peek() === 0x80) { + item.orderingRule = ber.readString(0x80) + } + /* istanbul ignore else */ + if (ber.peek() === 0x81) { + item.reverseOrder = (ber._readTag(0x81) !== 0) + } + this.value.push(item) + } + } + } + + _pojo (obj) { + obj.value = this.value + return obj + } + + _toBer (ber) { + if (this.value.length === 0) { return } + + const writer = new BerWriter() + writer.startSequence(0x30) + for (let i = 0; i < this.value.length; i++) { + const item = this.value[i] + writer.startSequence(0x30) + /* istanbul ignore else */ + if (hasOwn(item, 'attributeType')) { + writer.writeString(item.attributeType, Ber.OctetString) + } + /* istanbul ignore else */ + if (hasOwn(item, 'orderingRule')) { + writer.writeString(item.orderingRule, 0x80) + } + /* istanbul ignore else */ + if (hasOwn(item, 'reverseOrder')) { + writer.writeBoolean(item.reverseOrder, 0x81) + } + writer.endSequence() + } + writer.endSequence() + ber.writeBuffer(writer.buffer, 0x04) + } +} +module.exports = ServerSideSortingRequestControl diff --git a/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-request-control.test.js b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-request-control.test.js new file mode 100644 index 0000000..b45f4cc --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-request-control.test.js @@ -0,0 +1,144 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const SSSRC = require('./server-side-sorting-request-control') +const Control = require('../control') + +tap.test('contructor', t => { + t.test('new no args', async t => { + const control = new SSSRC() + t.ok(control) + t.type(control, SSSRC) + t.type(control, Control) + t.equal(control.type, SSSRC.OID) + t.same(control.value, []) + }) + + t.test('new with args', async t => { + const control = new SSSRC({ + type: '1.2.840.113556.1.4.473', + criticality: true, + value: [{ attributeType: 'foo' }] + }) + t.ok(control) + t.equal(control.type, '1.2.840.113556.1.4.473') + t.ok(control.criticality) + t.same(control.value, [{ attributeType: 'foo' }]) + }) + + t.test('new with object', async t => { + const control = new SSSRC({ + type: '1.2.840.113556.1.4.473', + criticality: true, + value: { attributeType: 'foo' } + }) + t.ok(control) + t.equal(control.type, '1.2.840.113556.1.4.473') + t.ok(control.criticality) + t.same(control.value, [{ attributeType: 'foo' }]) + }) + + t.test('with value buffer', async t => { + const value = new BerWriter() + value.startSequence(0x30) // Open "array" + value.startSequence(0x30) // Start "item" + value.writeString('foo', 0x04) + value.writeString('bar', 0x80) + value.writeBoolean(false, 0x81) + value.endSequence() // End item + value.endSequence() // Close array + + const control = new SSSRC({ value: value.buffer }) + t.same(control.value, [{ + attributeType: 'foo', + orderingRule: 'bar', + reverseOrder: false + }]) + }) + + t.test('throws for bad value', async t => { + t.throws(() => new SSSRC({ value: 42 })) + }) + + t.test('throws for bad object value', async t => { + t.throws(() => new SSSRC({ value: { foo: 'bar' } })) + }) + + t.test('throws for bad array value', async t => { + t.throws(() => new SSSRC({ value: [42] })) + t.throws(() => new SSSRC({ value: [{ foo: 'bar' }] })) + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('adds control value', async t => { + const control = new SSSRC() + t.same(control.pojo, { + type: SSSRC.OID, + criticality: false, + value: [] + }) + }) + + t.test('_pojo', async t => { + const control = new SSSRC() + const obj = control._pojo({ value: 'change_me' }) + t.strictSame(obj, { value: [] }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(SSSRC.OID) + target.writeBoolean(false) // Control.criticality + target.endSequence() + + const control = new SSSRC() + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts full instance BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(SSSRC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence(0x30) // Open "array" + value.startSequence(0x30) // Start "item" + value.writeString('one', 0x04) + value.writeString('one', 0x80) + value.writeBoolean(false, 0x81) + value.endSequence() // End item + value.startSequence(0x30) // Start "item" + value.writeString('two', 0x04) + value.writeString('two', 0x80) + value.writeBoolean(true, 0x81) + value.endSequence() // End item + value.endSequence() // Close array + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new SSSRC({ + value: [ + { attributeType: 'one', orderingRule: 'one', reverseOrder: false }, + { attributeType: 'two', orderingRule: 'two', reverseOrder: true } + ] + }) + const ber = control.toBer() + + t.equal(Buffer.compare(Buffer.from(target.buffer), ber.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-response-control.js b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-response-control.js new file mode 100644 index 0000000..976897c --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-response-control.js @@ -0,0 +1,129 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const Control = require('../control') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const { resultCodes: RESULT_CODES } = require('@ldapjs/protocol') + +const validCodeNames = [ + 'SUCCESS', + 'OPERATIONS_ERROR', + 'TIME_LIMIT_EXCEEDED', + 'STRONGER_AUTH_REQUIRED', + 'ADMIN_LIMIT_EXCEEDED', + 'NO_SUCH_ATTRIBUTE', + 'INAPPROPRIATE_MATCHING', + 'INSUFFICIENT_ACCESS_RIGHTS', + 'BUSY', + 'UNWILLING_TO_PERFORM', + 'OTHER' +] + +const filteredCodes = Object.entries(RESULT_CODES).filter(([k, v]) => validCodeNames.includes(k)) +const VALID_CODES = new Map([ + ...filteredCodes, + ...filteredCodes.map(([k, v]) => { return [v, k] }) +]) + +/** + * @typedef {object} ServerSideSortingResponseControlResult + * @property {number} result + * @property {string} failedAttribute + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-sorting#section-3.2 + * + * @extends Control + */ +class ServerSideSortingResponseControl extends Control { + static OID = '1.2.840.113556.1.4.474' + + /** + * A map of possible response codes. Includes `CODE => VALUE` and + * `VALUE => CODE`. For example, `RESPONSE_CODES.get(0)` returns + * `LDAP_SUCCESS`, and `RESPONSE_CODES.get('LDAP_SUCCESS')` returns `0`. + */ + static RESPONSE_CODES = Object.freeze(VALID_CODES) + + /** + * @typedef {ControlParams} ServerSideSortingResponseParams + * @property {ServerSideSortingResponseControlResult | Buffer} value + */ + + /** + * Creates a new server side sorting response control. + * + * @param {ServerSideSortingResponseParams} [options] + */ + constructor (options = {}) { + options.type = ServerSideSortingResponseControl.OID + options.criticality = false + super(options) + + this.value = {} + + if (hasOwn(options, 'value') === false || !options.value) { + return + } + + const value = options.value + if (Buffer.isBuffer(value)) { + this.#parse(value) + } else if (isObject(value)) { + if (VALID_CODES.has(value.result) === false) { + throw new Error('Invalid result code') + } + if (hasOwn(value, 'failedAttribute') && (typeof value.failedAttribute) !== 'string') { + throw new Error('failedAttribute must be String') + } + + this.value = value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + } + + get value () { + return this._value + } + + set value (obj) { + this._value = Object.assign({}, this._value, obj) + } + + #parse (buffer) { + const ber = new BerReader(buffer) + /* istanbul ignore else */ + if (ber.readSequence(0x30)) { + this._value = {} + this._value.result = ber.readEnumeration() + /* istanbul ignore else */ + if (ber.peek() === 0x80) { + this._value.failedAttribute = ber.readString(0x80) + } + } + } + + _pojo (obj) { + obj.value = this.value + return obj + } + + _toBer (ber) { + if (!this._value || Object.keys(this._value).length === 0) { return } + + const writer = new BerWriter() + writer.startSequence(0x30) + writer.writeEnumeration(this.value.result) + /* istanbul ignore else */ + if (this.value.result !== RESULT_CODES.SUCCESS && this.value.failedAttribute) { + writer.writeString(this.value.failedAttribute, 0x80) + } + writer.endSequence() + ber.writeBuffer(writer.buffer, 0x04) + } +} +module.exports = ServerSideSortingResponseControl diff --git a/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-response-control.test.js b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-response-control.test.js new file mode 100644 index 0000000..2579964 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/server-side-sorting-response-control.test.js @@ -0,0 +1,125 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const SSSRC = require('./server-side-sorting-response-control') +const Control = require('../control') + +tap.test('constructor', t => { + t.test('new no args', async t => { + const control = new SSSRC() + t.ok(control) + t.type(control, SSSRC) + t.type(control, Control) + t.equal(control.type, SSSRC.OID) + t.same(control.value, {}) + }) + + t.test('new with args', async t => { + const control = new SSSRC({ + type: '1.2.840.113556.1.4.474', + criticality: true, + value: { + result: SSSRC.RESPONSE_CODES.get('OPERATIONS_ERROR'), + failedAttribute: 'foo' + } + }) + t.ok(control) + t.equal(control.type, '1.2.840.113556.1.4.474') + t.equal(control.criticality, false) + t.same(control.value, { + result: 1, + failedAttribute: 'foo' + }) + }) + + t.test('with value buffer', async t => { + const value = new BerWriter() + value.startSequence(0x30) + value.writeEnumeration(1) + value.writeString('foo', 0x80) + value.endSequence() + + const control = new SSSRC({ value: value.buffer }) + t.same(control.value, { + result: 1, + failedAttribute: 'foo' + }) + }) + + t.test('throws for bad value', async t => { + t.throws(() => new SSSRC({ value: 42 })) + t.throws(() => new SSSRC({ value: {} })) + t.throws(() => new SSSRC({ + value: { + result: 1, + failedAttribute: 42 + } + })) + }) + + t.end() +}) + +tap.test('pojo', t => { + t.test('adds control value', async t => { + const control = new SSSRC() + t.same(control.pojo, { + type: SSSRC.OID, + criticality: false, + value: {} + }) + }) + + t.test('_pojo', async t => { + const control = new SSSRC() + t.strictSame(control._pojo({ value: 'change_me' }), { + value: {} + }) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts empty instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(SSSRC.OID) + target.writeBoolean(false) // Control.criticality + target.endSequence() + + const control = new SSSRC() + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.test('converts full instance to BER', async t => { + const target = new BerWriter() + target.startSequence() + target.writeString(SSSRC.OID) + target.writeBoolean(false) // Control.criticality + + const value = new BerWriter() + value.startSequence(0x30) + value.writeEnumeration(1) + value.writeString('foo', 0x80) + value.endSequence() + + target.writeBuffer(value.buffer, 0x04) + target.endSequence() + + const control = new SSSRC({ + value: { + result: SSSRC.RESPONSE_CODES.get('OPERATIONS_ERROR'), + failedAttribute: 'foo' + } + }) + const ber = control.toBer() + + t.equal(Buffer.compare(ber.buffer, target.buffer), 0) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-request-control.js b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-request-control.js new file mode 100644 index 0000000..ef7b1f4 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-request-control.js @@ -0,0 +1,116 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') + +/** + * @typedef {object} VirtualListViewControlValue + * @property {number} beforeCount + * @property {number} afterCount + * + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-ldapv3-vlv-07#section-6.1 + * + * @extends Control + */ +class VirtualListViewRequestControl extends Control { + static OID = '2.16.840.1.113730.3.4.9' + + /** + * @typedef {ControlParams} VirtualListViewRequestParams + * @property {Buffer|VirtualListViewControlValue} [value] + */ + + /** + * @param {VirtualListViewRequestParams} [options] + */ + constructor (options = {}) { + options.type = VirtualListViewRequestControl.OID + super(options) + + if (hasOwn(options, 'value') === false) { + // return + throw Error('control is not enabled') + } + + if (Buffer.isBuffer(options.value)) { + this.#parse(options.value) + } else if (isObject(options.value)) { + if (Object.prototype.hasOwnProperty.call(options.value, 'beforeCount') === false) { + throw new Error('Missing required key: beforeCount') + } + if (Object.prototype.hasOwnProperty.call(options.value, 'afterCount') === false) { + throw new Error('Missing required key: afterCount') + } + this._value = options.value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + + throw Error('control is not enabled') + } + + get value () { + return this._value + } + + set value (items) { + if (Buffer.isBuffer(items) === true) return + if (Array.isArray(items) === false) { + this._value = [items] + return + } + this._value = items + } + + #parse (buffer) { + const ber = new BerReader(buffer) + if (ber.readSequence()) { + this._value = {} + this._value.beforeCount = ber.readInt() + this._value.afterCount = ber.readInt() + if (ber.peek() === 0xa0) { + if (ber.readSequence(0xa0)) { + this._value.targetOffset = ber.readInt() + this._value.contentCount = ber.readInt() + } + } + if (ber.peek() === 0x81) { + this._value.greaterThanOrEqual = ber.readString(0x81) + } + return true + } + return false + } + + _pojo (obj) { + obj.value = this.value + return obj + } + + _toBer (ber) { + if (!this._value || this._value.length === 0) { + return + } + const writer = new BerWriter() + writer.startSequence(0x30) + writer.writeInt(this._value.beforeCount) + writer.writeInt(this._value.afterCount) + if (this._value.targetOffset !== undefined) { + writer.startSequence(0xa0) + writer.writeInt(this._value.targetOffset) + writer.writeInt(this._value.contentCount) + writer.endSequence() + } else if (this._value.greaterThanOrEqual !== undefined) { + writer.writeString(this._value.greaterThanOrEqual, 0x81) + } + writer.endSequence() + ber.writeBuffer(writer.buffer, 0x04) + } +} +module.exports = VirtualListViewRequestControl diff --git a/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-request-control.test.js b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-request-control.test.js new file mode 100644 index 0000000..e6df8ec --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-request-control.test.js @@ -0,0 +1,110 @@ +'use strict' + +const tap = require('tap') +tap.test('stubbed', async t => { + t.pass() +}) + +/** + * This test is disabled. The commented code below is directly copied from + * the original test file in the core `node-ldapjs` repo. The actual test + * suite should follow the patterns of the + * server-side-sorting-request-control.test.js test suite. + * + * See https://github.com/ldapjs/node-ldapjs/pull/797#issuecomment-1094132289 + */ + +// 'use strict' + +// const { test } = require('tap') +// const { BerReader, BerWriter } = require('@ldapjs/asn1') +// const { getControl, VirtualListViewRequestControl: VLVRControl } = require('../../lib') + +// test('VLV request - new no args', function (t) { +// t.ok(new VLVRControl()) +// t.end() +// }) + +// test('VLV request - new with args', function (t) { +// const c = new VLVRControl({ +// criticality: true, +// value: { +// beforeCount: 0, +// afterCount: 3, +// targetOffset: 1, +// contentCount: 0 +// } +// }) +// t.ok(c) +// t.equal(c.type, '2.16.840.1.113730.3.4.9') +// t.ok(c.criticality) +// t.equal(c.value.beforeCount, 0) +// t.equal(c.value.afterCount, 3) +// t.equal(c.value.targetOffset, 1) +// t.equal(c.value.contentCount, 0) + +// t.end() +// }) + +// test('VLV request - toBer - with offset', function (t) { +// const vlvc = new VLVRControl({ +// criticality: true, +// value: { +// beforeCount: 0, +// afterCount: 3, +// targetOffset: 1, +// contentCount: 0 +// } +// }) + +// const ber = new BerWriter() +// vlvc.toBer(ber) + +// const c = getControl(new BerReader(ber.buffer)) +// t.ok(c) +// t.equal(c.type, '2.16.840.1.113730.3.4.9') +// t.ok(c.criticality) +// t.equal(c.value.beforeCount, 0) +// t.equal(c.value.afterCount, 3) +// t.equal(c.value.targetOffset, 1) +// t.equal(c.value.contentCount, 0) + +// t.end() +// }) + +// test('VLV request - toBer - with assertion', function (t) { +// const vlvc = new VLVRControl({ +// criticality: true, +// value: { +// beforeCount: 0, +// afterCount: 3, +// greaterThanOrEqual: '*foo*' +// } +// }) + +// const ber = new BerWriter() +// vlvc.toBer(ber) + +// const c = getControl(new BerReader(ber.buffer)) +// t.ok(c) +// t.equal(c.type, '2.16.840.1.113730.3.4.9') +// t.ok(c.criticality) +// t.equal(c.value.beforeCount, 0) +// t.equal(c.value.afterCount, 3) +// t.equal(c.value.greaterThanOrEqual, '*foo*') + +// t.end() +// }) + +// test('VLV request - toBer - empty', function (t) { +// const vlvc = new VLVRControl() +// const ber = new BerWriter() +// vlvc.toBer(ber) + +// const c = getControl(new BerReader(ber.buffer)) +// t.ok(c) +// t.equal(c.type, '2.16.840.1.113730.3.4.9') +// t.equal(c.criticality, false) +// t.notOk(c.value.result) +// t.end() +// }) diff --git a/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-response-control.js b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-response-control.js new file mode 100644 index 0000000..f9b1efe --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-response-control.js @@ -0,0 +1,150 @@ +'use strict' + +const { Ber, BerReader, BerWriter } = require('@ldapjs/asn1') +const isObject = require('../is-object') +const hasOwn = require('../has-own') +const Control = require('../control') +const { resultCodes: RESULT_CODES } = require('@ldapjs/protocol') + +const validCodeNames = [ + 'SUCCESS', + 'OPERATIONS_ERROR', + 'UNWILLING_TO_PERFORM', + 'INSUFFICIENT_ACCESS_RIGHTS', + 'BUSY', + 'TIME_LIMIT_EXCEEDED', + 'STRONGER_AUTH_REQUIRED', + 'ADMIN_LIMIT_EXCEEDED', + 'SORT_CONTROL_MISSING', + 'OFFSET_RANGE_ERROR', + 'CONTROL_ERROR', + 'OTHER' +] + +const filteredCodes = Object.entries(RESULT_CODES).filter(([k, v]) => validCodeNames.includes(k)) +const VALID_CODES = new Map([ + ...filteredCodes, + ...filteredCodes.map(([k, v]) => { return [v, k] }) +]) + +// TODO: complete this doc block based on the "implements" spec link +/** + * @typedef {object} VirtualListViewResponseControlValue + * @property {number} result A valid LDAP response code for the control. + */ + +/** + * Implements: + * https://datatracker.ietf.org/doc/html/draft-ietf-ldapext-ldapv3-vlv-07#section-6.2 + * + * @extends Control + */ +class VirtualListViewResponseControl extends Control { + static OID = '2.16.840.1.113730.3.4.10' + + /** + * A map of possible response codes. Includes `CODE => VALUE` and + * `VALUE => CODE`. For example, `RESPONSE_CODES.get(0)` returns + * `LDAP_SUCCESS`, and `RESPONSE_CODES.get('LDAP_SUCCESS')` returns `0`. + */ + static RESPONSE_CODES = Object.freeze(VALID_CODES) + + /** + * @typedef {ControlParams} VirtualListViewResponseParams + * @property {Buffer|VirtualListViewResponseControlValue} [value] + */ + + /** + * @param {VirtualListViewResponseParams} options + */ + constructor (options = {}) { + options.type = VirtualListViewResponseControl.OID + options.criticality = false + super(options) + + this.value = {} + + if (hasOwn(options, 'value') === false || !options.value) { + // return + throw Error('control not enabled') + } + + const value = options.value + if (Buffer.isBuffer(value)) { + this.#parse(options.value) + } else if (isObject(value)) { + if (VALID_CODES.has(value.result) === false) { + throw new Error('Invalid result code') + } + this.value = options.value + } else { + throw new TypeError('options.value must be a Buffer or Object') + } + + throw Error('control not enabled') + } + + get value () { + return this._value + } + + set value (obj) { + this._value = Object.assign({}, this._value, obj) + } + + #parse (buffer) { + const ber = new BerReader(buffer) + if (ber.readSequence()) { + this._value = {} + + if (ber.peek(0x02)) { + this._value.targetPosition = ber.readInt() + } + + if (ber.peek(0x02)) { + this._value.contentCount = ber.readInt() + } + + this._value.result = ber.readEnumeration() + this._value.cookie = ber.readString(Ber.OctetString, true) + + // readString returns '' instead of a zero-length buffer + if (!this._value.cookie) { + this._value.cookie = Buffer.alloc(0) + } + + return true + } + + return false + } + + _pojo (obj) { + obj.value = this.value + return obj + } + + _toBer (ber) { + if (this.value.length === 0) { return } + + const writer = new BerWriter() + writer.startSequence() + if (this.value.targetPosition !== undefined) { + writer.writeInt(this.value.targetPosition) + } + if (this.value.contentCount !== undefined) { + writer.writeInt(this.value.contentCount) + } + + writer.writeEnumeration(this.value.result) + if (this.value.cookie && this.value.cookie.length > 0) { + writer.writeBuffer(this.value.cookie, Ber.OctetString) + } else { + writer.writeString('') // writeBuffer rejects zero-length buffers + } + + writer.endSequence() + ber.writeBuffer(writer.buffer, 0x04) + } +} +module.exports = VirtualListViewResponseControl diff --git a/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-response-control.test.js b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-response-control.test.js new file mode 100644 index 0000000..046e77f --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/controls/virtual-list-view-response-control.test.js @@ -0,0 +1,84 @@ +'use strict' + +const tap = require('tap') +tap.test('stubbed', async t => { + t.pass() +}) + +/** + * This test is disabled. The commented code below is directly copied from + * the original test file in the core `node-ldapjs` repo. The actual test + * suite should follow the patterns of the + * server-side-sorting-response-control.test.js test suite. + * + * See https://github.com/ldapjs/node-ldapjs/pull/797#issuecomment-1094132289 + */ + +// 'use strict' + +// const { test } = require('tap') +// const { BerReader, BerWriter } = require('@ldapjs/asn1') +// const ldap = require('../../lib') +// const { getControl, VirtualListViewResponseControl: VLVResponseControl } = require('../../lib') +// const OID = '2.16.840.1.113730.3.4.10' + +// test('VLV response - new no args', function (t) { +// const c = new VLVResponseControl() +// t.ok(c) +// t.equal(c.type, OID) +// t.equal(c.criticality, false) +// t.end() +// }) + +// test('VLV response - new with args', function (t) { +// const c = new VLVResponseControl({ +// criticality: true, +// value: { +// result: ldap.LDAP_SUCCESS, +// targetPosition: 0, +// contentCount: 10 +// } +// }) +// t.ok(c) +// t.equal(c.type, OID) +// t.equal(c.criticality, false) +// t.equal(c.value.result, ldap.LDAP_SUCCESS) +// t.equal(c.value.targetPosition, 0) +// t.equal(c.value.contentCount, 10) +// t.end() +// }) + +// test('VLV response - toBer', function (t) { +// const vlpc = new VLVResponseControl({ +// value: { +// targetPosition: 0, +// contentCount: 10, +// result: ldap.LDAP_SUCCESS +// } +// }) + +// const ber = new BerWriter() +// vlpc.toBer(ber) + +// const c = getControl(new BerReader(ber.buffer)) +// t.ok(c) +// t.equal(c.type, OID) +// t.equal(c.criticality, false) +// t.equal(c.value.result, ldap.LDAP_SUCCESS) +// t.equal(c.value.targetPosition, 0) +// t.equal(c.value.contentCount, 10) +// t.end() +// }) + +// test('VLV response - toBer - empty', function (t) { +// const vlpc = new VLVResponseControl() +// const ber = new BerWriter() +// vlpc.toBer(ber) + +// const c = getControl(new BerReader(ber.buffer)) +// t.ok(c) +// t.equal(c.type, OID) +// t.equal(c.criticality, false) +// t.notOk(c.value.result) +// t.end() +// }) diff --git a/node_modules/@ldapjs/controls/lib/has-own.js b/node_modules/@ldapjs/controls/lib/has-own.js new file mode 100644 index 0000000..e2feef6 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/has-own.js @@ -0,0 +1,5 @@ +'use strict' + +module.exports = function hasOwn (obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop) +} diff --git a/node_modules/@ldapjs/controls/lib/is-object.js b/node_modules/@ldapjs/controls/lib/is-object.js new file mode 100644 index 0000000..c0f5e75 --- /dev/null +++ b/node_modules/@ldapjs/controls/lib/is-object.js @@ -0,0 +1,5 @@ +'use strict' + +module.exports = function isObject (input) { + return Object.prototype.toString.call(input) === '[object Object]' +} diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/.github/workflows/main.yml b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/.taprc.yml b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/.taprc.yml new file mode 100644 index 0000000..6054aa4 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/.taprc.yml @@ -0,0 +1,4 @@ +check-coverage: false + +files: + - 'lib/**/*.test.js' diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/LICENSE b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/LICENSE new file mode 100644 index 0000000..1913201 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2011 Mark Cavage, All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/README.md b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/README.md new file mode 100644 index 0000000..2ec01a3 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/README.md @@ -0,0 +1,39 @@ +# `@ldapjs/asn1` + +`@ldapjs/asn1` is a library for encoding and decoding ASN.1 datatypes in pure +JS. Currently BER encoding is supported. + +### Decoding + +The following reads an ASN.1 sequence with a boolean. + + var Ber = require('@ldapjs/asn1').Ber; + + var reader = new Ber.Reader(Buffer.from([0x30, 0x03, 0x01, 0x01, 0xff])); + + reader.readSequence(); + console.log('Sequence len: ' + reader.length); + if (reader.peek() === Ber.Boolean) + console.log(reader.readBoolean()); + +### Encoding + +The following generates the same payload as above. + + var Ber = require('@ldapjs/asn1').Ber; + + var writer = new Ber.Writer(); + + writer.startSequence(); + writer.writeBoolean(true); + writer.endSequence(); + + console.log(writer.buffer); + +## Installation + + npm install asn1 + +## Bugs + +See . diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/errors.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/errors.js new file mode 100644 index 0000000..f08f259 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/errors.js @@ -0,0 +1,12 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +module.exports = { + + newInvalidAsn1Error: function (msg) { + const e = new Error() + e.name = 'InvalidAsn1Error' + e.message = msg || '' + return e + } + +} diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/index.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/index.js new file mode 100644 index 0000000..f9c6f31 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/index.js @@ -0,0 +1,24 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +const errors = require('./errors') +const types = require('./types') + +const Reader = require('./reader') +const Writer = require('./writer') + +// --- Exports + +module.exports = { + + Reader: Reader, + + Writer: Writer + +} + +for (const t in types) { + if (Object.prototype.hasOwnProperty.call(types, t)) { module.exports[t] = types[t] } +} +for (const e in errors) { + if (Object.prototype.hasOwnProperty.call(errors, e)) { module.exports[e] = errors[e] } +} diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/reader.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/reader.js new file mode 100644 index 0000000..80d4eb3 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/reader.js @@ -0,0 +1,227 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +const assert = require('assert') +const ASN1 = require('./types') +const errors = require('./errors') + +// --- Globals + +const newInvalidAsn1Error = errors.newInvalidAsn1Error + +// --- API + +function Reader (data) { + if (!data || !Buffer.isBuffer(data)) { throw new TypeError('data must be a node Buffer') } + + this._buf = data + this._size = data.length + + // These hold the "current" state + this._len = 0 + this._offset = 0 +} + +Object.defineProperty(Reader.prototype, Symbol.toStringTag, { value: 'BerReader' }) + +Object.defineProperty(Reader.prototype, 'length', { + enumerable: true, + get: function () { return (this._len) } +}) + +Object.defineProperty(Reader.prototype, 'offset', { + enumerable: true, + get: function () { return (this._offset) } +}) + +Object.defineProperty(Reader.prototype, 'remain', { + get: function () { return (this._size - this._offset) } +}) + +Object.defineProperty(Reader.prototype, 'buffer', { + get: function () { return (this._buf.slice(this._offset)) } +}) + +/** + * Reads a single byte and advances offset; you can pass in `true` to make this + * a "peek" operation (i.e., get the byte, but don't advance the offset). + * + * @param {Boolean} peek true means don't move offset. + * @return {Number} the next byte, null if not enough data. + */ +Reader.prototype.readByte = function (peek) { + if (this._size - this._offset < 1) { return null } + + const b = this._buf[this._offset] & 0xff + + if (!peek) { this._offset += 1 } + + return b +} + +Reader.prototype.peek = function () { + return this.readByte(true) +} + +/** + * Reads a (potentially) variable length off the BER buffer. This call is + * not really meant to be called directly, as callers have to manipulate + * the internal buffer afterwards. + * + * As a result of this call, you can call `Reader.length`, until the + * next thing called that does a readLength. + * + * @return {Number} the amount of offset to advance the buffer. + * @throws {InvalidAsn1Error} on bad ASN.1 + */ +Reader.prototype.readLength = function (offset) { + if (offset === undefined) { offset = this._offset } + + if (offset >= this._size) { return null } + + let lenB = this._buf[offset++] & 0xff + if (lenB === null) { return null } + + if ((lenB & 0x80) === 0x80) { + lenB &= 0x7f + + if (lenB === 0) { throw newInvalidAsn1Error('Indefinite length not supported') } + + if (lenB > 4) { throw newInvalidAsn1Error('encoding too long') } + + if (this._size - offset < lenB) { return null } + + this._len = 0 + for (let i = 0; i < lenB; i++) { this._len = (this._len << 8) + (this._buf[offset++] & 0xff) } + } else { + // Wasn't a variable length + this._len = lenB + } + + return offset +} + +/** + * Parses the next sequence in this BER buffer. + * + * To get the length of the sequence, call `Reader.length`. + * + * @return {Number} the sequence's tag. + */ +Reader.prototype.readSequence = function (tag) { + const seq = this.peek() + if (seq === null) { return null } + if (tag !== undefined && tag !== seq) { + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + seq.toString(16)) + } + + const o = this.readLength(this._offset + 1) // stored in `length` + if (o === null) { return null } + + this._offset = o + return seq +} + +Reader.prototype.readInt = function () { + return this._readTag(ASN1.Integer) +} + +Reader.prototype.readBoolean = function (tag) { + return (this._readTag(tag || ASN1.Boolean) !== 0) +} + +Reader.prototype.readEnumeration = function () { + return this._readTag(ASN1.Enumeration) +} + +Reader.prototype.readString = function (tag, retbuf) { + if (!tag) { tag = ASN1.OctetString } + + const b = this.peek() + if (b === null) { return null } + + if (b !== tag) { + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)) + } + + const o = this.readLength(this._offset + 1) // stored in `length` + + if (o === null) { return null } + + if (this.length > this._size - o) { return null } + + this._offset = o + + if (this.length === 0) { return retbuf ? Buffer.alloc(0) : '' } + + const str = this._buf.slice(this._offset, this._offset + this.length) + this._offset += this.length + + return retbuf ? str : str.toString('utf8') +} + +Reader.prototype.readOID = function (tag) { + if (!tag) { tag = ASN1.OID } + + const b = this.readString(tag, true) + if (b === null) { return null } + + const values = [] + let value = 0 + + for (let i = 0; i < b.length; i++) { + const byte = b[i] & 0xff + + value <<= 7 + value += byte & 0x7f + if ((byte & 0x80) === 0) { + values.push(value) + value = 0 + } + } + + value = values.shift() + values.unshift(value % 40) + values.unshift((value / 40) >> 0) + + return values.join('.') +} + +Reader.prototype._readTag = function (tag) { + assert.ok(tag !== undefined) + + const b = this.peek() + + if (b === null) { return null } + + if (b !== tag) { + throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) + + ': got 0x' + b.toString(16)) + } + + const o = this.readLength(this._offset + 1) // stored in `length` + if (o === null) { return null } + + if (this.length > 4) { throw newInvalidAsn1Error('Integer too long: ' + this.length) } + + if (this.length > this._size - o) { return null } + this._offset = o + + const fb = this._buf[this._offset] + let value = 0 + + let i + for (i = 0; i < this.length; i++) { + value <<= 8 + value |= (this._buf[this._offset++] & 0xff) + } + + if ((fb & 0x80) === 0x80 && i !== 4) { value -= (1 << (i * 8)) } + + return value >> 0 +} + +// --- Exported API + +module.exports = Reader diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/reader.test.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/reader.test.js new file mode 100644 index 0000000..1d94775 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/reader.test.js @@ -0,0 +1,182 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +const { test } = require('tap') +const BerReader = require('./reader') + +test('load library', function (t) { + t.ok(BerReader) + try { + const reader = new BerReader() + t.equal(reader, null, 'reader') + t.fail('Should have thrown') + } catch (e) { + t.ok(e instanceof TypeError, 'Should have been a type error') + } + t.end() +}) + +test('read byte', function (t) { + const reader = new BerReader(Buffer.from([0xde])) + t.ok(reader) + t.equal(reader.readByte(), 0xde, 'wrong value') + t.end() +}) + +test('read 1 byte int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x01, 0x03])) + t.ok(reader) + t.equal(reader.readInt(), 0x03, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + t.end() +}) + +test('read 2 byte int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x02, 0x7e, 0xde])) + t.ok(reader) + t.equal(reader.readInt(), 0x7ede, 'wrong value') + t.equal(reader.length, 0x02, 'wrong length') + t.end() +}) + +test('read 3 byte int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x03, 0x7e, 0xde, 0x03])) + t.ok(reader) + t.equal(reader.readInt(), 0x7ede03, 'wrong value') + t.equal(reader.length, 0x03, 'wrong length') + t.end() +}) + +test('read 4 byte int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x04, 0x7e, 0xde, 0x03, 0x01])) + t.ok(reader) + t.equal(reader.readInt(), 0x7ede0301, 'wrong value') + t.equal(reader.length, 0x04, 'wrong length') + t.end() +}) + +test('read 1 byte negative int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x01, 0xdc])) + t.ok(reader) + t.equal(reader.readInt(), -36, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + t.end() +}) + +test('read 2 byte negative int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x02, 0xc0, 0x4e])) + t.ok(reader) + t.equal(reader.readInt(), -16306, 'wrong value') + t.equal(reader.length, 0x02, 'wrong length') + t.end() +}) + +test('read 3 byte negative int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x03, 0xff, 0x00, 0x19])) + t.ok(reader) + t.equal(reader.readInt(), -65511, 'wrong value') + t.equal(reader.length, 0x03, 'wrong length') + t.end() +}) + +test('read 4 byte negative int', function (t) { + const reader = new BerReader(Buffer.from([0x02, 0x04, 0x91, 0x7c, 0x22, 0x1f])) + t.ok(reader) + t.equal(reader.readInt(), -1854135777, 'wrong value') + t.equal(reader.length, 0x04, 'wrong length') + t.end() +}) + +test('read boolean true', function (t) { + const reader = new BerReader(Buffer.from([0x01, 0x01, 0xff])) + t.ok(reader) + t.equal(reader.readBoolean(), true, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + t.end() +}) + +test('read boolean false', function (t) { + const reader = new BerReader(Buffer.from([0x01, 0x01, 0x00])) + t.ok(reader) + t.equal(reader.readBoolean(), false, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + t.end() +}) + +test('read enumeration', function (t) { + const reader = new BerReader(Buffer.from([0x0a, 0x01, 0x20])) + t.ok(reader) + t.equal(reader.readEnumeration(), 0x20, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + t.end() +}) + +test('read string', function (t) { + const dn = 'cn=foo,ou=unit,o=test' + const buf = Buffer.alloc(dn.length + 2) + buf[0] = 0x04 + buf[1] = Buffer.byteLength(dn) + buf.write(dn, 2) + const reader = new BerReader(buf) + t.ok(reader) + t.equal(reader.readString(), dn, 'wrong value') + t.equal(reader.length, dn.length, 'wrong length') + t.end() +}) + +test('read sequence', function (t) { + const reader = new BerReader(Buffer.from([0x30, 0x03, 0x01, 0x01, 0xff])) + t.ok(reader) + t.equal(reader.readSequence(), 0x30, 'wrong value') + t.equal(reader.length, 0x03, 'wrong length') + t.equal(reader.readBoolean(), true, 'wrong value') + t.equal(reader.length, 0x01, 'wrong length') + t.end() +}) + +test('anonymous LDAPv3 bind', function (t) { + const BIND = Buffer.alloc(14) + BIND[0] = 0x30 // Sequence + BIND[1] = 12 // len + BIND[2] = 0x02 // ASN.1 Integer + BIND[3] = 1 // len + BIND[4] = 0x04 // msgid (make up 4) + BIND[5] = 0x60 // Bind Request + BIND[6] = 7 // len + BIND[7] = 0x02 // ASN.1 Integer + BIND[8] = 1 // len + BIND[9] = 0x03 // v3 + BIND[10] = 0x04 // String (bind dn) + BIND[11] = 0 // len + BIND[12] = 0x80 // ContextSpecific (choice) + BIND[13] = 0 // simple bind + + // Start testing ^^ + const ber = new BerReader(BIND) + t.equal(ber.readSequence(), 48, 'Not an ASN.1 Sequence') + t.equal(ber.length, 12, 'Message length should be 12') + t.equal(ber.readInt(), 4, 'Message id should have been 4') + t.equal(ber.readSequence(), 96, 'Bind Request should have been 96') + t.equal(ber.length, 7, 'Bind length should have been 7') + t.equal(ber.readInt(), 3, 'LDAP version should have been 3') + t.equal(ber.readString(), '', 'Bind DN should have been empty') + t.equal(ber.length, 0, 'string length should have been 0') + t.equal(ber.readByte(), 0x80, 'Should have been ContextSpecific (choice)') + t.equal(ber.readByte(), 0, 'Should have been simple bind') + t.equal(null, ber.readByte(), 'Should be out of data') + t.end() +}) + +test('long string', function (t) { + const buf = Buffer.alloc(256) + const s = + '2;649;CN=Red Hat CS 71GA Demo,O=Red Hat CS 71GA Demo,C=US;' + + 'CN=RHCS Agent - admin01,UID=admin01,O=redhat,C=US [1] This is ' + + 'Teena Vradmin\'s description.' + buf[0] = 0x04 + buf[1] = 0x81 + buf[2] = 0x94 + buf.write(s, 3) + const ber = new BerReader(buf.slice(0, 3 + s.length)) + t.equal(ber.readString(), s) + t.end() +}) diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/types.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/types.js new file mode 100644 index 0000000..d4d094e --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/types.js @@ -0,0 +1,35 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +module.exports = { + EOC: 0, + Boolean: 1, + Integer: 2, + BitString: 3, + OctetString: 4, + Null: 5, + OID: 6, + ObjectDescriptor: 7, + External: 8, + Real: 9, // float + Enumeration: 10, + PDV: 11, + Utf8String: 12, + RelativeOID: 13, + Sequence: 16, + Set: 17, + NumericString: 18, + PrintableString: 19, + T61String: 20, + VideotexString: 21, + IA5String: 22, + UTCTime: 23, + GeneralizedTime: 24, + GraphicString: 25, + VisibleString: 26, + GeneralString: 28, + UniversalString: 29, + CharacterString: 30, + BMPString: 31, + Constructor: 32, + Context: 128 +} diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/writer.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/writer.js new file mode 100644 index 0000000..afc056a --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/writer.js @@ -0,0 +1,298 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +const assert = require('assert') +const ASN1 = require('./types') +const errors = require('./errors') + +// --- Globals + +const newInvalidAsn1Error = errors.newInvalidAsn1Error + +const DEFAULT_OPTS = { + size: 1024, + growthFactor: 8 +} + +// --- Helpers + +function merge (from, to) { + assert.ok(from) + assert.equal(typeof (from), 'object') + assert.ok(to) + assert.equal(typeof (to), 'object') + + const keys = Object.getOwnPropertyNames(from) + keys.forEach(function (key) { + if (to[key]) { return } + + const value = Object.getOwnPropertyDescriptor(from, key) + Object.defineProperty(to, key, value) + }) + + return to +} + +// --- API + +function Writer (options) { + options = merge(DEFAULT_OPTS, options || {}) + + this._buf = Buffer.alloc(options.size || 1024) + this._size = this._buf.length + this._offset = 0 + this._options = options + + // A list of offsets in the buffer where we need to insert + // sequence tag/len pairs. + this._seq = [] +} + +Object.defineProperty(Writer.prototype, Symbol.toStringTag, { value: 'BerWriter' }) + +Object.defineProperty(Writer.prototype, 'buffer', { + get: function () { + if (this._seq.length) { throw newInvalidAsn1Error(this._seq.length + ' unended sequence(s)') } + + return (this._buf.slice(0, this._offset)) + } +}) + +/** + * Append a raw buffer to the current writer instance. No validation to + * determine if the buffer represents a valid BER encoding is performed. + * + * @param {Buffer} buffer The buffer to append. If this is not a valid BER + * sequence of data, it will invalidate the BER represented by the `BerWriter`. + * + * @throws If the input is not an instance of Buffer. + */ +Writer.prototype.appendBuffer = function appendBuffer (buffer) { + if (Buffer.isBuffer(buffer) === false) { + throw Error('buffer must be an instance of Buffer') + } + for (const b of buffer.values()) { + this.writeByte(b) + } +} + +Writer.prototype.writeByte = function (b) { + if (typeof (b) !== 'number') { throw new TypeError('argument must be a Number') } + + this._ensure(1) + this._buf[this._offset++] = b +} + +Writer.prototype.writeInt = function (i, tag) { + if (typeof (i) !== 'number') { throw new TypeError('argument must be a Number') } + if (typeof (tag) !== 'number') { tag = ASN1.Integer } + + let sz = 4 + + while ((((i & 0xff800000) === 0) || ((i & 0xff800000) === 0xff800000 >> 0)) && + (sz > 1)) { + sz-- + i <<= 8 + } + + if (sz > 4) { throw newInvalidAsn1Error('BER ints cannot be > 0xffffffff') } + + this._ensure(2 + sz) + this._buf[this._offset++] = tag + this._buf[this._offset++] = sz + + while (sz-- > 0) { + this._buf[this._offset++] = ((i & 0xff000000) >>> 24) + i <<= 8 + } +} + +Writer.prototype.writeNull = function () { + this.writeByte(ASN1.Null) + this.writeByte(0x00) +} + +Writer.prototype.writeEnumeration = function (i, tag) { + if (typeof (i) !== 'number') { throw new TypeError('argument must be a Number') } + if (typeof (tag) !== 'number') { tag = ASN1.Enumeration } + + return this.writeInt(i, tag) +} + +Writer.prototype.writeBoolean = function (b, tag) { + if (typeof (b) !== 'boolean') { throw new TypeError('argument must be a Boolean') } + if (typeof (tag) !== 'number') { tag = ASN1.Boolean } + + this._ensure(3) + this._buf[this._offset++] = tag + this._buf[this._offset++] = 0x01 + this._buf[this._offset++] = b ? 0xff : 0x00 +} + +Writer.prototype.writeString = function (s, tag) { + if (typeof (s) !== 'string') { throw new TypeError('argument must be a string (was: ' + typeof (s) + ')') } + if (typeof (tag) !== 'number') { tag = ASN1.OctetString } + + const len = Buffer.byteLength(s) + this.writeByte(tag) + this.writeLength(len) + if (len) { + this._ensure(len) + this._buf.write(s, this._offset) + this._offset += len + } +} + +Writer.prototype.writeBuffer = function (buf, tag) { + if (typeof (tag) !== 'number') { throw new TypeError('tag must be a number') } + if (!Buffer.isBuffer(buf)) { throw new TypeError('argument must be a buffer') } + + this.writeByte(tag) + this.writeLength(buf.length) + this._ensure(buf.length) + buf.copy(this._buf, this._offset, 0, buf.length) + this._offset += buf.length +} + +Writer.prototype.writeStringArray = function (strings) { + if (Array.isArray(strings) === false) { throw new TypeError('argument must be an Array[String]') } + + const self = this + strings.forEach(function (s) { + self.writeString(s) + }) +} + +// This is really to solve DER cases, but whatever for now +Writer.prototype.writeOID = function (s, tag) { + if (typeof (s) !== 'string') { throw new TypeError('argument must be a string') } + if (typeof (tag) !== 'number') { tag = ASN1.OID } + + if (!/^([0-9]+\.){3,}[0-9]+$/.test(s)) { throw new Error('argument is not a valid OID string') } + + function encodeOctet (bytes, octet) { + if (octet < 128) { + bytes.push(octet) + } else if (octet < 16384) { + bytes.push((octet >>> 7) | 0x80) + bytes.push(octet & 0x7F) + } else if (octet < 2097152) { + bytes.push((octet >>> 14) | 0x80) + bytes.push(((octet >>> 7) | 0x80) & 0xFF) + bytes.push(octet & 0x7F) + } else if (octet < 268435456) { + bytes.push((octet >>> 21) | 0x80) + bytes.push(((octet >>> 14) | 0x80) & 0xFF) + bytes.push(((octet >>> 7) | 0x80) & 0xFF) + bytes.push(octet & 0x7F) + } else { + bytes.push(((octet >>> 28) | 0x80) & 0xFF) + bytes.push(((octet >>> 21) | 0x80) & 0xFF) + bytes.push(((octet >>> 14) | 0x80) & 0xFF) + bytes.push(((octet >>> 7) | 0x80) & 0xFF) + bytes.push(octet & 0x7F) + } + } + + const tmp = s.split('.') + const bytes = [] + bytes.push(parseInt(tmp[0], 10) * 40 + parseInt(tmp[1], 10)) + tmp.slice(2).forEach(function (b) { + encodeOctet(bytes, parseInt(b, 10)) + }) + + const self = this + this._ensure(2 + bytes.length) + this.writeByte(tag) + this.writeLength(bytes.length) + bytes.forEach(function (b) { + self.writeByte(b) + }) +} + +Writer.prototype.writeLength = function (len) { + if (typeof (len) !== 'number') { throw new TypeError('argument must be a Number') } + + this._ensure(4) + + if (len <= 0x7f) { + this._buf[this._offset++] = len + } else if (len <= 0xff) { + this._buf[this._offset++] = 0x81 + this._buf[this._offset++] = len + } else if (len <= 0xffff) { + this._buf[this._offset++] = 0x82 + this._buf[this._offset++] = len >> 8 + this._buf[this._offset++] = len + } else if (len <= 0xffffff) { + this._buf[this._offset++] = 0x83 + this._buf[this._offset++] = len >> 16 + this._buf[this._offset++] = len >> 8 + this._buf[this._offset++] = len + } else { + throw newInvalidAsn1Error('Length too long (> 4 bytes)') + } +} + +Writer.prototype.startSequence = function (tag) { + if (typeof (tag) !== 'number') { tag = ASN1.Sequence | ASN1.Constructor } + + this.writeByte(tag) + this._seq.push(this._offset) + this._ensure(3) + this._offset += 3 +} + +Writer.prototype.endSequence = function () { + const seq = this._seq.pop() + const start = seq + 3 + const len = this._offset - start + + if (len <= 0x7f) { + this._shift(start, len, -2) + this._buf[seq] = len + } else if (len <= 0xff) { + this._shift(start, len, -1) + this._buf[seq] = 0x81 + this._buf[seq + 1] = len + } else if (len <= 0xffff) { + this._buf[seq] = 0x82 + this._buf[seq + 1] = len >> 8 + this._buf[seq + 2] = len + } else if (len <= 0xffffff) { + this._shift(start, len, 1) + this._buf[seq] = 0x83 + this._buf[seq + 1] = len >> 16 + this._buf[seq + 2] = len >> 8 + this._buf[seq + 3] = len + } else { + throw newInvalidAsn1Error('Sequence too long') + } +} + +Writer.prototype._shift = function (start, len, shift) { + assert.ok(start !== undefined) + assert.ok(len !== undefined) + assert.ok(shift) + + this._buf.copy(this._buf, start + shift, start, start + len) + this._offset += shift +} + +Writer.prototype._ensure = function (len) { + assert.ok(len) + + if (this._size - this._offset < len) { + let sz = this._size * this._options.growthFactor + if (sz - this._offset < len) { sz += len } + + const buf = Buffer.alloc(sz) + + this._buf.copy(buf, 0, 0, this._offset) + this._buf = buf + this._size = sz + } +} + +// --- Exported API + +module.exports = Writer diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/writer.test.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/writer.test.js new file mode 100644 index 0000000..e6f3fc0 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/ber/writer.test.js @@ -0,0 +1,344 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +const { test } = require('tap') +const BerWriter = require('./writer') + +test('write byte', function (t) { + const writer = new BerWriter() + + writer.writeByte(0xC2) + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 1, 'Wrong length') + t.equal(ber[0], 0xC2, 'value wrong') + + t.end() +}) + +test('write 1 byte int', function (t) { + const writer = new BerWriter() + + writer.writeInt(0x7f) + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 3, 'Wrong length for an int: ' + ber.length) + t.equal(ber[0], 0x02, 'ASN.1 tag wrong (2) -> ' + ber[0]) + t.equal(ber[1], 0x01, 'length wrong(1) -> ' + ber[1]) + t.equal(ber[2], 0x7f, 'value wrong(3) -> ' + ber[2]) + + t.end() +}) + +test('write 2 byte int', function (t) { + const writer = new BerWriter() + + writer.writeInt(0x7ffe) + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 4, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x02, 'length wrong') + t.equal(ber[2], 0x7f, 'value wrong (byte 1)') + t.equal(ber[3], 0xfe, 'value wrong (byte 2)') + + t.end() +}) + +test('write 3 byte int', function (t) { + const writer = new BerWriter() + + writer.writeInt(0x7ffffe) + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 5, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x03, 'length wrong') + t.equal(ber[2], 0x7f, 'value wrong (byte 1)') + t.equal(ber[3], 0xff, 'value wrong (byte 2)') + t.equal(ber[4], 0xfe, 'value wrong (byte 3)') + + t.end() +}) + +test('write 4 byte int', function (t) { + const writer = new BerWriter() + + writer.writeInt(0x7ffffffe) + const ber = writer.buffer + + t.ok(ber) + + t.equal(ber.length, 6, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x04, 'length wrong') + t.equal(ber[2], 0x7f, 'value wrong (byte 1)') + t.equal(ber[3], 0xff, 'value wrong (byte 2)') + t.equal(ber[4], 0xff, 'value wrong (byte 3)') + t.equal(ber[5], 0xfe, 'value wrong (byte 4)') + + t.end() +}) + +test('write 1 byte negative int', function (t) { + const writer = new BerWriter() + + writer.writeInt(-128) + const ber = writer.buffer + + t.ok(ber) + + t.equal(ber.length, 3, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x01, 'length wrong') + t.equal(ber[2], 0x80, 'value wrong (byte 1)') + + t.end() +}) + +test('write 2 byte negative int', function (t) { + const writer = new BerWriter() + + writer.writeInt(-22400) + const ber = writer.buffer + + t.ok(ber) + + t.equal(ber.length, 4, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x02, 'length wrong') + t.equal(ber[2], 0xa8, 'value wrong (byte 1)') + t.equal(ber[3], 0x80, 'value wrong (byte 2)') + + t.end() +}) + +test('write 3 byte negative int', function (t) { + const writer = new BerWriter() + + writer.writeInt(-481653) + const ber = writer.buffer + + t.ok(ber) + + t.equal(ber.length, 5, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x03, 'length wrong') + t.equal(ber[2], 0xf8, 'value wrong (byte 1)') + t.equal(ber[3], 0xa6, 'value wrong (byte 2)') + t.equal(ber[4], 0x8b, 'value wrong (byte 3)') + + t.end() +}) + +test('write 4 byte negative int', function (t) { + const writer = new BerWriter() + + writer.writeInt(-1522904131) + const ber = writer.buffer + + t.ok(ber) + + t.equal(ber.length, 6, 'Wrong length for an int') + t.equal(ber[0], 0x02, 'ASN.1 tag wrong') + t.equal(ber[1], 0x04, 'length wrong') + t.equal(ber[2], 0xa5, 'value wrong (byte 1)') + t.equal(ber[3], 0x3a, 'value wrong (byte 2)') + t.equal(ber[4], 0x53, 'value wrong (byte 3)') + t.equal(ber[5], 0xbd, 'value wrong (byte 4)') + + t.end() +}) + +test('write boolean', function (t) { + const writer = new BerWriter() + + writer.writeBoolean(true) + writer.writeBoolean(false) + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 6, 'Wrong length') + t.equal(ber[0], 0x01, 'tag wrong') + t.equal(ber[1], 0x01, 'length wrong') + t.equal(ber[2], 0xff, 'value wrong') + t.equal(ber[3], 0x01, 'tag wrong') + t.equal(ber[4], 0x01, 'length wrong') + t.equal(ber[5], 0x00, 'value wrong') + + t.end() +}) + +test('write string', function (t) { + const writer = new BerWriter() + writer.writeString('hello world') + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 13, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.slice(2).toString('utf8'), 'hello world', 'wrong value') + + t.end() +}) + +test('write buffer', function (t) { + const writer = new BerWriter() + // write some stuff to start with + writer.writeString('hello world') + let ber = writer.buffer + const buf = Buffer.from([0x04, 0x0b, 0x30, 0x09, 0x02, 0x01, 0x0f, 0x01, 0x01, + 0xff, 0x01, 0x01, 0xff]) + writer.writeBuffer(buf.slice(2, buf.length), 0x04) + ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 26, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value') + t.equal(ber[13], buf[0], 'wrong tag') + t.equal(ber[14], buf[1], 'wrong length') + for (let i = 13, j = 0; i < ber.length && j < buf.length; i++, j++) { + t.equal(ber[i], buf[j], 'buffer contents not identical') + } + t.end() +}) + +test('write string array', function (t) { + const writer = new BerWriter() + writer.writeStringArray(['hello world', 'fubar!']) + const ber = writer.buffer + + t.ok(ber) + + t.equal(ber.length, 21, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.slice(2, 13).toString('utf8'), 'hello world', 'wrong value') + + t.equal(ber[13], 0x04, 'wrong tag') + t.equal(ber[14], 6, 'wrong length') + t.equal(ber.slice(15).toString('utf8'), 'fubar!', 'wrong value') + + t.end() +}) + +test('resize internal buffer', function (t) { + const writer = new BerWriter({ size: 2 }) + writer.writeString('hello world') + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 13, 'wrong length') + t.equal(ber[0], 0x04, 'wrong tag') + t.equal(ber[1], 11, 'wrong length') + t.equal(ber.slice(2).toString('utf8'), 'hello world', 'wrong value') + + t.end() +}) + +test('sequence', function (t) { + const writer = new BerWriter({ size: 25 }) + writer.startSequence() + writer.writeString('hello world') + writer.endSequence() + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 15, 'wrong length') + t.equal(ber[0], 0x30, 'wrong tag') + t.equal(ber[1], 13, 'wrong length') + t.equal(ber[2], 0x04, 'wrong tag') + t.equal(ber[3], 11, 'wrong length') + t.equal(ber.slice(4).toString('utf8'), 'hello world', 'wrong value') + + t.end() +}) + +test('nested sequence', function (t) { + const writer = new BerWriter({ size: 25 }) + writer.startSequence() + writer.writeString('hello world') + writer.startSequence() + writer.writeString('hello world') + writer.endSequence() + writer.endSequence() + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 30, 'wrong length') + t.equal(ber[0], 0x30, 'wrong tag') + t.equal(ber[1], 28, 'wrong length') + t.equal(ber[2], 0x04, 'wrong tag') + t.equal(ber[3], 11, 'wrong length') + t.equal(ber.slice(4, 15).toString('utf8'), 'hello world', 'wrong value') + t.equal(ber[15], 0x30, 'wrong tag') + t.equal(ber[16], 13, 'wrong length') + t.equal(ber[17], 0x04, 'wrong tag') + t.equal(ber[18], 11, 'wrong length') + t.equal(ber.slice(19, 30).toString('utf8'), 'hello world', 'wrong value') + + t.end() +}) + +test('LDAP bind message', function (t) { + const dn = 'cn=foo,ou=unit,o=test' + const writer = new BerWriter() + writer.startSequence() + writer.writeInt(3) // msgid = 3 + writer.startSequence(0x60) // ldap bind + writer.writeInt(3) // ldap v3 + writer.writeString(dn) + writer.writeByte(0x80) + writer.writeByte(0x00) + writer.endSequence() + writer.endSequence() + const ber = writer.buffer + + t.ok(ber) + t.equal(ber.length, 35, 'wrong length (buffer)') + t.equal(ber[0], 0x30, 'wrong tag') + t.equal(ber[1], 33, 'wrong length') + t.equal(ber[2], 0x02, 'wrong tag') + t.equal(ber[3], 1, 'wrong length') + t.equal(ber[4], 0x03, 'wrong value') + t.equal(ber[5], 0x60, 'wrong tag') + t.equal(ber[6], 28, 'wrong length') + t.equal(ber[7], 0x02, 'wrong tag') + t.equal(ber[8], 1, 'wrong length') + t.equal(ber[9], 0x03, 'wrong value') + t.equal(ber[10], 0x04, 'wrong tag') + t.equal(ber[11], dn.length, 'wrong length') + t.equal(ber.slice(12, 33).toString('utf8'), dn, 'wrong value') + t.equal(ber[33], 0x80, 'wrong tag') + t.equal(ber[34], 0x00, 'wrong len') + + t.end() +}) + +test('Write OID', function (t) { + const oid = '1.2.840.113549.1.1.1' + const writer = new BerWriter() + writer.writeOID(oid) + + const expected = Buffer.from([0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01]) + const ber = writer.buffer + t.equal(ber.compare(expected), 0) + + t.end() +}) + +test('appendBuffer appends a buffer', async t => { + const expected = Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f, 0x66, 0x6f, 0x6f]) + const writer = new BerWriter() + writer.writeString('foo') + writer.appendBuffer(Buffer.from('foo')) + t.equal(Buffer.compare(writer.buffer, expected), 0) +}) diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/index.js b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/index.js new file mode 100644 index 0000000..d5d3d02 --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/lib/index.js @@ -0,0 +1,18 @@ +// Copyright 2011 Mark Cavage All rights reserved. + +// If you have no idea what ASN.1 or BER is, see this: +// https://web.archive.org/web/20220314051854/http://luca.ntop.org/Teaching/Appunti/asn1.html + +const Ber = require('./ber/index') + +// --- Exported API + +module.exports = { + + Ber: Ber, + + BerReader: Ber.Reader, + + BerWriter: Ber.Writer + +} diff --git a/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/package.json b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/package.json new file mode 100644 index 0000000..c03217b --- /dev/null +++ b/node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1/package.json @@ -0,0 +1,34 @@ +{ + "originalAuthor": "Joyent (joyent.com)", + "contributors": [ + "Mark Cavage ", + "David Gwynne ", + "Yunong Xiao ", + "Alex Wilson " + ], + "name": "@ldapjs/asn1", + "description": "Contains parsers and serializers for ASN.1 (currently BER only)", + "version": "1.2.0", + "repository": { + "type": "git", + "url": "git://github.com/ldapjs/asn1.git" + }, + "main": "lib/index.js", + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "standard": "^16.0.4", + "tap": "^16.0.1" + }, + "scripts": { + "test": "tap --no-coverage-report -R terse", + "test:cov": "tap -R terse", + "test:cov:html": "tap -R terse --coverage-report=html", + "test:watch": "tap -w --no-coverage-report -R terse", + "lint": "standard" + }, + "license": "MIT", + "pre-commit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/controls/package.json b/node_modules/@ldapjs/controls/package.json new file mode 100644 index 0000000..201dd89 --- /dev/null +++ b/node_modules/@ldapjs/controls/package.json @@ -0,0 +1,45 @@ +{ + "name": "@ldapjs/controls", + "version": "2.1.0", + "description": "LDAP control objects", + "main": "index.js", + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report -R terse", + "test:cov": "tap -R terse", + "test:cov:html": "tap -R terse --coverage-report=html", + "test:watch": "tap -w --no-coverage-report -R terse" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/ldapjs/controls.git" + }, + "keywords": [ + "ldapjs" + ], + "author": "James Sumners", + "license": "MIT", + "bugs": { + "url": "https://github.com/ldapjs/controls/issues" + }, + "homepage": "https://github.com/ldapjs/controls#readme", + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.34.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.4" + }, + "dependencies": { + "@ldapjs/asn1": "^1.2.0", + "@ldapjs/protocol": "^1.2.1" + }, + "pre-commit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/dn/.eslintrc b/node_modules/@ldapjs/dn/.eslintrc new file mode 100644 index 0000000..2d36b5e --- /dev/null +++ b/node_modules/@ldapjs/dn/.eslintrc @@ -0,0 +1,13 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ], + + "rules": { + "no-labels": ["error", {"allowLoop": true}] + } +} diff --git a/node_modules/@ldapjs/dn/.github/workflows/main.yml b/node_modules/@ldapjs/dn/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/dn/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/dn/.taprc.yaml b/node_modules/@ldapjs/dn/.taprc.yaml new file mode 100644 index 0000000..1f33096 --- /dev/null +++ b/node_modules/@ldapjs/dn/.taprc.yaml @@ -0,0 +1,5 @@ +reporter: terse +coverage-map: coverage-map.js + +files: + - 'lib/**/*.test.js' diff --git a/node_modules/@ldapjs/dn/LICENSE b/node_modules/@ldapjs/dn/LICENSE new file mode 100644 index 0000000..923d87e --- /dev/null +++ b/node_modules/@ldapjs/dn/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Patrick Mooney. All rights reserved. +Copyright (c) 2014 Mark Cavage, Inc. All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/dn/README.md b/node_modules/@ldapjs/dn/README.md new file mode 100644 index 0000000..8108002 --- /dev/null +++ b/node_modules/@ldapjs/dn/README.md @@ -0,0 +1,8 @@ +# dn + +Provides objects for representing and working with LDAP distinguished name +strings as defined by [RFC 4514](https://www.rfc-editor.org/rfc/rfc4514). + +## License + +MIT. diff --git a/node_modules/@ldapjs/dn/coverage-map.js b/node_modules/@ldapjs/dn/coverage-map.js new file mode 100644 index 0000000..fc2046a --- /dev/null +++ b/node_modules/@ldapjs/dn/coverage-map.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = testFile => testFile.replace(/\.test\.js$/, '.js') diff --git a/node_modules/@ldapjs/dn/index.js b/node_modules/@ldapjs/dn/index.js new file mode 100644 index 0000000..cae4100 --- /dev/null +++ b/node_modules/@ldapjs/dn/index.js @@ -0,0 +1,6 @@ +'use strict' + +module.exports = { + DN: require('./lib/dn'), + RDN: require('./lib/rdn') +} diff --git a/node_modules/@ldapjs/dn/lib/deprecations.js b/node_modules/@ldapjs/dn/lib/deprecations.js new file mode 100644 index 0000000..acade37 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/deprecations.js @@ -0,0 +1,11 @@ +'use strict' + +const warning = require('process-warning')() +const clazz = 'LdapjsDnWarning' + +warning.create(clazz, 'LDAP_DN_DEP_001', 'attribute options is deprecated and are ignored') +warning.create(clazz, 'LDAP_DN_DEP_002', '.format() is deprecated. Use .toString() instead') +warning.create(clazz, 'LDAP_DN_DEP_003', '.set() is deprecated. Use .setAttribute() instead') +warning.create(clazz, 'LDAP_DN_DEP_004', '.setFormat() is deprecated. Options will be ignored') + +module.exports = warning diff --git a/node_modules/@ldapjs/dn/lib/dn.js b/node_modules/@ldapjs/dn/lib/dn.js new file mode 100644 index 0000000..368b3b4 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/dn.js @@ -0,0 +1,336 @@ +'use strict' + +const warning = require('./deprecations') +const RDN = require('./rdn') +const parseString = require('./utils/parse-string') + +/** + * Implements distinguished name strings as described in + * https://www.rfc-editor.org/rfc/rfc4514 as an object. + * This is the primary implementation for parsing and generating DN strings. + * + * @example + * const dn = new DN({rdns: [{cn: 'jdoe', givenName: 'John'}] }) + * dn.toString() // 'cn=jdoe+givenName=John' + */ +class DN { + #rdns = [] + + /** + * @param {object} input + * @param {RDN[]} [input.rdns=[]] A set of RDN objects that define the DN. + * Remember that DNs are in reverse domain order. Thus, the target RDN must + * be the first item and the top-level RDN the last item. + * + * @throws When the provided `rdns` array is invalid. + */ + constructor ({ rdns = [] } = {}) { + if (Array.isArray(rdns) === false) { + throw Error('rdns must be an array') + } + + const hasNonRdn = rdns.some( + r => RDN.isRdn(r) === false + ) + if (hasNonRdn === true) { + throw Error('rdns must be an array of RDN objects') + } + + Array.prototype.push.apply( + this.#rdns, + rdns.map(r => { + if (Object.prototype.toString.call(r) === '[object LdapRdn]') { + return r + } + return new RDN(r) + }) + ) + } + + get [Symbol.toStringTag] () { + return 'LdapDn' + } + + /** + * The number of RDNs that make up the DN. + * + * @returns {number} + */ + get length () { + return this.#rdns.length + } + + /** + * Determine if the current instance is the child of another DN instance or + * DN string. + * + * @param {DN|string} dn + * + * @returns {boolean} + */ + childOf (dn) { + if (typeof dn === 'string') { + const parsedDn = DN.fromString(dn) + return parsedDn.parentOf(this) + } + return dn.parentOf(this) + } + + /** + * Get a new instance that is a replica of the current instance. + * + * @returns {DN} + */ + clone () { + return new DN({ rdns: this.#rdns }) + } + + /** + * Determine if the instance is equal to another DN. + * + * @param {DN|string} dn + * + * @returns {boolean} + */ + equals (dn) { + if (typeof dn === 'string') { + const parsedDn = DN.fromString(dn) + return parsedDn.equals(this) + } + + if (this.length !== dn.length) return false + + for (let i = 0; i < this.length; i += 1) { + if (this.#rdns[i].equals(dn.rdnAt(i)) === false) { + return false + } + } + + return true + } + + /** + * @deprecated Use .toString() instead. + * + * @returns {string} + */ + format () { + warning.emit('LDAP_DN_DEP_002') + return this.toString() + } + + /** + * Determine if the instance has any RDNs defined. + * + * @returns {boolean} + */ + isEmpty () { + return this.#rdns.length === 0 + } + + /** + * Get a DN representation of the parent of this instance. + * + * @returns {DN|undefined} + */ + parent () { + if (this.length === 0) return undefined + const save = this.shift() + const dn = new DN({ rdns: this.#rdns }) + this.unshift(save) + return dn + } + + /** + * Determine if the instance is the parent of a given DN instance or DN + * string. + * + * @param {DN|string} dn + * + * @returns {boolean} + */ + parentOf (dn) { + if (typeof dn === 'string') { + const parsedDn = DN.fromString(dn) + return this.parentOf(parsedDn) + } + + if (this.length >= dn.length) { + // If we have more RDNs in our set then we must be a descendent at least. + return false + } + + const numberOfElementsDifferent = dn.length - this.length + for (let i = this.length - 1; i >= 0; i -= 1) { + const myRdn = this.#rdns[i] + const theirRdn = dn.rdnAt(i + numberOfElementsDifferent) + if (myRdn.equals(theirRdn) === false) { + return false + } + } + + return true + } + + /** + * Removes the last RDN from the list and returns it. This alters the + * instance. + * + * @returns {RDN} + */ + pop () { + return this.#rdns.pop() + } + + /** + * Adds a new RDN to the end of the list (i.e. the "top most" RDN in the + * directory path) and returns the new RDN count. + * + * @param {RDN} rdn + * + * @returns {number} + * + * @throws When the input is not a valid RDN. + */ + push (rdn) { + if (Object.prototype.toString.call(rdn) !== '[object LdapRdn]') { + throw Error('rdn must be a RDN instance') + } + return this.#rdns.push(rdn) + } + + /** + * Return the RDN at the provided index in the list of RDNs associated with + * this instance. + * + * @param {number} index + * + * @returns {RDN} + */ + rdnAt (index) { + return this.#rdns[index] + } + + /** + * Reverse the RDNs list such that the first element becomes the last, and + * the last becomes the first. This is useful when the RDNs were added in the + * opposite order of how they should have been. + * + * This is an in-place operation. The instance is changed as a result of + * this operation. + * + * @returns {DN} The current instance (i.e. this method is chainable). + */ + reverse () { + this.#rdns.reverse() + return this + } + + /** + * @deprecated Formatting options are not supported. + */ + setFormat () { + warning.emit('LDAP_DN_DEP_004') + } + + /** + * Remove the first RDN from the set of RDNs and return it. + * + * @returns {RDN} + */ + shift () { + return this.#rdns.shift() + } + + /** + * Render the DN instance as a spec compliant DN string. + * + * @returns {string} + */ + toString () { + let result = '' + for (const rdn of this.#rdns) { + const rdnString = rdn.toString() + result += `,${rdnString}` + } + return result.substring(1) + } + + /** + * Adds an RDN to the beginning of the RDN list and returns the new length. + * + * @param {RDN} rdn + * + * @returns {number} + * + * @throws When the RDN is invalid. + */ + unshift (rdn) { + if (Object.prototype.toString.call(rdn) !== '[object LdapRdn]') { + throw Error('rdn must be a RDN instance') + } + return this.#rdns.unshift(rdn) + } + + /** + * Determine if an object is an instance of {@link DN} or is at least + * a DN-like object. It is safer to perform a `toString` check. + * + * @example Valid Instance + * const dn = new DN() + * DN.isDn(dn) // true + * + * @example DN-like Instance + * let dn = { rdns: [{name: 'cn', value: 'foo'}] } + * DN.isDn(dn) // true + * + * dn = { rdns: [{cn: 'foo', sn: 'bar'}, {dc: 'example'}, {dc: 'com'}]} + * DN.isDn(dn) // true + * + * @example Preferred Check + * let dn = new DN() + * Object.prototype.toString.call(dn) === '[object LdapDn]' // true + * + * dn = { rdns: [{name: 'cn', value: 'foo'}] } + * Object.prototype.toString.call(dn) === '[object LdapDn]' // false + * + * @param {object} dn + * @returns {boolean} + */ + static isDn (dn) { + if (Object.prototype.toString.call(dn) === '[object LdapDn]') { + return true + } + if ( + Object.prototype.toString.call(dn) !== '[object Object]' || + Array.isArray(dn.rdns) === false + ) { + return false + } + if (dn.rdns.some(dn => RDN.isRdn(dn) === false) === true) { + return false + } + + return true + } + + /** + * Parses a DN string and returns a new {@link DN} instance. + * + * @example + * const dn = DN.fromString('cn=foo,dc=example,dc=com') + * DN.isDn(dn) // true + * + * @param {string} dnString + * + * @returns {DN} + * + * @throws If the string is not parseable. + */ + static fromString (dnString) { + const rdns = parseString(dnString) + return new DN({ rdns }) + } +} + +module.exports = DN diff --git a/node_modules/@ldapjs/dn/lib/dn.test.js b/node_modules/@ldapjs/dn/lib/dn.test.js new file mode 100644 index 0000000..90252b5 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/dn.test.js @@ -0,0 +1,527 @@ +'use strict' + +const tap = require('tap') +const warning = require('./deprecations') +const RDN = require('./rdn') +const DN = require('./dn') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +tap.test('constructor', t => { + t.test('throws for non-array', async t => { + t.throws( + () => new DN({ rdns: 42 }), + Error('rdns must be an array') + ) + }) + + t.test('throws for non-rdn in array', async t => { + const rdns = [ + new RDN(), + { 'non-string-value': 42 }, + new RDN() + ] + t.throws( + () => new DN({ rdns }) + ) + }) + + t.test('handles mixed array', async t => { + const rdns = [ + { cn: 'foo' }, + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + const dn = new DN({ rdns }) + t.equal(dn.length, 3) + t.equal(dn.toString(), 'cn=foo,dc=example,dc=com') + }) + + t.end() +}) + +tap.test('childOf', t => { + t.test('false if we are shallower', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = new DN({ + rdns: [ + new RDN({ cn: 'foo' }), + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.childOf(target), false) + }) + + t.test('false if differing path', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = new DN({ + rdns: [ + new RDN({ dc: 'ldapjs' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.childOf(target), false) + }) + + t.test('true if we are a child', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = new DN({ + rdns: [ + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.childOf(target), true) + }) + + t.test('handles string input', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = 'dc=example,dc=com' + t.equal(dn.childOf(target), true) + }) + + t.end() +}) + +tap.test('clone', t => { + t.test('returns a copy', async t => { + const rdns = [new RDN({ cn: 'foo' })] + const src = new DN({ rdns }) + const clone = src.clone() + + t.equal(src.length, clone.length) + t.equal(src.toString(), clone.toString()) + }) + + t.end() +}) + +tap.test('equals', t => { + t.test('false for non-equal length', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = new DN({ + rdns: [ + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.equals(target), false) + }) + + t.test('false for non-equal paths', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = new DN({ + rdns: [ + new RDN({ ou: 'computers' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.equals(target), false) + }) + + t.test('true for equal paths', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.equals(target), true) + }) + + t.test('handles string input', async t => { + const dn = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = 'ou=people,dc=example,dc=com' + t.equal(dn.equals(target), true) + }) + + t.end() +}) + +tap.test('format', t => { + t.test('emits warning', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_DN_DEP_002', false) + }) + + const rdns = [{ cn: 'foo' }] + const dnString = (new DN({ rdns })).format() + t.equal(dnString, 'cn=foo') + + function handler (error) { + t.equal(error.message, '.format() is deprecated. Use .toString() instead') + t.end() + } + }) + + t.end() +}) + +tap.test('isEmpty', t => { + t.test('returns correct result', async t => { + let dn = new DN() + t.equal(dn.isEmpty(), true) + + dn = new DN({ + rdns: [new RDN({ cn: 'foo' })] + }) + t.equal(dn.isEmpty(), false) + }) + + t.end() +}) + +tap.test('parent', t => { + t.test('undefined for an empty DN', async t => { + const dn = new DN() + const parent = dn.parent() + t.equal(parent, undefined) + }) + + t.test('returns correct DN', async t => { + const dn = new DN({ + rdns: [ + new RDN({ cn: 'jdoe', givenName: 'John' }), + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const parent = dn.parent() + t.equal(parent.toString(), 'ou=people,dc=example,dc=com') + }) + + t.end() +}) + +tap.test('parentOf', t => { + t.test('false if we are deeper', async t => { + const target = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const dn = new DN({ + rdns: [ + new RDN({ cn: 'foo' }), + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.parentOf(target), false) + }) + + t.test('false if differing path', async t => { + const target = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const dn = new DN({ + rdns: [ + new RDN({ dc: 'ldapjs' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.parentOf(target), false) + }) + + t.test('true if we are a parent', async t => { + const target = new DN({ + rdns: [ + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const dn = new DN({ + rdns: [ + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.parentOf(target), true) + }) + + t.test('handles string input', async t => { + const dn = new DN({ + rdns: [ + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const target = 'ou=people,dc=example,dc=com' + t.equal(dn.parentOf(target), true) + }) + + t.end() +}) + +tap.test('pop', t => { + t.test('returns the last element and shortens the list', async t => { + const dn = new DN({ + rdns: [ + new RDN({ cn: 'foo' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.toString(), 'cn=foo,dc=example,dc=com') + + const rdn = dn.pop() + t.equal(rdn.toString(), 'dc=com') + t.equal(dn.toString(), 'cn=foo,dc=example') + }) + + t.end() +}) + +tap.test('push', t => { + t.test('throws for bad input', async t => { + const dn = new DN() + t.throws( + () => dn.push({ cn: 'foo' }), + Error('rdn must be a RDN instance') + ) + }) + + t.test('adds to the front of the list', async t => { + const dn = new DN({ + rdns: [ + new RDN({ cn: 'foo' }), + new RDN({ dc: 'example' }) + + ] + }) + t.equal(dn.toString(), 'cn=foo,dc=example') + + const newLength = dn.push(new RDN({ dc: 'com' })) + t.equal(newLength, 3) + t.equal(dn.toString(), 'cn=foo,dc=example,dc=com') + }) + + t.end() +}) + +tap.test('rdnAt', t => { + t.test('returns correct RDN', async t => { + const dn = new DN({ + rdns: [ + new RDN({ cn: 'jdoe', givenName: 'John' }), + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + const rdn = dn.rdnAt(1) + t.equal(rdn.toString(), 'ou=people') + }) + + t.end() +}) + +tap.test('reverse', t => { + t.test('reverses the list', async t => { + const dn = new DN({ + rdns: [ + new RDN({ dc: 'com' }), + new RDN({ dc: 'example' }), + new RDN({ cn: 'foo' }) + ] + }) + t.equal(dn.toString(), 'dc=com,dc=example,cn=foo') + + const result = dn.reverse() + t.equal(dn, result) + t.equal(dn.toString(), 'cn=foo,dc=example,dc=com') + }) + + t.end() +}) + +tap.test('setFormat', t => { + t.test('emits warning', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_DN_DEP_004', false) + }) + + const rdns = [{ cn: 'foo' }] + new DN({ rdns }).setFormat() + + function handler (error) { + t.equal(error.message, '.setFormat() is deprecated. Options will be ignored') + t.end() + } + }) + + t.end() +}) + +tap.test('shift', t => { + t.test('returns the first element and shortens the list', async t => { + const dn = new DN({ + rdns: [ + new RDN({ cn: 'foo' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.toString(), 'cn=foo,dc=example,dc=com') + + const rdn = dn.shift() + t.equal(rdn.toString(), 'cn=foo') + t.equal(dn.toString(), 'dc=example,dc=com') + }) + + t.end() +}) + +tap.test('toString', t => { + t.test('renders correctly', async t => { + const dn = new DN({ + rdns: [ + new RDN({ cn: 'jdoe', givenName: 'John' }), + new RDN({ ou: 'people' }), + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.toString(), 'cn=jdoe+givenName=John,ou=people,dc=example,dc=com') + }) + + t.test('empty string for empty DN', async t => { + const dn = new DN() + t.equal(dn.toString(), '') + }) + + t.end() +}) + +tap.test('unshift', t => { + t.test('throws for bad input', async t => { + const dn = new DN() + t.throws( + () => dn.unshift({ cn: 'foo' }), + Error('rdn must be a RDN instance') + ) + }) + + t.test('adds to the front of the list', async t => { + const dn = new DN({ + rdns: [ + new RDN({ dc: 'example' }), + new RDN({ dc: 'com' }) + ] + }) + t.equal(dn.toString(), 'dc=example,dc=com') + + const newLength = dn.unshift(new RDN({ cn: 'foo' })) + t.equal(newLength, 3) + t.equal(dn.toString(), 'cn=foo,dc=example,dc=com') + }) + + t.end() +}) + +tap.test('#isDn', t => { + t.test('true for instance', async t => { + const dn = new DN() + t.equal(DN.isDn(dn), true) + }) + + t.test('false for non-object', async t => { + t.equal(DN.isDn(42), false) + }) + + t.test('false for non-array rdns', async t => { + const input = { rdns: 42 } + t.equal(DN.isDn(input), false) + }) + + t.test('false for bad rdn', async t => { + const input = { rdns: [{ bad: 'rdn', answer: 42 }] } + t.equal(DN.isDn(input), false) + }) + + t.test('true for dn-like', async t => { + const input = { rdns: [{ name: 'cn', value: 'foo' }] } + t.equal(DN.isDn(input), true) + }) + + t.end() +}) + +tap.test('#fromString', t => { + t.test('parses a basic string into an instance', async t => { + const input = 'cn=foo+sn=bar,dc=example,dc=com' + const dn = DN.fromString(input) + t.equal(DN.isDn(dn), true) + t.equal(dn.length, 3) + t.equal(dn.rdnAt(0).toString(), 'cn=foo+sn=bar') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/dn/lib/rdn.js b/node_modules/@ldapjs/dn/lib/rdn.js new file mode 100644 index 0000000..1f077df --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/rdn.js @@ -0,0 +1,257 @@ +'use strict' + +const warning = require('./deprecations') +const escapeValue = require('./utils/escape-value') +const isDottedDecimal = require('./utils/is-dotted-decimal') + +/** + * Implements a relative distinguished name as described in + * https://www.rfc-editor.org/rfc/rfc4514. + * + * @example + * const rdn = new RDN({cn: 'jdoe', givenName: 'John'}) + * rdn.toString() // 'cn=jdoe+givenName=John' + */ +class RDN { + #attributes = new Map() + + /** + * @param {object} rdn An object of key-values to use as RDN attribute + * types and attribute values. Attribute values should be strings. + */ + constructor (rdn = {}) { + for (const [key, val] of Object.entries(rdn)) { + this.setAttribute({ name: key, value: val }) + } + } + + get [Symbol.toStringTag] () { + return 'LdapRdn' + } + + /** + * The number attributes associated with the RDN. + * + * @returns {number} + */ + get size () { + return this.#attributes.size + } + + /** + * Very naive equality check against another RDN instance. In short, if they + * do not have the exact same key names with the exact same values, then + * this check will return `false`. + * + * @param {RDN} rdn + * + * @returns {boolean} + * + * @todo Should implement support for the attribute types listed in https://www.rfc-editor.org/rfc/rfc4514#section-3 + */ + equals (rdn) { + if (Object.prototype.toString.call(rdn) !== '[object LdapRdn]') { + return false + } + if (this.size !== rdn.size) { + return false + } + + for (const key of this.keys()) { + if (rdn.has(key) === false) return false + if (this.getValue(key) !== rdn.getValue(key)) return false + } + + return true + } + + /** + * The value associated with the given attribute name. + * + * @param {string} name An attribute name associated with the RDN. + * + * @returns {*} + */ + getValue (name) { + return this.#attributes.get(name)?.value + } + + /** + * Determine if the RDN has a specific attribute assigned. + * + * @param {string} name The name of the attribute. + * + * @returns {boolean} + */ + has (name) { + return this.#attributes.has(name) + } + + /** + * All attribute names associated with the RDN. + * + * @returns {IterableIterator} + */ + keys () { + return this.#attributes.keys() + } + + /** + * Define an attribute type and value on the RDN. + * + * @param {string} name + * @param {string | import('@ldapjs/asn1').BerReader} value + * @param {object} options Deprecated. All options will be ignored. + * + * @throws If any parameter is invalid. + */ + setAttribute ({ name, value, options = {} }) { + if (typeof name !== 'string') { + throw Error('name must be a string') + } + + const valType = Object.prototype.toString.call(value) + if (typeof value !== 'string' && valType !== '[object BerReader]') { + throw Error('value must be a string or BerReader') + } + if (Object.prototype.toString.call(options) !== '[object Object]') { + throw Error('options must be an object') + } + + const startsWithAlpha = str => /^[a-zA-Z]/.test(str) === true + if (startsWithAlpha(name) === false && isDottedDecimal(name) === false) { + throw Error('attribute name must start with an ASCII alpha character or be a numeric OID') + } + + const attr = { value, name } + for (const [key, val] of Object.entries(options)) { + warning.emit('LDAP_DN_DEP_001') + if (key === 'value') continue + attr[key] = val + } + + this.#attributes.set(name, attr) + } + + /** + * Convert the RDN to a string representation. If an attribute value is + * an instance of `BerReader`, the value will be encoded appropriately. + * + * @example Dotted Decimal Type + * const rdn = new RDN({ + * cn: '#foo', + * '1.3.6.1.4.1.1466.0': '#04024869' + * }) + * rnd.toString() + * // => 'cn=\23foo+1.3.6.1.4.1.1466.0=#04024869' + * + * @example Unescaped Value + * const rdn = new RDN({ + * cn: '#foo' + * }) + * rdn.toString({ unescaped: true }) + * // => 'cn=#foo' + * + * @param {object} [options] + * @param {boolean} [options.unescaped=false] Return the unescaped version + * of the RDN string. + * + * @returns {string} + */ + toString ({ unescaped = false } = {}) { + let result = '' + const isHexEncodedValue = val => /^#([0-9a-fA-F]{2})+$/.test(val) === true + + for (const entry of this.#attributes.values()) { + result += entry.name + '=' + + if (isHexEncodedValue(entry.value)) { + result += entry.value + } else if (Object.prototype.toString.call(entry.value) === '[object BerReader]') { + let encoded = '#' + for (const byte of entry.value.buffer) { + encoded += Number(byte).toString(16).padStart(2, '0') + } + result += encoded + } else { + result += unescaped === false ? escapeValue(entry.value) : entry.value + } + + result += '+' + } + + return result.substring(0, result.length - 1) + } + + /** + * @returns {string} + * + * @deprecated Use {@link toString}. + */ + format () { + // If we decide to add back support for this, we should do it as + // `.toStringWithFormatting(options)`. + warning.emit('LDAP_DN_DEP_002') + return this.toString() + } + + /** + * @param {string} name + * @param {string} value + * @param {object} options + * + * @deprecated Use {@link setAttribute}. + */ + set (name, value, options) { + warning.emit('LDAP_DN_DEP_003') + this.setAttribute({ name, value, options }) + } + + /** + * Determine if an object is an instance of {@link RDN} or is at least + * a RDN-like object. It is safer to perform a `toString` check. + * + * @example Valid Instance + * const Rdn = new RDN() + * RDN.isRdn(rdn) // true + * + * @example RDN-like Instance + * const rdn = { name: 'cn', value: 'foo' } + * RDN.isRdn(rdn) // true + * + * @example Preferred Check + * let rdn = new RDN() + * Object.prototype.toString.call(rdn) === '[object LdapRdn]' // true + * + * dn = { name: 'cn', value: 'foo' } + * Object.prototype.toString.call(dn) === '[object LdapRdn]' // false + * + * @param {object} rdn + * @returns {boolean} + */ + static isRdn (rdn) { + if (Object.prototype.toString.call(rdn) === '[object LdapRdn]') { + return true + } + + const isObject = Object.prototype.toString.call(rdn) === '[object Object]' + if (isObject === false) { + return false + } + + if (typeof rdn.name === 'string' && typeof rdn.value === 'string') { + return true + } + + for (const value of Object.values(rdn)) { + if ( + typeof value !== 'string' && + Object.prototype.toString.call(value) !== '[object BerReader]' + ) return false + } + + return true + } +} + +module.exports = RDN diff --git a/node_modules/@ldapjs/dn/lib/rdn.test.js b/node_modules/@ldapjs/dn/lib/rdn.test.js new file mode 100644 index 0000000..5276812 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/rdn.test.js @@ -0,0 +1,214 @@ +'use strict' + +const tap = require('tap') +const warning = require('./deprecations') +const { BerReader } = require('@ldapjs/asn1') +const RDN = require('./rdn') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +tap.test('equals', t => { + t.test('false for non-rdn object', async t => { + const rdn = new RDN() + t.equal(rdn.equals({}), false) + }) + + t.test('false for size mis-match', async t => { + const rdn1 = new RDN({ cn: 'foo' }) + const rdn2 = new RDN({ cn: 'foo', sn: 'bar' }) + t.equal(rdn1.equals(rdn2), false) + }) + + t.test('false for keys mis-match', async t => { + const rdn1 = new RDN({ cn: 'foo' }) + const rdn2 = new RDN({ sn: 'bar' }) + t.equal(rdn1.equals(rdn2), false) + }) + + t.test('false for value mis-match', async t => { + const rdn1 = new RDN({ cn: 'foo' }) + const rdn2 = new RDN({ cn: 'bar' }) + t.equal(rdn1.equals(rdn2), false) + }) + + t.test('true for match', async t => { + const rdn1 = new RDN({ cn: 'foo' }) + const rdn2 = new RDN({ cn: 'foo' }) + t.equal(rdn1.equals(rdn2), true) + }) + + t.end() +}) + +tap.test('setAttribute', async t => { + t.test('throws for bad name', async t => { + const rdn = new RDN() + t.throws( + () => rdn.setAttribute({ name: 42 }), + Error('name must be a string') + ) + + t.throws( + () => rdn.setAttribute({ name: '3cn', value: 'foo' }), + Error('attribute name must start with an ASCII alpha character or be a numeric OID') + ) + }) + + t.test('throws for bad value', async t => { + const rdn = new RDN() + t.throws( + () => rdn.setAttribute({ name: 'cn', value: 42 }), + Error('value must be a string') + ) + }) + + t.test('throws for options', async t => { + const rdn = new RDN() + t.throws( + () => rdn.setAttribute({ name: 'cn', value: 'foo', options: 42 }), + Error('options must be an object') + ) + }) + + t.test('sets an attribute with value', async t => { + const rdn = new RDN() + rdn.setAttribute({ name: 'cn', value: 'foo' }) + t.equal(rdn.getValue('cn'), 'foo') + }) + + t.test('options generates warning', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_DN_DEP_001', false) + }) + + const rdn = new RDN() + rdn.setAttribute({ name: 'cn', value: 'foo', options: { foo: 'bar' } }) + + function handler (error) { + t.equal(error.message, 'attribute options is deprecated and are ignored') + t.end() + } + }) + + t.end() +}) + +tap.test('toString', t => { + t.test('basic single value', async t => { + const rdn = new RDN({ cn: 'foo' }) + t.equal(rdn.toString(), 'cn=foo') + }) + + t.test('escaped single value', async t => { + const rdn = new RDN({ cn: ' foo, bar\n' }) + t.equal(rdn.toString(), 'cn=\\20foo\\2c bar\\0a') + }) + + t.test('basic multi-value', async t => { + const rdn = new RDN({ cn: 'foo', sn: 'bar' }) + t.equal(rdn.toString(), 'cn=foo+sn=bar') + }) + + t.test('escaped multi-value', async t => { + const rdn = new RDN({ cn: '#foo', sn: 'bar' }) + t.equal(rdn.toString(), 'cn=\\23foo+sn=bar') + }) + + t.test('recognizes encoded string values', async t => { + const rdn = new RDN({ + cn: '#foo', + '1.3.6.1.4.1.1466.0': '#04024869' + }) + t.equal(rdn.toString(), 'cn=\\23foo+1.3.6.1.4.1.1466.0=#04024869') + }) + + t.test('encodes BerReader instances', async t => { + const rdn = new RDN({ + cn: new BerReader(Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f])) + }) + t.equal(rdn.toString(), 'cn=#0403666f6f') + }) + + t.test('honors unescaped options', async t => { + const rdn = new RDN({ + ou: '研发二组' + }) + t.equal(rdn.toString({ unescaped: true }), 'ou=研发二组') + }) + + t.end() +}) + +tap.test('deprecations', t => { + t.test('format', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_DN_DEP_002', false) + }) + + const rdn = new RDN({ cn: 'foo' }) + t.equal(rdn.format(), 'cn=foo') + + function handler (error) { + t.equal(error.message, '.format() is deprecated. Use .toString() instead') + t.end() + } + }) + + t.test('set', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_DN_DEP_002', false) + }) + + const rdn = new RDN() + rdn.set('cn', 'foo', { value: 'ignored' }) + + function handler (error) { + t.equal(error.message, '.set() is deprecated. Use .setAttribute() instead') + t.end() + } + }) + + t.end() +}) + +tap.test('#isRdn', t => { + t.test('true for instance', async t => { + const rdn = new RDN() + t.equal(RDN.isRdn(rdn), true) + }) + + t.test('false for non-object', async t => { + t.equal(RDN.isRdn(42), false) + }) + + t.test('false for bad object', async t => { + const input = { bad: 'rdn', 'non-string-value': 42 } + t.equal(RDN.isRdn(input), false) + }) + + t.test('true for rdn-like with name+value keys', async t => { + const input = { name: 'cn', value: 'foo' } + t.equal(RDN.isRdn(input), true) + }) + + t.test('true for pojo representation', async t => { + const input = { cn: 'foo', sn: 'bar' } + t.equal(RDN.isRdn(input), true) + }) + + t.test('true for pojo with BerReader', async t => { + const input = { + foo: new BerReader(Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f])) + } + t.equal(RDN.isRdn(input), true) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/escape-value.js b/node_modules/@ldapjs/dn/lib/utils/escape-value.js new file mode 100644 index 0000000..d9ccf98 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/escape-value.js @@ -0,0 +1,104 @@ +'use strict' + +/** + * Converts an attribute value into an escaped string as described in + * https://www.rfc-editor.org/rfc/rfc4514#section-2.4. + * + * This function supports up to 4 byte unicode characters. + * + * @param {string} value + * @returns {string} The escaped string. + */ +module.exports = function escapeValue (value) { + if (typeof value !== 'string') { + throw Error('value must be a string') + } + + const toEscape = Buffer.from(value, 'utf8') + const escaped = [] + + // We will handle the reverse solidus ('\') on its own. + const embeddedReservedChars = [ + 0x22, // '"' + 0x2b, // '+' + 0x2c, // ',' + 0x3b, // ';' + 0x3c, // '<' + 0x3e // '>' + ] + for (let i = 0; i < toEscape.byteLength;) { + const charHex = toEscape[i] + + // Handle leading space or #. + if (i === 0 && (charHex === 0x20 || charHex === 0x23)) { + escaped.push(toEscapedHexString(charHex)) + i += 1 + continue + } + // Handle trailing space. + if (i === toEscape.byteLength - 1 && charHex === 0x20) { + escaped.push(toEscapedHexString(charHex)) + i += 1 + continue + } + + if (embeddedReservedChars.includes(charHex) === true) { + escaped.push(toEscapedHexString(charHex)) + i += 1 + continue + } + + if (charHex >= 0xc0 && charHex <= 0xdf) { + // Represents the first byte in a 2-byte UTF-8 character. + escaped.push(toEscapedHexString(charHex)) + escaped.push(toEscapedHexString(toEscape[i + 1])) + i += 2 + continue + } + + if (charHex >= 0xe0 && charHex <= 0xef) { + // Represents the first byte in a 3-byte UTF-8 character. + escaped.push(toEscapedHexString(charHex)) + escaped.push(toEscapedHexString(toEscape[i + 1])) + escaped.push(toEscapedHexString(toEscape[i + 2])) + i += 3 + continue + } + + if (charHex >= 0xf0 && charHex <= 0xf7) { + // Represents the first byte in a 4-byte UTF-8 character. + escaped.push(toEscapedHexString(charHex)) + escaped.push(toEscapedHexString(toEscape[i + 1])) + escaped.push(toEscapedHexString(toEscape[i + 2])) + escaped.push(toEscapedHexString(toEscape[i + 3])) + i += 4 + continue + } + + if (charHex <= 31) { + // Represents an ASCII control character. + escaped.push(toEscapedHexString(charHex)) + i += 1 + continue + } + + escaped.push(String.fromCharCode(charHex)) + i += 1 + continue + } + + return escaped.join('') +} + +/** + * Given a byte, convert it to an escaped hex string. + * + * @example + * toEscapedHexString(0x20) // '\20' + * + * @param {number} char + * @returns {string} + */ +function toEscapedHexString (char) { + return '\\' + char.toString(16).padStart(2, '0') +} diff --git a/node_modules/@ldapjs/dn/lib/utils/escape-value.test.js b/node_modules/@ldapjs/dn/lib/utils/escape-value.test.js new file mode 100644 index 0000000..9f7ba71 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/escape-value.test.js @@ -0,0 +1,62 @@ +'use strict' + +const tap = require('tap') +const escapeValue = require('./escape-value') + +tap.test('throws for bad input', async t => { + t.throws( + () => escapeValue(42), + Error('value must be a string') + ) +}) + +tap.test('reserved chars', t => { + t.test('space', async t => { + const input = ' has a leading and trailing space ' + const expected = '\\20has a leading and trailing space\\20' + const result = escapeValue(input) + t.equal(result, expected) + }) + + t.test('leading #', async t => { + t.equal(escapeValue('#hashtag'), '\\23hashtag') + }) + + t.test('pompous name', async t => { + t.equal( + escapeValue('James "Jim" Smith, III'), + 'James \\22Jim\\22 Smith\\2c III' + ) + }) + + t.test('carriage return', async t => { + t.equal(escapeValue('Before\rAfter'), 'Before\\0dAfter') + }) + + t.end() +}) + +tap.test('2-byte utf-8', t => { + t.test('Lučić', async t => { + const expected = 'Lu\\c4\\8di\\c4\\87' + t.equal(escapeValue('Lučić'), expected) + }) + + t.end() +}) + +tap.test('3-byte utf-8', t => { + t.test('₠', async t => { + t.equal(escapeValue('₠'), '\\e2\\82\\a0') + }) + + t.end() +}) + +tap.test('4-byte utf-8', t => { + t.test('😀', async t => { + t.equal(escapeValue('😀'), '\\f0\\9f\\98\\80') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/is-dotted-decimal.js b/node_modules/@ldapjs/dn/lib/utils/is-dotted-decimal.js new file mode 100644 index 0000000..d80cdbb --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/is-dotted-decimal.js @@ -0,0 +1,19 @@ +'use strict' + +const partIsNotNumeric = part => /^\d+$/.test(part) === false + +/** + * Determines if a passed in string is a dotted decimal string. + * + * @param {string} value + * + * @returns {boolean} + */ +module.exports = function isDottedDecimal (value) { + if (typeof value !== 'string') return false + + const parts = value.split('.') + const nonNumericParts = parts.filter(partIsNotNumeric) + + return nonNumericParts.length === 0 +} diff --git a/node_modules/@ldapjs/dn/lib/utils/is-dotted-decimal.test.js b/node_modules/@ldapjs/dn/lib/utils/is-dotted-decimal.test.js new file mode 100644 index 0000000..f13ca3a --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/is-dotted-decimal.test.js @@ -0,0 +1,24 @@ +'use strict' + +const tap = require('tap') +const isDottedDecimal = require('./is-dotted-decimal') + +tap.test('false for non-string', async t => { + t.equal(isDottedDecimal(), false) +}) + +tap.test('false for empty string', async t => { + t.equal(isDottedDecimal(''), false) +}) + +tap.test('false for alpha string', async t => { + t.equal(isDottedDecimal('foo'), false) +}) + +tap.test('false for alpha-num string', async t => { + t.equal(isDottedDecimal('foo.123'), false) +}) + +tap.test('true for valid string', async t => { + t.equal(isDottedDecimal('1.2.3'), true) +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-end.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-end.js new file mode 100644 index 0000000..25c5723 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-end.js @@ -0,0 +1,58 @@ +'use strict' + +/** + * Find the ending position of the attribute type name portion of an RDN. + * This function does not verify if the name is a valid description string + * or numeric OID. It merely reads a string from the given starting position + * to the spec defined end of an attribute type string. + * + * @param {Buffer} searchBuffer A buffer representing the RDN. + * @param {number} startPos The position in the `searchBuffer` to start + * searching from. + * + * @returns {number} The position of the end of the RDN's attribute type name, + * or `-1` if an invalid character has been encountered. + */ +module.exports = function findNameEnd ({ searchBuffer, startPos }) { + let pos = startPos + + while (pos < searchBuffer.byteLength) { + const char = searchBuffer[pos] + if (char === 0x20 || char === 0x3d) { + // Name ends with a space or an '=' character. + break + } + if (isValidNameChar(char) === true) { + pos += 1 + continue + } + return -1 + } + + return pos +} + +/** + * Determine if a character is a valid `attributeType` character as defined + * in RFC 4514 §3. + * + * @param {number} c The character to verify. Should be the byte representation + * of the character from a {@link Buffer} instance. + * + * @returns {boolean} + */ +function isValidNameChar (c) { + if (c >= 0x41 && c <= 0x5a) { // A - Z + return true + } + if (c >= 0x61 && c <= 0x7a) { // a - z + return true + } + if (c >= 0x30 && c <= 0x39) { // 0 - 9 + return true + } + if (c === 0x2d || c === 0x2e) { // - or . + return true + } + return false +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-end.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-end.test.js new file mode 100644 index 0000000..e04c450 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-end.test.js @@ -0,0 +1,28 @@ +'use strict' + +const tap = require('tap') +const findNameEnd = require('./find-name-end') + +tap.test('stops on a space', async t => { + const input = Buffer.from('foo = bar') + const pos = findNameEnd({ searchBuffer: input, startPos: 0 }) + t.equal(pos, 3) +}) + +tap.test('stops on an equals', async t => { + const input = Buffer.from('foo=bar') + const pos = findNameEnd({ searchBuffer: input, startPos: 0 }) + t.equal(pos, 3) +}) + +tap.test('returns -1 for bad character', async t => { + const input = Buffer.from('føø=bar') + const pos = findNameEnd({ searchBuffer: input, startPos: 0 }) + t.equal(pos, -1) +}) + +tap.test('recognizes all valid characters', async t => { + const input = Buffer.from('Foo.0-bar=baz') + const pos = findNameEnd({ searchBuffer: input, startPos: 0 }) + t.equal(pos, 9) +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-start.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-start.js new file mode 100644 index 0000000..4da7aa0 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-start.js @@ -0,0 +1,34 @@ +'use strict' + +// Attribute types must start with an ASCII alphanum character. +// https://www.rfc-editor.org/rfc/rfc4514#section-3 +// https://www.rfc-editor.org/rfc/rfc4512#section-1.4 +const isLeadChar = (c) => /[a-zA-Z0-9]/.test(c) === true + +/** + * Find the starting position of an attribute type (name). Leading spaces and + * commas are ignored. If an invalid leading character is encountered, an + * invalid position will be returned. + * + * @param {Buffer} searchBuffer + * @param {number} startPos + * + * @returns {number} The position in the buffer where the name starts, or `-1` + * if an invalid name starting character is encountered. + */ +module.exports = function findNameStart ({ searchBuffer, startPos }) { + let pos = startPos + while (pos < searchBuffer.byteLength) { + if (searchBuffer[pos] === 0x20 || searchBuffer[pos] === 0x2c) { + // Skip leading space and comma. + pos += 1 + continue + } + const char = String.fromCharCode(searchBuffer[pos]) + if (isLeadChar(char) === true) { + return pos + } + break + } + return -1 +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-start.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-start.test.js new file mode 100644 index 0000000..a0c2a16 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/find-name-start.test.js @@ -0,0 +1,28 @@ +'use strict' + +const tap = require('tap') +const findNameStart = require('./find-name-start') + +tap.test('returns correct position', async t => { + const input = Buffer.from(' foo') + t.equal( + findNameStart({ searchBuffer: input, startPos: 0 }), + 3 + ) +}) + +tap.test('skips leading comma', async t => { + const input = Buffer.from(' , foo=bar') + t.equal( + findNameStart({ searchBuffer: input, startPos: 0 }), + 3 + ) +}) + +tap.test('returns -1 for invalid lead char', async t => { + const input = Buffer.from(' øfoo') + t.equal( + findNameStart({ searchBuffer: input, startPos: 0 }), + -1 + ) +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/index.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/index.js new file mode 100644 index 0000000..4d53a58 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/index.js @@ -0,0 +1,105 @@ +'use strict' + +const readAttributePair = require('./read-attribute-pair') + +/** + * @typedef {object} ParsedPojoRdn + * @property {string} name Either the name of an RDN attribute, or the + * equivalent numeric OID. + * @property {string | import('@ldapjs/asn1').BerReader} value The attribute + * value as a plain string, or a `BerReader` if the string value was an encoded + * hex string. + */ + +/** + * Parse a string into a set of plain JavaScript object representations of + * RDNs. + * + * @example A plain string with multiple RDNs and multiple attribute assertions. + * const input = 'cn=foo+sn=bar,dc=example,dc=com + * const result = parseString(input) + * // [ + * // { cn: 'foo', sn: 'bar' }, + * // { dc: 'example' } + * // { dc: 'com' } + * // ] + * + * @param {string} input The RDN string to parse. + * + * @returns {ParsedPojoRdn[]} + * + * @throws When there is some problem parsing the RDN string. + */ +module.exports = function parseString (input) { + if (typeof input !== 'string') { + throw Error('input must be a string') + } + if (input.length === 0) { + // Short circuit because the input is an empty DN (i.e. "root DSE"). + return [] + } + + const searchBuffer = Buffer.from(input, 'utf8') + const length = searchBuffer.byteLength + const rdns = [] + + let pos = 0 + let rdn = {} + + readRdnLoop: + while (pos <= length) { + if (pos === length) { + const char = searchBuffer[pos - 1] + + /* istanbul ignore else */ + if (char === 0x2b || char === 0x2c || char === 0x3b) { + throw Error('rdn string ends abruptly with character: ' + String.fromCharCode(char)) + } + } + + // Find the start of significant characters by skipping over any leading + // whitespace. + while (pos < length && searchBuffer[pos] === 0x20) { + pos += 1 + } + + const readAttrPairResult = readAttributePair({ searchBuffer, startPos: pos }) + pos = readAttrPairResult.endPos + rdn = { ...rdn, ...readAttrPairResult.pair } + + if (pos >= length) { + // We've reached the end of the string. So push the current RDN and stop. + rdns.push(rdn) + break + } + + // Next, we need to determine if the next set of significant characters + // denotes another attribute pair for the current RDN, or is the indication + // of another RDN. + while (pos < length) { + const char = searchBuffer[pos] + + // We don't need to skip whitespace before the separator because the + // attribute pair function has already advanced us past any such + // whitespace. + + if (char === 0x2b) { // + + // We need to continue adding attribute pairs to the current RDN. + pos += 1 + continue readRdnLoop + } + + /* istanbul ignore else */ + if (char === 0x2c || char === 0x3b) { // , or ; + // The current RDN has been fully parsed, so push it to the list, + // reset the collector, and start parsing the next RDN. + rdns.push(rdn) + rdn = {} + pos += 1 + continue readRdnLoop + } + } + } + + return rdns +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/index.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/index.test.js new file mode 100644 index 0000000..38b37b7 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/index.test.js @@ -0,0 +1,214 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const parseString = require('./index') + +tap.test('throws for non-string input', async t => { + const input = ['cn=foo'] + t.throws( + () => parseString(input), + 'input must be a string' + ) +}) + +tap.test('short circuits for root dse', async t => { + t.same(parseString(''), []) +}) + +tap.test('parses basic single rdn', async t => { + const input = 'cn=foo' + const result = parseString(input) + t.same(result, [{ cn: 'foo' }]) +}) + +tap.test('skips leading whitespace', async t => { + const input = ' cn=foo' + const result = parseString(input) + t.same(result, [{ cn: 'foo' }]) +}) + +tap.test('parses basic multiple rdns', async t => { + let input = 'dc=example,dc=com' + let result = parseString(input) + t.same( + result, + [ + { dc: 'example' }, + { dc: 'com' } + ] + ) + + // RFC 2253 §4 separator is supported. + input = 'dc=example;dc=com' + result = parseString(input) + t.same( + result, + [ + { dc: 'example' }, + { dc: 'com' } + ] + ) +}) + +tap.test('handles multivalued rdn', async t => { + const input = 'foo=bar+baz=bif' + const result = parseString(input) + t.same(result, [{ foo: 'bar', baz: 'bif' }]) +}) + +tap.test('abruptly ending strings throw', async t => { + const baseError = 'rdn string ends abruptly with character: ' + const tests = [ + { input: 'foo=bar+', expected: baseError + '+' }, + { input: 'foo=bar,', expected: baseError + ',' }, + { input: 'foo=bar;', expected: baseError + ';' } + ] + for (const test of tests) { + t.throws(() => parseString(test.input), test.expected) + } +}) + +tap.test('adds rdn with trailing whitespace', async t => { + const input = 'foo=bar ' + const result = parseString(input) + t.same(result, [{ foo: 'bar' }]) +}) + +tap.test('parses rdn with attribute name in OID form', async t => { + const input = '0.9.2342.19200300.100.1.25=Example' + const result = parseString(input) + t.same(result, [{ '0.9.2342.19200300.100.1.25': 'Example' }]) +}) + +tap.test('throws for invalid attribute type name', async t => { + let input = '3foo=bar' + t.throws( + () => parseString(input), + 'invalid attribute type name: 3foo' + ) + + input = '1.2.3.abc=bar' + t.throws( + () => parseString(input), + 'invalid attribute type name: 1.2.3.abc=bar' + ) + + input = 'føø=bar' + t.throws( + () => parseString(input), + 'invalid attribute type name: føø' + ) +}) + +tap.test('throws for abrupt end', async t => { + const input = 'foo=bar,' + t.throws( + () => parseString(input), + 'rdn string ends abruptly with character: ,' + ) +}) + +tap.test('rfc 4514 §4 examples', async t => { + const tests = [ + { + input: 'UID=jsmith,DC=example,DC=net', + expected: [{ UID: 'jsmith' }, { DC: 'example' }, { DC: 'net' }] + }, + { + input: 'OU=Sales+CN=J. Smith,DC=example,DC=net', + expected: [ + { OU: 'Sales', CN: 'J. Smith' }, + { DC: 'example' }, + { DC: 'net' } + ] + }, + { + input: 'CN=James \\"Jim\\" Smith\\, III,DC=example,DC=net', + expected: [{ CN: 'James "Jim" Smith, III' }, { DC: 'example' }, { DC: 'net' }] + }, + { + input: 'CN=Before\\0dAfter,DC=example,DC=net', + expected: [{ CN: 'Before\rAfter' }, { DC: 'example' }, { DC: 'net' }] + }, + { + checkBuffer: true, + input: '1.3.6.1.4.1.1466.0=#04024869', + expected: [{ '1.3.6.1.4.1.1466.0': new BerReader(Buffer.from([0x04, 0x02, 0x48, 0x69])) }] + }, + { + input: 'CN=Lu\\C4\\8Di\\C4\\87', + expected: [{ CN: 'Lučić' }] + } + ] + + for (const test of tests) { + const result = parseString(test.input) + if (test.checkBuffer) { + for (const [i, rdn] of test.expected.entries()) { + for (const key of Object.keys(rdn)) { + t.equal( + rdn[key].buffer.compare(result[i][key].buffer), + 0 + ) + } + } + } else { + t.same(result, test.expected) + } + } +}) + +tap.test('rfc 2253 §5 examples', async t => { + const tests = [ + { + input: 'CN=Steve Kille,O=Isode Limited,C=GB', + expected: [{ CN: 'Steve Kille' }, { O: 'Isode Limited' }, { C: 'GB' }] + }, + { + input: 'OU=Sales+CN=J. Smith,O=Widget Inc.,C=US', + expected: [{ OU: 'Sales', CN: 'J. Smith' }, { O: 'Widget Inc.' }, { C: 'US' }] + }, + { + input: 'CN=L. Eagle,O=Sue\\, Grabbit and Runn,C=GB', + expected: [{ CN: 'L. Eagle' }, { O: 'Sue, Grabbit and Runn' }, { C: 'GB' }] + }, + { + input: 'CN=Before\\0DAfter,O=Test,C=GB', + expected: [{ CN: 'Before\rAfter' }, { O: 'Test' }, { C: 'GB' }] + }, + { + checkBuffer: true, + input: '1.3.6.1.4.1.1466.0=#04024869,O=Test,C=GB', + expected: [ + { '1.3.6.1.4.1.1466.0': new BerReader(Buffer.from([0x04, 0x02, 0x48, 0x69])) }, + { O: 'Test' }, + { C: 'GB' } + ] + }, + { + input: 'SN=Lu\\C4\\8Di\\C4\\87', + expected: [{ SN: 'Lučić' }] + } + ] + + for (const test of tests) { + const result = parseString(test.input) + if (test.checkBuffer) { + for (const [i, rdn] of test.expected.entries()) { + for (const key of Object.keys(rdn)) { + if (typeof rdn[key] !== 'string') { + t.equal( + rdn[key].buffer.compare(result[i][key].buffer), + 0 + ) + } else { + t.equal(rdn[key], result[i][key]) + } + } + } + } else { + t.same(result, test.expected) + } + } +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/is-valid-attribute-type-name.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/is-valid-attribute-type-name.js new file mode 100644 index 0000000..af4d49d --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/is-valid-attribute-type-name.js @@ -0,0 +1,28 @@ +'use strict' + +const isDigit = c => /[0-9]/.test(c) === true +const hasKeyChars = input => /[a-zA-Z-]/.test(input) === true +const isValidLeadChar = c => /[a-zA-Z]/.test(c) === true +const hasInvalidChars = input => /[^a-zA-Z0-9-]/.test(input) === true + +/** + * An attribute type name is defined by RFC 4514 §3 as a "descr" or + * "numericoid". These are defined by RFC 4512 §1.4. This function validates + * the given name as matching the spec. + * + * @param {string} name + * + * @returns {boolean} + */ +module.exports = function isValidAttributeTypeName (name) { + if (isDigit(name[0]) === true) { + // A leading digit indicates that the name should be a numericoid. + return hasKeyChars(name) === false + } + + if (isValidLeadChar(name[0]) === false) { + return false + } + + return hasInvalidChars(name) === false +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/is-valid-attribute-type-name.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/is-valid-attribute-type-name.test.js new file mode 100644 index 0000000..01f903e --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/is-valid-attribute-type-name.test.js @@ -0,0 +1,36 @@ +'use strict' + +const tap = require('tap') +const isValidAttributeTypeName = require('./is-valid-attribute-type-name') + +tap.test('validates numericoids', async t => { + let input = '1.2.3.4' + let result = isValidAttributeTypeName(input) + t.equal(result, true) + + input = '1.2.3.4.abc' + result = isValidAttributeTypeName(input) + t.equal(result, false) +}) + +tap.test('validates descrs', async t => { + let input = 'foo' + let result = isValidAttributeTypeName(input) + t.equal(result, true) + + input = '3foo' + result = isValidAttributeTypeName(input) + t.equal(result, false) + + input = 'foo-3' + result = isValidAttributeTypeName(input) + t.equal(result, true) + + input = 'føø3' + result = isValidAttributeTypeName(input) + t.equal(result, false) + + input = 'ƒ00' + result = isValidAttributeTypeName(input) + t.equal(result, false) +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-pair.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-pair.js new file mode 100644 index 0000000..aaad85c --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-pair.js @@ -0,0 +1,73 @@ +'use strict' + +const findNameStart = require('./find-name-start') +const findNameEnd = require('./find-name-end') +const isValidAttributeTypeName = require('./is-valid-attribute-type-name') +const readAttributeValue = require('./read-attribute-value') + +/** + * @typedef {object} AttributePair + * @property {string | import('@ldapjs/asn1').BerReader} name Property name is + * actually the property name of the attribute pair. The value will be a string, + * or, in the case of the value being a hex encoded string, an instance of + * `BerReader`. + * + * @example + * const input = 'foo=bar' + * const pair = { foo: 'bar' } + */ + +/** + * @typedef {object} ReadAttributePairResult + * @property {number} endPos The ending position in the input search buffer that + * is the end of the read attribute pair. + * @property {AttributePair} pair The parsed attribute pair. + */ + +/** + * Read an RDN attribute type and attribute value pair from the provided + * search buffer at the given starting position. + * + * @param {Buffer} searchBuffer + * @param {number} startPos + * + * @returns {ReadAttributePairResult} + * + * @throws When there is some problem with the input string. + */ +module.exports = function readAttributePair ({ searchBuffer, startPos }) { + let pos = startPos + + const nameStartPos = findNameStart({ + searchBuffer, + startPos: pos + }) + if (nameStartPos < 0) { + throw Error('invalid attribute name leading character encountered') + } + + const nameEndPos = findNameEnd({ + searchBuffer, + startPos: nameStartPos + }) + if (nameStartPos < 0) { + throw Error('invalid character in attribute name encountered') + } + + const attributeName = searchBuffer.subarray(nameStartPos, nameEndPos).toString('utf8') + if (isValidAttributeTypeName(attributeName) === false) { + throw Error('invalid attribute type name: ' + attributeName) + } + + const valueReadResult = readAttributeValue({ + searchBuffer, + startPos: nameEndPos + }) + pos = valueReadResult.endPos + const attributeValue = valueReadResult.value + + return { + endPos: pos, + pair: { [attributeName]: attributeValue } + } +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-value.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-value.js new file mode 100644 index 0000000..2b863e9 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-value.js @@ -0,0 +1,165 @@ +'use strict' + +const readHexString = require('./read-hex-string') +const readEscapeSequence = require('./read-escape-sequence') + +/** + * @typedef {object} ReadAttributeValueResult + * @property {number} endPos The position in the buffer that marks the end of + * the value. + * @property {string | import('@ldapjs/asn1').BerReader} value + */ + +/** + * Read an attribute value string from a given {@link Buffer} and return it. + * If the value is an encoded octet string, it will be decoded and returned + * as a {@link Buffer}. + * + * @param {Buffer} searchBuffer + * @param {number} startPos + * + * @returns {ReadAttributeValueResult} + * + * @throws When there is a syntax error in the attribute value string. + */ +module.exports = function readAttributeValue ({ searchBuffer, startPos }) { + let pos = startPos + + while (pos < searchBuffer.byteLength && searchBuffer[pos] === 0x20) { + // Skip over any leading whitespace before the '='. + pos += 1 + } + + if (pos >= searchBuffer.byteLength || searchBuffer[pos] !== 0x3d) { + throw Error('attribute value does not start with equals sign') + } + + // Advance past the equals sign. + pos += 1 + while (pos <= searchBuffer.byteLength && searchBuffer[pos] === 0x20) { + // Advance past any leading whitespace. + pos += 1 + } + + if (pos >= searchBuffer.byteLength) { + return { endPos: pos, value: '' } + } + + if (searchBuffer[pos] === 0x23) { + const result = readHexString({ searchBuffer, startPos: pos + 1 }) + pos = result.endPos + return { endPos: pos, value: result.berReader } + } + + const readValueResult = readValueString({ searchBuffer, startPos: pos }) + pos = readValueResult.endPos + return { + endPos: pos, + value: readValueResult.value.toString('utf8').trim() + } +} + +/** + * @typedef {object} ReadValueStringResult + * @property {number} endPos + * @property {Buffer} value + * @private + */ + +/** + * Read a series of bytes from the buffer as a plain string. + * + * @param {Buffer} searchBuffer + * @param {number} startPos + * + * @returns {ReadValueStringResult} + * + * @throws When the attribute value is malformed. + * + * @private + */ +function readValueString ({ searchBuffer, startPos }) { + let pos = startPos + let inQuotes = false + let endQuotePresent = false + + const bytes = [] + while (pos <= searchBuffer.byteLength) { + const char = searchBuffer[pos] + + if (pos === searchBuffer.byteLength) { + if (inQuotes === true && endQuotePresent === false) { + throw Error('missing ending double quote for attribute value') + } + break + } + + if (char === 0x22) { + // Handle the double quote (") character. + // RFC 2253 §4 allows for attribute values to be wrapped in double + // quotes in order to allow certain characters to be unescaped. + // We are not enforcing escaping of characters in this parser, so we only + // need to recognize that the quotes are present. Our RDN string encoder + // will escape characters as necessary. + if (inQuotes === true) { + pos += 1 + endQuotePresent = true + + // We should be at the end of the value. + while (pos < searchBuffer.byteLength) { + const nextChar = searchBuffer[pos] + if (isEndChar(nextChar) === true) { + break + } + if (nextChar !== 0x20) { + throw Error('significant rdn character found outside of quotes at position ' + pos) + } + pos += 1 + } + + break + } + + if (pos !== startPos) { + throw Error('unexpected quote (") in rdn string at position ' + pos) + } + inQuotes = true + pos += 1 + continue + } + + if (isEndChar(char) === true && inQuotes === false) { + break + } + + if (char === 0x5c) { + // We have encountered the start of an escape sequence. + const seqResult = readEscapeSequence({ + searchBuffer, + startPos: pos + }) + pos = seqResult.endPos + Array.prototype.push.apply(bytes, seqResult.parsed) + continue + } + + bytes.push(char) + pos += 1 + } + + return { + endPos: pos, + value: Buffer.from(bytes) + } +} + +function isEndChar (c) { + switch (c) { + case 0x2b: // + + case 0x2c: // , + case 0x3b: // ; -- Allowed by RFC 2253 §4 in place of a comma. + return true + default: + return false + } +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-value.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-value.test.js new file mode 100644 index 0000000..55d25eb --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-attribute-value.test.js @@ -0,0 +1,119 @@ +'use strict' + +const tap = require('tap') +const readAttributeValue = require('./read-attribute-value') +const { BerReader } = require('@ldapjs/asn1') + +const missingError = Error('attribute value does not start with equals sign') + +tap.test('throws if missing equals sign', async t => { + let input = Buffer.from('foo') + t.throws( + () => readAttributeValue({ searchBuffer: input, startPos: 3 }), + missingError + ) + + input = Buffer.from('foo ≠') + t.throws( + () => readAttributeValue({ searchBuffer: input, startPos: 3 }), + missingError + ) +}) + +tap.test('handles empty attribute value', async t => { + const input = Buffer.from('foo=') + const result = readAttributeValue({ searchBuffer: input, startPos: 3 }) + t.same(result, { endPos: 4, value: '' }) +}) + +tap.test('returns attribute value', async t => { + const input = Buffer.from('foo=bar') + const result = readAttributeValue({ searchBuffer: input, startPos: 3 }) + t.same(result, { endPos: 7, value: 'bar' }) +}) + +tap.test('quoted values', t => { + t.test('throws if quote is unexpected', async t => { + const input = Buffer.from('=foo"bar') + t.throws( + () => readAttributeValue({ searchBuffer: input, startPos: 0 }), + 'unexpected quote (") in rdn string at position 4' + ) + }) + + t.test('handles a basic quoted value', async t => { + const input = Buffer.from('="bar"') + const result = readAttributeValue({ searchBuffer: input, startPos: 0 }) + t.same(result, { endPos: 6, value: 'bar' }) + }) + + t.test('handles quote followed by end char', async t => { + const input = Buffer.from('="bar",another=rdn') + const result = readAttributeValue({ searchBuffer: input, startPos: 0 }) + t.same(result, { endPos: 6, value: 'bar' }) + }) + + t.test('significant spaces in quoted values are part of the value', async t => { + const input = Buffer.from('="foo bar "') + const result = readAttributeValue({ searchBuffer: input, startPos: 0 }) + t.same(result, { endPos: 13, value: 'foo bar' }) + }) + + t.test('throws if next significant char is not an end char', async t => { + const input = Buffer.from('="foo bar" baz') + t.throws( + () => readAttributeValue({ searchBuffer: input, startPos: 0 }), + 'significant rdn character found outside of quotes at position 7' + ) + }) + + t.test('throws if ending quote not found', async t => { + const input = Buffer.from('="foo') + t.throws( + () => readAttributeValue({ searchBuffer: input, startPos: 0 }), + 'missing ending double quote for attribute value' + ) + }) + + t.end() +}) + +tap.test('leading and trailing spaces are omitted', async t => { + const input = Buffer.from('= foo ') + const result = readAttributeValue({ searchBuffer: input, startPos: 0 }) + t.same(result, { endPos: 9, value: 'foo' }) +}) + +tap.test('parses escaped attribute values', async t => { + const input = Buffer.from('foo=foo\\#bar') + const result = readAttributeValue({ searchBuffer: input, startPos: 3 }) + t.same(result, { endPos: 12, value: 'foo#bar' }) +}) + +tap.test('stops reading at all ending characters', async t => { + const tests = [ + { input: '=foo,bar', expected: { endPos: 4, value: 'foo' } }, + { input: '=foo+bar', expected: { endPos: 4, value: 'foo' } }, + { input: '=foo;bar', expected: { endPos: 4, value: 'foo' } } + ] + + for (const test of tests) { + const result = readAttributeValue({ + searchBuffer: Buffer.from(test.input), + startPos: 0 + }) + t.same(result, test.expected) + } +}) + +tap.test('reads hex encoded string', async t => { + const input = Buffer.from('=#0403666f6f') + const result = readAttributeValue({ searchBuffer: input, startPos: 0 }) + const expected = { + endPos: 12, + value: new BerReader(Buffer.from([0x04, 0x03, 0x66, 0x6f, 0x6f])) + } + + t.same(result, expected) + t.equal(result.value.buffer.compare(expected.value.buffer), 0) +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.js new file mode 100644 index 0000000..706f7f3 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.js @@ -0,0 +1,137 @@ +'use strict' + +/** + * @typedef ReadEscapeSequenceResult + * @property {number} endPos The position in the buffer that marks the end of + * the escape sequence. + * @property {Buffer} parsed The parsed escape sequence as a buffer of bytes. + */ + +/** + * Read an escape sequence from a buffer. It reads until no escape sequences + * are found. Thus, a sequence of escape sequences will all be parsed at once + * and returned as a single result. + * + * @example A Single ASCII Sequence + * const toParse = Buffer.from('foo\\#bar', 'utf8') + * const {parsed, endPos} = readEscapeSequence({ + * searchBuffer: toParse, + * startPos: 3 + * }) + * // => parsed = '#', endPos = 5 + * + * @example Multiple ASCII Sequences In Succession + * const toParse = Buffer.from('foo\\#\\!bar', 'utf8') + * const {parsed, endPos} = readEscapeSequence({ + * searchBuffer: toParse, + * startPos: 3 + * }) + * // => parsed = '#!', endPos = 7 + * + * @param searchBuffer + * @param startPos + * + * @returns {ReadEscapeSequenceResult} + * + * @throws When an escaped sequence is not a valid hexadecimal value. + */ +module.exports = function readEscapeSequence ({ searchBuffer, startPos }) { + // This is very similar to the `readEscapedCharacters` algorithm in + // the `utils/escape-filter-value` in `@ldapjs/filter`. The difference being + // that here we want to interpret the escape sequence instead of return it + // as a string to be embedded in an "escaped" string. + // https://github.com/ldapjs/filter/blob/1423612/lib/utils/escape-filter-value.js + + let pos = startPos + const buf = [] + + while (pos < searchBuffer.byteLength) { + const char = searchBuffer[pos] + const nextChar = searchBuffer[pos + 1] + + if (char !== 0x5c) { + // End of sequence reached. + break + } + + const strHexCode = String.fromCharCode(nextChar) + + String.fromCharCode(searchBuffer[pos + 2]) + const hexCode = parseInt(strHexCode, 16) + if (Number.isNaN(hexCode) === true) { + if (nextChar >= 0x00 && nextChar <= 0x7f) { + // Sequence is a single escaped ASCII character + buf.push(nextChar) + pos += 2 + continue + } else { + throw Error('invalid hex code in escape sequence') + } + } + + if (hexCode >= 0xc0 && hexCode <= 0xdf) { + // Sequence is a 2-byte utf-8 character. + const secondByte = parseInt( + String.fromCharCode(searchBuffer[pos + 4]) + + String.fromCharCode(searchBuffer[pos + 5]), + 16 + ) + buf.push(hexCode) + buf.push(secondByte) + pos += 6 + continue + } + + if (hexCode >= 0xe0 && hexCode <= 0xef) { + // Sequence is a 3-byte utf-8 character. + const secondByte = parseInt( + String.fromCharCode(searchBuffer[pos + 4]) + + String.fromCharCode(searchBuffer[pos + 5]), + 16 + ) + const thirdByte = parseInt( + String.fromCharCode(searchBuffer[pos + 7]) + + String.fromCharCode(searchBuffer[pos + 8]), + 16 + ) + buf.push(hexCode) + buf.push(secondByte) + buf.push(thirdByte) + pos += 9 + continue + } + + if (hexCode >= 0xf0 && hexCode <= 0xf7) { + // Sequence is a 4-byte utf-8 character. + const secondByte = parseInt( + String.fromCharCode(searchBuffer[pos + 4]) + + String.fromCharCode(searchBuffer[pos + 5]), + 16 + ) + const thirdByte = parseInt( + String.fromCharCode(searchBuffer[pos + 7]) + + String.fromCharCode(searchBuffer[pos + 8]), + 16 + ) + const fourthByte = parseInt( + String.fromCharCode(searchBuffer[pos + 10]) + + String.fromCharCode(searchBuffer[pos + 11]), + 16 + ) + buf.push(hexCode) + buf.push(secondByte) + buf.push(thirdByte) + buf.push(fourthByte) + pos += 12 + continue + } + + // The escaped character should be a single hex value. + buf.push(hexCode) + pos += 3 + } + + return { + endPos: pos, + parsed: Buffer.from(buf) + } +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.test.js new file mode 100644 index 0000000..362c8dd --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-escape-sequence.test.js @@ -0,0 +1,72 @@ +'use strict' + +const tap = require('tap') +const readEscapeSequence = require('./read-escape-sequence') + +tap.test('throws for bad sequence', async t => { + const input = Buffer.from('foo\\ø') + t.throws( + () => readEscapeSequence({ searchBuffer: input, startPos: 3 }), + Error('invalid hex code in escape sequence') + ) +}) + +tap.test('reads a single ascii sequence', async t => { + const input = Buffer.from('foo\\#bar', 'utf8') + const { parsed, endPos } = readEscapeSequence({ + searchBuffer: input, + startPos: 3 + }) + t.equal(parsed.toString(), '#') + t.equal(endPos, 5) +}) + +tap.test('reads a sequence of ascii sequences', async t => { + const input = Buffer.from('foo\\#\\!bar', 'utf8') + const { parsed, endPos } = readEscapeSequence({ + searchBuffer: input, + startPos: 3 + }) + t.equal(parsed.toString(), '#!') + t.equal(endPos, 7) +}) + +tap.test('reads a single hex sequence', async t => { + const input = Buffer.from('foo\\2abar', 'utf8') + const { parsed, endPos } = readEscapeSequence({ + searchBuffer: input, + startPos: 3 + }) + t.equal(parsed.toString(), '*') + t.equal(endPos, 6) +}) + +tap.test('reads 2-byte utf-8 sequence', async t => { + const input = Buffer.from('fo\\c5\\8f bar') + const { parsed, endPos } = readEscapeSequence({ + searchBuffer: input, + startPos: 2 + }) + t.equal(parsed.toString(), 'ŏ') + t.equal(endPos, 8) +}) + +tap.test('reads 3-byte utf-8 sequence', async t => { + const input = Buffer.from('fo\\e0\\b0\\b0 bar') + const { parsed, endPos } = readEscapeSequence({ + searchBuffer: input, + startPos: 2 + }) + t.equal(parsed.toString(), 'ర') + t.equal(endPos, 11) +}) + +tap.test('reads 4-byte utf-8 sequence', async t => { + const input = Buffer.from('fo\\f0\\92\\84\\ad bar') + const { parsed, endPos } = readEscapeSequence({ + searchBuffer: input, + startPos: 2 + }) + t.equal(parsed.toString(), '𒄭') + t.equal(endPos, 14) +}) diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-hex-string.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-hex-string.js new file mode 100644 index 0000000..2894042 --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-hex-string.js @@ -0,0 +1,61 @@ +'use strict' + +const { BerReader } = require('@ldapjs/asn1') + +const isValidHexCode = code => /[0-9a-fA-F]{2}/.test(code) === true + +/** + * @typedef {object} ReadHexStringResult + * @property {number} endPos The position in the buffer where the end of the + * hex string was encountered. + * @property {import('@ldapjs/asn1').BerReader} berReader The parsed hex string + * as an BER object. + */ + +/** + * Read a sequence of bytes as a hex encoded octet string. The sequence is + * assumed to be a spec compliant encoded BER object. + * + * @param {Buffer} searchBuffer The buffer to read. + * @param {number} startPos The position in the buffer to start reading from. + * + * @returns {ReadHexStringResult} + * + * @throws When an invalid hex pair has been encountered. + */ +module.exports = function readHexString ({ searchBuffer, startPos }) { + const bytes = [] + + let pos = startPos + while (pos < searchBuffer.byteLength) { + if (isEndChar(searchBuffer[pos])) { + break + } + + const hexPair = String.fromCharCode(searchBuffer[pos]) + + String.fromCharCode(searchBuffer[pos + 1]) + if (isValidHexCode(hexPair) === false) { + throw Error('invalid hex pair encountered: 0x' + hexPair) + } + + bytes.push(parseInt(hexPair, 16)) + pos += 2 + } + + return { + endPos: pos, + berReader: new BerReader(Buffer.from(bytes)) + } +} + +function isEndChar (c) { + switch (c) { + case 0x20: // space + case 0x2b: // + + case 0x2c: // , + case 0x3b: // ; + return true + default: + return false + } +} diff --git a/node_modules/@ldapjs/dn/lib/utils/parse-string/read-hex-string.test.js b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-hex-string.test.js new file mode 100644 index 0000000..57fcf4d --- /dev/null +++ b/node_modules/@ldapjs/dn/lib/utils/parse-string/read-hex-string.test.js @@ -0,0 +1,52 @@ +'use strict' + +const tap = require('tap') +const readHexString = require('./read-hex-string') + +tap.test('throws for invalid hex pair', async t => { + let input = Buffer.from('1z2f') + t.throws( + () => readHexString({ searchBuffer: input, startPos: 0 }), + 'invalid hex pair encountered: 0x1z' + ) + + input = Buffer.from('a0b1g692') + t.throws( + () => readHexString({ searchBuffer: input, startPos: 0 }), + 'invalid hex pair encountered: 0xg6' + ) +}) + +tap.test('handles incorrect length string', async t => { + const input = Buffer.from('a1b') + t.throws( + () => readHexString({ searchBuffer: input, startPos: 0 }), + 'invalid hex pair encountered: 0xb' + ) +}) + +tap.test('reads hex string', async t => { + let input = Buffer.from('0403666f6f') + let result = readHexString({ searchBuffer: input, startPos: 0 }) + t.equal(result.endPos, 10) + t.equal(result.berReader.readString(), 'foo') + + input = Buffer.from('uid=#0409746573742E75736572') + result = readHexString({ searchBuffer: input, startPos: 5 }) + t.equal(result.endPos, input.byteLength) + t.equal(result.berReader.readString(), 'test.user') +}) + +tap.test('stops on end chars', async t => { + const inputs = [ + Buffer.from('0403666f6f foo'), + Buffer.from('0403666f6f+foo'), + Buffer.from('0403666f6f,foo'), + Buffer.from('0403666f6f;foo') + ] + for (const input of inputs) { + const result = readHexString({ searchBuffer: input, startPos: 0 }) + t.equal(result.endPos, 10) + t.equal(result.berReader.readString(), 'foo') + } +}) diff --git a/node_modules/@ldapjs/dn/package.json b/node_modules/@ldapjs/dn/package.json new file mode 100644 index 0000000..626f6d1 --- /dev/null +++ b/node_modules/@ldapjs/dn/package.json @@ -0,0 +1,43 @@ +{ + "originalAuthor": "Patrick Mooney", + "originalContributors": [ + "Mark Cavage ", + "Cody Peter Mello " + ], + "name": "@ldapjs/dn", + "homepage": "https://github.com/ldapjs/dn", + "description": "API for handling LDAP distinguished name strings", + "version": "1.1.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:ldapjs/dn.git" + }, + "main": "index.js", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "process-warning": "^2.1.0" + }, + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.34.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.4" + }, + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report", + "test:cov": "tap", + "test:cov:html": "tap --coverage-report=html", + "test:watch": "tap -w --no-coverage-report" + }, + "precommit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/filter/.eslintrc b/node_modules/@ldapjs/filter/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/filter/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/filter/.github/workflows/main.yml b/node_modules/@ldapjs/filter/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/filter/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/filter/.taprc.yaml b/node_modules/@ldapjs/filter/.taprc.yaml new file mode 100644 index 0000000..7591538 --- /dev/null +++ b/node_modules/@ldapjs/filter/.taprc.yaml @@ -0,0 +1,10 @@ +reporter: terse +coverage-map: coverage-map.js + +lines: 90 +functions: 80 +branches: 85 +statements: 90 + +files: + - 'lib/**/*.test.js' diff --git a/node_modules/@ldapjs/filter/CHANGES.md b/node_modules/@ldapjs/filter/CHANGES.md new file mode 100644 index 0000000..2f92b54 --- /dev/null +++ b/node_modules/@ldapjs/filter/CHANGES.md @@ -0,0 +1,54 @@ +# ldap-filter + +> ### Important +> This file is no longer maintained. For changes, please read +> the releases page: https://github.com/ldapjs/filter/releases + +## 0.3.3 + +- Assert that NOT filters are closed by a parentheses + +## 0.3.2 + +- Perform better checks for trailing characters +- Improve test coverage +- Change \*Filter.json to work recursively for child filters +- Bump assert-plus dependency to 1.0.0 + +## 0.3.1 + +- Tolerate underscores in attribute names + +## 0.3.0 + +- Enforce stricter output escaping for buffer values +- **BREAKING** Rename `NotFilter.addfilter` to `NotFilter.setFilter` +- **BREAKING** Rewrite filter parser to be more strict about input. + This _significantly_ changes the sort of filters which the parser files + acceptable. While the old parser would tolerate unescaped characters in + the `()\*` set, the new parser requires them to be escaped via the `\XX` + hex notation. This is in keeping with + [RFC 4514](http://tools.ietf.org/search/rfc4515) +- Perform better escaping for values which are not UTF-8 + +## 0.2.3 +- Update dev dependencies +- Clean up asserts and prototypes + +## 0.2.2 + +- Fix nested paren handling in parser + +## 0.2.1 + +- Fix AndFilter per RFC4526 + +## 0.2.0 + +- Add 'attribute' accessor for ExtFilter matchType +- Improve API for custom match functions +- Support other value types in EqualityFilter + +## 0.1.0 + +- Initial import from ldapjs diff --git a/node_modules/@ldapjs/filter/LICENSE b/node_modules/@ldapjs/filter/LICENSE new file mode 100644 index 0000000..923d87e --- /dev/null +++ b/node_modules/@ldapjs/filter/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Patrick Mooney. All rights reserved. +Copyright (c) 2014 Mark Cavage, Inc. All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/filter/README.md b/node_modules/@ldapjs/filter/README.md new file mode 100644 index 0000000..5705a4b --- /dev/null +++ b/node_modules/@ldapjs/filter/README.md @@ -0,0 +1,8 @@ +# ldap-filter + +Provides methods for representing and working with LDAP filter +strings as defined by [RFC 4515](https://datatracker.ietf.org/doc/html/rfc4515). + +## License + +MIT. diff --git a/node_modules/@ldapjs/filter/coverage-map.js b/node_modules/@ldapjs/filter/coverage-map.js new file mode 100644 index 0000000..fc2046a --- /dev/null +++ b/node_modules/@ldapjs/filter/coverage-map.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = testFile => testFile.replace(/\.test\.js$/, '.js') diff --git a/node_modules/@ldapjs/filter/lib/ber-parsing/Readme.md b/node_modules/@ldapjs/filter/lib/ber-parsing/Readme.md new file mode 100644 index 0000000..fb85cac --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/ber-parsing/Readme.md @@ -0,0 +1,39 @@ +The code in this directory implements parsing of BER encoded representations +of LDAP filters as defined in https://datatracker.ietf.org/doc/html/rfc4515#section-2. +In short, it decodes messages according to the ASN.1: + +``` +Filter ::= CHOICE { + and [0] SET OF Filter, + or [1] SET OF Filter, + not [2] Filter, + equalityMatch [3] AttributeValueAssertion, + substrings [4] SubstringFilter, + greaterOrEqual [5] AttributeValueAssertion, + lessOrEqual [6] AttributeValueAssertion, + present [7] AttributeType, + approxMatch [8] AttributeValueAssertion, + extensibleMatch [9] MatchingRuleAssertion --v3 only +} +SubstringFilter ::= SEQUENCE { + type AttributeType, + SEQUENCE OF CHOICE { + initial [0] IA5String, + any [1] IA5String, + final [2] IA5String + } +} +``` + +Along with the `extensibleMatch` that was added in LDAPv3: + +``` +MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleID OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE +} +``` + +Remember: the bracketed numbers represent the context specific tag identifier. diff --git a/node_modules/@ldapjs/filter/lib/ber-parsing/_fixtures/evolution-filter.js b/node_modules/@ldapjs/filter/lib/ber-parsing/_fixtures/evolution-filter.js new file mode 100644 index 0000000..104b677 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/ber-parsing/_fixtures/evolution-filter.js @@ -0,0 +1,445 @@ +'use strict' + +const fs = require('fs') +const path = require('path') + +const text = fs.readFileSync(path.join(__dirname, 'evolution-filter.txt')) + .toString('utf8') + .replace(/(\s+)\(/g, '(') + .replace(/\s\)/, ')') + .replaceAll('\n', '') + +/** + * This is the byte representation of the filter defined in + * `evolution-filter.txt`. Said filter is part of the original "laundry.test" + * suite in the `node-ldapjs` code (through at least `ldapjs@2`). + * + * @type {Buffer} + */ +const bytes = Buffer.from([ + 0xa1, 0x82, 0x04, 0xa3, // sequence, 1187 bytes (OR filter: 0xa1, length: 0x04a3) + + 0xa4, 0x0b, // substring filter, 11 bytes + 0x04, 0x02, // string, 2 bytes + // "cn" + 0x63, 0x6e, + 0x30, 0x05, // sequence, 5 bytes + 0x80, 0x03, // initial string, 3 bytes + // "ogo" + 0x6f, 0x67, 0x6f, + + 0xa4, 0x12, // substring filter, 18 bytes + 0x04, 0x09, // string 9 bytes + // "givenname" + 0x67, 0x69, 0x76, 0x65, 0x6e, 0x6e, 0x61, 0x6d, 0x65, + 0x30, 0x05, // sequence, 5 bytes + 0x80, 0x03, // string, 3 bytes + // "ogo" + 0x6f, 0x67, 0x6f, + + // The above pattern repeats for all of the clauses in the + // filter. Each pattern is chunked below as above, but not commented. + + 0xa4, 0x0b, + 0x04, 0x02, + 0x73, 0x6e, + 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, + + 0xa4, 0x0d, + 0x04, 0x04, + 0x6d, 0x61, 0x69, 0x6c, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0f, + 0x04, 0x06, + 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x15, + 0x04, 0x0c, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x18, + 0x04, 0x0f, + 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x12, + 0x04, 0x09, + 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0f, + 0x04, 0x06, + 0x6d, 0x6f, 0x62, 0x69, 0x6c, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x11, + 0x04, 0x08, + 0x63, 0x61, 0x72, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x21, + 0x04, 0x18, + 0x66, 0x61, 0x63, 0x73, 0x69, + 0x6d, 0x69, 0x6c, 0x65, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x25, + 0x04, 0x1c, + 0x68, 0x6f, 0x6d, 0x65, 0x66, + 0x61, 0x63, 0x73, 0x69, 0x6d, + 0x69, 0x6c, 0x65, 0x74, 0x65, + 0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x13, + 0x04, 0x0a, + 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x26, + 0x04, 0x1d, + 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x73, 0x69, + 0x6d, 0x69, 0x6c, 0x65, 0x74, + 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, + + 0xa4, 0x20, + 0x04, 0x17, + 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x69, 0x73, + 0x64, 0x6e, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0e, + 0x04, 0x05, + 0x70, 0x61, 0x67, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0e, + 0x04, 0x05, + 0x72, 0x61, 0x64, 0x69, 0x6f, + 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, + + 0xa4, 0x0e, + 0x04, 0x05, + 0x74, 0x65, 0x6c, 0x65, 0x78, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x17, + 0x04, 0x0e, 0x61, 0x73, 0x73, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x70, 0x68, 0x6f, + 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x15, + 0x04, 0x0c, + 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, + 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x16, + 0x04, 0x0d, + 0x63, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x70, 0x68, 0x6f, 0x6e, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0c, + 0x04, 0x03, + 0x74, 0x74, 0x79, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0a, + 0x04, 0x01, + 0x6f, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0b, + 0x04, 0x02, + 0x6f, 0x75, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x13, + 0x04, 0x0a, + 0x72, + 0x6f, 0x6f, 0x6d, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0e, + 0x04, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x15, + 0x04, 0x0c, + 0x62, 0x75, 0x73, 0x69, + 0x6e, 0x65, 0x73, 0x73, 0x72, 0x6f, 0x6c, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x14, + 0x04, 0x0b, + 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x16, + 0x04, 0x0d, + 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x6e, 0x61, 0x6d, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x16, + 0x04, 0x0d, + 0x70, 0x6f, 0x73, 0x74, 0x61, + 0x6c, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0a, + 0x04, 0x01, + 0x6c, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0b, + 0x04, 0x02, + 0x73, 0x74, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x16, + 0x04, 0x0d, + 0x70, 0x6f, 0x73, 0x74, 0x6f, 0x66, + 0x66, 0x69, 0x63, 0x65, 0x62, 0x6f, 0x78, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x13, + 0x04, 0x0a, + 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x63, 0x6f, 0x64, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0a, + 0x04, 0x01, + 0x63, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x1a, + 0x04, 0x11, + 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x61, + 0x6c, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x20, + 0x04, 0x17, + 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x68, 0x6f, 0x6d, 0x65, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x6e, 0x61, + 0x6d, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x19, + 0x04, 0x10, + 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, + 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x1e, + 0x04, 0x15, + 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x68, 0x6f, 0x6d, + 0x65, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x63, 0x6f, 0x64, + 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x1f, + 0x04, 0x16, + 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x68, + 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, + 0x6e, 0x61, 0x6d, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x1b, + 0x04, 0x12, + 0x6f, 0x74, 0x68, 0x65, 0x72, + 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x12, + 0x04, 0x09, + 0x6a, 0x70, 0x65, 0x67, 0x70, 0x68, + 0x6f, 0x74, 0x6f, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x18, + 0x04, 0x0f, 0x75, 0x73, 0x65, 0x72, 0x63, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x13, + 0x04, 0x0a, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, 0x75, 0x72, 0x69, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x14, + 0x04, 0x0b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x6e, 0x61, + 0x6d, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x13, + 0x04, 0x0a, + 0x73, 0x70, 0x6f, 0x75, 0x73, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x0d, 0x04, 0x04, 0x6e, 0x6f, 0x74, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x14, + 0x04, 0x0b, + 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x72, 0x79, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x12, + 0x04, 0x09, + 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, 0x61, 0x74, 0x65, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0f, + 0x04, 0x06, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x0f, + 0x04, 0x06, + 0x66, 0x69, 0x6c, 0x65, 0x61, 0x73, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x11, + 0x04, 0x08, + 0x63, 0x61, 0x74, 0x65, 0x67, + 0x6f, 0x72, 0x79, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x12, + 0x04, 0x09, + 0x63, 0x61, 0x6c, 0x63, 0x61, 0x6c, + 0x75, 0x72, 0x69, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x11, + 0x04, 0x08, + 0x63, 0x61, 0x6c, 0x66, 0x62, 0x75, + 0x72, 0x6c, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f, + + 0xa4, 0x14, + 0x04, 0x0b, + 0x69, 0x63, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x6e, 0x64, 0x61, 0x72, + 0x30, 0x05, + 0x80, 0x03, + 0x6f, 0x67, 0x6f +]) + +module.exports = { text, bytes } diff --git a/node_modules/@ldapjs/filter/lib/ber-parsing/_fixtures/evolution-filter.txt b/node_modules/@ldapjs/filter/lib/ber-parsing/_fixtures/evolution-filter.txt new file mode 100644 index 0000000..5fcaf07 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/ber-parsing/_fixtures/evolution-filter.txt @@ -0,0 +1,57 @@ +(| + (cn=ogo*) + (givenname=ogo*) + (sn=ogo*) + (mail=ogo*) + (member=ogo*) + (primaryphone=ogo*) + (telephonenumber=ogo*) + (homephone=ogo*) + (mobile=ogo*) + (carphone=ogo*) + (facsimiletelephonenumber=ogo*) + (homefacsimiletelephonenumber=ogo*) + (otherphone=ogo*) + (otherfacsimiletelephonenumber=ogo*) + (internationalisdnnumber=ogo*) + (pager=ogo*) + (radio=ogo*) + (telex=ogo*) + (assistantphone=ogo*) + (companyphone=ogo*) + (callbackphone=ogo*) + (tty=ogo*) + (o=ogo*) + (ou=ogo*) + (roomnumber=ogo*) + (title=ogo*) + (businessrole=ogo*) + (managername=ogo*) + (assistantname=ogo*) + (postaladdress=ogo*) + (l=ogo*) + (st=ogo*) + (postofficebox=ogo*) + (postalcode=ogo*) + (c=ogo*) + (homepostaladdress=ogo*) + (mozillahomelocalityname=ogo*) + (mozillahomestate=ogo*) + (mozillahomepostalcode=ogo*) + (mozillahomecountryname=ogo*) + (otherpostaladdress=ogo*) + (jpegphoto=ogo*) + (usercertificate=ogo*) + (labeleduri=ogo*) + (displayname=ogo*) + (spousename=ogo*) + (note=ogo*) + (anniversary=ogo*) + (birthdate=ogo*) + (mailer=ogo*) + (fileas=ogo*) + (category=ogo*) + (calcaluri=ogo*) + (calfburl=ogo*) + (icscalendar=ogo*) +) diff --git a/node_modules/@ldapjs/filter/lib/ber-parsing/index.js b/node_modules/@ldapjs/filter/lib/ber-parsing/index.js new file mode 100644 index 0000000..ef57f92 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/ber-parsing/index.js @@ -0,0 +1,102 @@ +'use strict' + +const { search } = require('@ldapjs/protocol') + +const FILTERS = { + [search.FILTER_AND]: require('../filters/and'), + [search.FILTER_APPROX]: require('../filters/approximate'), + [search.FILTER_EQUALITY]: require('../filters/equality'), + [search.FILTER_EXT]: require('../filters/extensible'), + [search.FILTER_GE]: require('../filters/greater-than-equals'), + [search.FILTER_LE]: require('../filters/less-than-equals'), + [search.FILTER_NOT]: require('../filters/not'), + [search.FILTER_OR]: require('../filters/or'), + [search.FILTER_PRESENT]: require('../filters/presence'), + [search.FILTER_SUBSTRINGS]: require('../filters/substring') +} + +/** + * Reads a buffer that is encoded BER data and returns the appropriate + * filter that it represents. + * + * @param {BerReader} ber The BER buffer to parse. + * + * @returns {FilterString} + * + * @throws If input is not of correct type or there is an error is parsing. + */ +module.exports = function parseBer (ber) { + if (Object.prototype.toString.call(ber) !== '[object BerReader]') { + throw new TypeError('ber (BerReader) required') + } + + return _parse(ber) +} + +function _parse (ber) { + let f + + const filterStartOffset = ber.offset + const type = ber.readSequence() + switch (type) { + case search.FILTER_AND: + case search.FILTER_OR: { + f = new FILTERS[type]() + parseSet(f) + break + } + + case search.FILTER_NOT: { + const innerFilter = _parse(ber) + f = new FILTERS[type]({ filter: innerFilter }) + break + } + + case search.FILTER_APPROX: + case search.FILTER_EQUALITY: + case search.FILTER_EXT: + case search.FILTER_GE: + case search.FILTER_LE: + case search.FILTER_PRESENT: + case search.FILTER_SUBSTRINGS: { + f = FILTERS[type].parse(getBerBuffer(ber)) + break + } + + default: { + throw Error( + 'invalid search filter type: 0x' + type.toString(16).padStart(2, '0') + ) + } + } + + return f + + function parseSet (f) { + const end = ber.offset + ber.length + while (ber.offset < end) { + const parsed = _parse(ber) + f.addClause(parsed) + } + } + + function getBerBuffer (inputBer) { + // Since our new filter code does not allow "empty" constructors, + // we need to pass a BER into the filter's `.parse` method in order + // to get a new instance. In order to do that, we need to read the + // full BER section of the buffer for the filter. When we enter this + // function, the tag and length has already been read in order to determine + // what type of filter is being constructed. Since need those bytes to + // construct a valid TLV buffer, we must rewind the offset by 2 bytes. + ber.setOffset(filterStartOffset) + + // Next, we need the tag so that we can supply it to the raw buffer read + // method. + const tag = inputBer.peek() + + // We must advance the internal offset of the passed in BER here. + // Again, this is due to the original side effect reliant nature of + // ldapjs. + return inputBer.readRawBuffer(tag) + } +} diff --git a/node_modules/@ldapjs/filter/lib/ber-parsing/index.test.js b/node_modules/@ldapjs/filter/lib/ber-parsing/index.test.js new file mode 100644 index 0000000..d5e6030 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/ber-parsing/index.test.js @@ -0,0 +1,206 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const parse = require('./index') + +const AndFilter = require('../filters/and') +const ApproximateFilter = require('../filters/approximate') +const EqualityFilter = require('../filters/equality') +const ExtensibleFilter = require('../filters/extensible') +const GreaterThanEqualsFilter = require('../filters/greater-than-equals') +const LessThanEqualsFilter = require('../filters/less-than-equals') +const NotFilter = require('../filters/not') +const OrFilter = require('../filters/or') +const PresenceFilter = require('../filters/presence') +const SubstringFilter = require('../filters/substring') +const parseString = require('../string-parsing/parse-string') + +tap.test('throws if BerReader not supplied', async t => { + const expected = Error('ber (BerReader) required') + t.throws( + () => parse(), + expected + ) + t.throws( + () => parse({}), + expected + ) +}) + +tap.test('parses AndFilter', async t => { + const input = Buffer.from([ + 0xa0, 0x0c, 0xa3, 0x0a, // and tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, AndFilter) + t.equal(f.clauses.length, 1) + t.equal(f.toString(), '(&(foo=bar))') +}) + +tap.test('parses ApproximateFilter', async t => { + const input = Buffer.from([ + 0xa8, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, ApproximateFilter) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo~=bar)') +}) + +tap.test('parses EqualityFilter', async t => { + const input = Buffer.from([ + 0xa3, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, EqualityFilter) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo=bar)') +}) + +tap.test('parses ExtensibleFilter', async t => { + const fooArray = [0x03, 0x66, 0x6f, 0x6f] // length + string + const barArray = [0x03, 0x62, 0x61, 0x72] // length + string + const input = Buffer.from([ + 0xa9, 0x14, + 0x81, 0x05, 0x31, 0x2e, 0x32, 0x2e, 0x33, // OID 1.2.3 + 0x82, ...fooArray, // attribute + 0x83, ...barArray, // value + 0x84, 0x01, 0xff // dnAttributes + ]) + const f = parse(new BerReader(input)) + t.type(f, ExtensibleFilter) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.matchingRule, '1.2.3') + t.equal(f.dnAttributes, true) + t.equal(f.toString(), '(foo:dn:1.2.3:=bar)') +}) + +tap.test('parses GreaterThanEqualsFilter', async t => { + const input = Buffer.from([ + 0xa5, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, GreaterThanEqualsFilter) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo>=bar)') +}) + +tap.test('parses LessThanEqualsFilter', async t => { + const input = Buffer.from([ + 0xa6, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, LessThanEqualsFilter) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo<=bar)') +}) + +tap.test('parses NotFilter', async t => { + const input = Buffer.from([ + 0xa2, 0x0c, 0xa3, 0x0a, // not tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, NotFilter) + t.equal(f.toString(), '(!(foo=bar))') +}) + +tap.test('parses OrFilter', async t => { + const input = Buffer.from([ + 0xa1, 0x0c, 0xa3, 0x0a, // or tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, OrFilter) + t.equal(f.clauses.length, 1) + t.equal(f.toString(), '(|(foo=bar))') +}) + +tap.test('parses PresenceFilter', async t => { + const input = Buffer.from([0x87, 0x03, 0x66, 0x6f, 0x6f]) + const f = parse(new BerReader(input)) + t.type(f, PresenceFilter) + t.equal(f.toString(), '(foo=*)') +}) + +tap.test('parses SubstringFilter', async t => { + const input = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x80, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = parse(new BerReader(input)) + t.type(f, SubstringFilter) + t.equal(f.attribute, 'foo') + t.equal(f.initial, 'bar') + t.equal(f.toString(), '(foo=bar*)') +}) + +tap.test('throws for invalid filter tag', async t => { + const input = Buffer.from([0x92, 0x03, 0x66, 0x6f, 0x6f]) + t.throws( + () => parse(new BerReader(input)), + Error('invalid search filter type: 0x92') + ) +}) + +tap.test('parseSet reads OR filter from BER', async t => { + const expected = Buffer.from([ + 0xa1, 0x1b, + 0xa3, 0x07, // eq filter + 0x04, 0x02, 0x63, 0x6e, 0x04, 0x01, 0x31, // string, 2 chars (cn), string 1 char (1) + 0xa3, 0x07, // eq filter + 0x04, 0x02, 0x63, 0x6e, 0x04, 0x01, 0x32, // string, 2 chars (cn), string 1 char (2) + 0xa3, 0x07, // eq filter + 0x04, 0x02, 0x63, 0x6e, 0x04, 0x01, 0x33 // string, 2 chars (cn), string 1 char (3) + ]) + + let f = new OrFilter() + f.addClause(new EqualityFilter({ attribute: 'cn', value: '1' })) + f.addClause(new EqualityFilter({ attribute: 'cn', value: '2' })) + f.addClause(new EqualityFilter({ attribute: 'cn', value: '3' })) + + const filterBuffer = f.toBer().buffer + t.equal(expected.compare(filterBuffer), 0) + + const reader = new BerReader(filterBuffer) + f = parse(reader) + t.ok(f) + t.equal(f.type, 'OrFilter') + t.equal(f.clauses.length, 3) + for (let i = 1; i <= 3; i += 1) { + const filter = f.clauses[i - 1] + t.equal(filter.attribute, 'cn') + t.equal(filter.value, `${i}`) + } +}) + +tap.test('parses evolution filter', async t => { + const evolutionFilterFixture = require('./_fixtures/evolution-filter') + const filter = parseString(evolutionFilterFixture.text) + const ber = filter.toBer() + + t.equal(ber.buffer.compare(evolutionFilterFixture.bytes), 0) + + const filterFromBer = parse(ber) + t.equal(filterFromBer.toString(), evolutionFilterFixture.text) +}) diff --git a/node_modules/@ldapjs/filter/lib/deprecations.js b/node_modules/@ldapjs/filter/lib/deprecations.js new file mode 100644 index 0000000..98f5367 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/deprecations.js @@ -0,0 +1,15 @@ +'use strict' + +const warning = require('process-warning')() + +const clazz = 'LdapjsFilterWarning' + +warning.create(clazz, 'LDAP_FILTER_DEP_001', 'parse is deprecated. Use the parseString function instead.') + +warning.create(clazz, 'LDAP_FILTER_DEP_002', 'subInitial is deprecated. Use initial instead.') + +warning.create(clazz, 'LDAP_FILTER_DEP_003', 'subAny is deprecated. Use any instead.') + +warning.create(clazz, 'LDAP_FILTER_DEP_004', 'subFinal is deprecated. Use final instead.') + +module.exports = warning diff --git a/node_modules/@ldapjs/filter/lib/filter-string.js b/node_modules/@ldapjs/filter/lib/filter-string.js new file mode 100644 index 0000000..78e2189 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filter-string.js @@ -0,0 +1,266 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') + +/** + * Baseline LDAP filter object. This exists solely to define the interface + * and baseline properties and methods for actual LDAP filters. + */ +class FilterString { + /** + * The BER tag for the filter as defined in + * https://datatracker.ietf.org/doc/html/rfc4511#section-4.5.1. + */ + TAG = 0x30 + // For this base `FilterString` we repurpose the sequence start tag. We + // represent it as a sequence that contains a null value. + // So we do this because it is nonsense to have an empty filter string. + + /** + * Local name of the filter. + */ + type = 'FilterString' + + /** + * String value denoting which LDAP attribute the filter targets. For example, + * in the filter `(&(cn=Foo Bar))`, the value would be "cn". + */ + attribute = '' + + #value + + #clauses = [] + + /** + * @typedef {object} FilterStringParams + * @property {string} attribute The name of the attribute the filter + * will target. + * @property {*} value The right hand side of the filter. + */ + + /** + * Creates a new filter object and sets the `attribute`. + * + * @param {FilterStringParams} input + * + * @returns {FilterString} + */ + constructor ({ attribute = '', value, clauses = [] } = {}) { + this.attribute = attribute + this.#value = value + + if (Array.isArray(clauses) === false) { + throw Error('clauses must be an array') + } + Array.prototype.push.apply(this.#clauses, clauses) + } + + get [Symbol.toStringTag] () { + return 'FilterString' + } + + /** + * String or Buffer representing the righthand side of the filter string. + * + * @property {string|Buffer} value + */ + get value () { + return this.#value + } + + set value (val) { + this.#value = val + } + + /** + * Determines if a filter instance meets specific criteria. + * Each type of filter provides its own logic for this method. + * Thus, the documentation for the method should be consulted on each + * specific filter. This baseline implementation always returns `false`. + * + * @returns {boolean} Always `false`. + */ + matches () { + return false + } + + /** + * Generate a string representation of the filter. + * + * @returns {string} + */ + toString () { + return '()' + } + + /** + * Returns a BER instance of the filter. This is typically used when + * constructing search messages to send to an LDAP server. + * + * @returns {object} A `BerReader` instance from `@ldapjs/asn1`. + */ + toBer () { + const ber = new BerWriter() + + ber.startSequence(this.TAG) + this._toBer(ber) + ber.endSequence() + + return new BerReader(ber.buffer) + } + + _toBer (ber) { + ber.writeNull() + } + + /** + * Get a "JSON" (plain JavaScript object) representation of the filter. + * Do not rely on this property to exist. + * + * @deprecated 2022-06-12 + * @property {object} + */ + get json () { + return { + type: this.type, + attribute: this.attribute, + value: this.#value + } + } + + /** + * Alias for the filter itself. This is added for backward compatibility. + * Do not rely on this property. + * + * @deprecated 2022-06-12 + * @property {FilterString} + */ + get filter () { + return this + } + + /** + * Alias for accessing the filter clauses. This is added for backward + * compatibility. Do not rely on this property. + * + * @deprecated 2022-06-12 + * @property {FilterString[]} + */ + get filters () { + return this.#clauses + } + + /** + * Most filters, e.g. "and" and "not" filters, can have multiple filter + * clauses. For example, the filter `(&(foo=a)(bar=b))` is an "and" filter + * with two clauses: `(foo=a)` and `(bar=b)`. This property provides access + * to the sibling clauses, which are themselves `FilterString` instances. + * + * @property {FilterString[]} + */ + get clauses () { + return this.#clauses + } + + /** + * @callback filterForEachCallback + * @param {FilterString} + */ + /** + * For every filter clause in the filter, apply a callback function. + * This includes the root filter. + * + * @param {filterForEachCallback} callback + */ + forEach (callback) { + this.#clauses.forEach(clause => clause.forEach(callback)) + callback(this) // eslint-disable-line + } + + /** + * @callback filterMapCallback + * @param {FilterString} + */ + /** + * For every filter clause in the filter, including the root filter, + * apply a mutation callback. + * + * @param {filterMapCallback} callback + * @returns {FilterString|*} The result of applying the callback to the + * root filter. + */ + map (callback) { + if (this.#clauses.length === 0) { + return callback(this) // eslint-disable-line + } + + const child = this.#clauses + .map(clause => clause.map(callback)) + .filter(clause => clause !== null) + if (child.length === 0) { + return null + } + this.#clauses = child + return callback(this) // eslint-disable-line + } + + /** + * Alias for `.addClause`. This is added for backward compatibility. + * Do not rely on this. + * + * @deprecated 2022-06-12 + * @param {FilterString} filter + */ + addFilter (filter) { + this.addClause(filter) + } + + /** + * Adds a new filter clause to the filter. + * + * @see clauses + * @param {FilterString} clause + */ + addClause (clause) { + if (clause instanceof FilterString === false) { + throw Error('clause must be an instance of FilterString') + } + this.#clauses.push(clause) + } + + /** + * Parses a `Buffer` instance and returns a new `FilterString` representation. + * Each `FilterString` implementation must implement this method. + * + * @param {Buffer} buffer + * + * @throws When the input `buffer` does not match the expected format. + * + * @returns {FilterString} + */ + static parse (buffer) { + // It is actually nonsense to implement this method for the base + // `FilteSring`, but we do it any way for completeness sake. We effectively + // just validate that the input buffer is the one we expect for our made up + // "empty" filter string and return a new instance if the buffer validates. + + if (buffer.length !== 4) { + throw Error(`expected buffer length 4, got ${buffer.length}`) + } + + const reader = new BerReader(buffer) + let seq = reader.readSequence() + if (seq !== 0x30) { + throw Error(`expected sequence start, got 0x${seq.toString(16).padStart(2, '0')}`) + } + + seq = reader.readSequence() + if (seq !== 0x05) { + throw Error(`expected null sequence start, got 0x${seq.toString(16).padStart(2, '0')}`) + } + + return new FilterString() + } +} + +module.exports = FilterString diff --git a/node_modules/@ldapjs/filter/lib/filter-string.test.js b/node_modules/@ldapjs/filter/lib/filter-string.test.js new file mode 100644 index 0000000..3203983 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filter-string.test.js @@ -0,0 +1,192 @@ +'use strict' + +const tap = require('tap') +const FilterString = require('./filter-string') + +tap.test('creates an empty filter string', async t => { + const f = new FilterString() + t.equal(f.TAG, 0x30) + t.equal(f.type, 'FilterString') + t.equal(f.attribute, '') + t.equal(f.value, undefined) + t.equal(f.toString(), '()') + t.equal(Object.prototype.toString.call(f), '[object FilterString]') +}) + +tap.test('throws if clauses not an array', async t => { + t.throws( + () => new FilterString({ clauses: 42 }), + Error('clauses must be an array') + ) +}) + +tap.test('set/get value', async t => { + const f = new FilterString() + t.equal(f.value, undefined) + f.value = 'foo' + t.equal(f.value, 'foo') +}) + +tap.test('matches are false', async t => { + const f = new FilterString() + t.equal(f.matches(), false) + t.equal(f.matches('nonsense'), false) +}) + +tap.test('encodes BER correctly', async t => { + const expected = Buffer.from([0x30, 0x02, 0x05, 0x00]) + const f = new FilterString() + const ber = f.toBer() + + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('json returns POJO', async t => { + const f = new FilterString({ attribute: 'foo', value: 'bar' }) + t.strictSame(f.json, { + type: 'FilterString', + attribute: 'foo', + value: 'bar' + }) +}) + +tap.test('filter property', async t => { + const f = new FilterString() + const f2 = f.filter + t.equal(f, f2) +}) + +tap.test('filters returns clauses', async t => { + const f = new FilterString({ clauses: ['foo', 'bar'] }) + t.same(f.filters, ['foo', 'bar']) +}) + +tap.test('clauses returns clauses', async t => { + const f = new FilterString({ clauses: ['foo', 'bar'] }) + t.same(f.clauses, ['foo', 'bar']) +}) + +tap.test('forEach iterates all clauses and root filter', async t => { + t.plan(3) + + const clauses = [ + new FilterString({ attribute: 'child1' }), + new FilterString({ attribute: 'child2' }) + ] + const f = new FilterString({ attribute: 'foo', clauses }) + f.forEach(clause => { + t.equal(['foo', 'child1', 'child2'].includes(clause.attribute), true) + }) +}) + +tap.test('map', t => { + t.test('maps the root filter', async t => { + t.plan(4) + + const f = new FilterString({ attribute: 'foo' }) + const f2 = f.map(item => { + t.equal(item.attribute, 'foo') + item.attribute = 'bar' + return item + }) + t.equal(f2.attribute, 'bar') + t.equal(f.attribute, 'bar') + t.equal(f, f2) + }) + + t.test('maps all clauses and root filter', async t => { + const clauses = [ + new FilterString({ attribute: 'child1' }), + new FilterString({ attribute: 'child2' }) + ] + const f = new FilterString({ attribute: 'foo', clauses }) + f.map(item => { + item.value = item.attribute + return item + }) + + t.equal(f.value, 'foo') + t.equal(clauses[0].value, 'child1') + t.equal(clauses[1].value, 'child2') + }) + + t.test('aborts if callback does not apply to clauses', async t => { + // No idea why this is a feature. We replicate it for completeness. + // Maybe one day we can remove it? ~ 2022-06-12 + const clauses = [ + new FilterString({ attribute: 'child1' }), + new FilterString({ attribute: 'child2' }) + ] + const f = new FilterString({ attribute: 'foo', clauses }) + const result = f.map(item => { + if (item.attribute !== 'foo') return null + t.fail('should not reach here') + return undefined + }) + + t.equal(f.value, undefined) + t.equal(f.clauses.length, 2) + t.equal(result, null) + }) + + t.end() +}) + +tap.test('addFilter adds a filter', async t => { + const f = new FilterString({ attribute: 'foo' }) + f.addFilter(new FilterString({ attribute: 'bar' })) + t.equal(f.clauses.length, 1) + t.equal(f.clauses[0].attribute, 'bar') +}) + +tap.test('addClause', t => { + t.test('throws if not a filter string', async t => { + const f = new FilterString() + t.throws( + () => f.addClause('foo'), + Error('clause must be an instance of FilterString') + ) + }) + + t.test('adds a clause', async t => { + const f = new FilterString({ attribute: 'foo' }) + f.addClause(new FilterString({ attribute: 'bar' })) + t.equal(f.clauses.length, 1) + t.equal(f.clauses[0].attribute, 'bar') + }) + + t.end() +}) + +tap.test('#parse', t => { + t.test('throws for bad length', async t => { + const input = Buffer.alloc(3) + t.throws( + () => FilterString.parse(input), + Error('expected buffer length 4, got 3') + ) + }) + + t.test('throws for bad sequence start', async t => { + const input = Buffer.from([0x31, 0x02, 0x05, 0x00]) + t.throws( + () => FilterString.parse(input), + Error('expected sequence start, got 0x31') + ) + }) + + t.test('throws for bad null sequence start', async t => { + const input = Buffer.from([0x30, 0x02, 0x06, 0x00]) + t.throws( + () => FilterString.parse(input), + Error('expected null sequence start, got 0x06') + ) + }) + + t.test('parses a buffer', async t => { + const f = FilterString.parse(Buffer.from([0x30, 0x02, 0x05, 0x00])) + t.equal(f.toString(), '()') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/and.js b/node_modules/@ldapjs/filter/lib/filters/and.js new file mode 100644 index 0000000..b60249b --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/and.js @@ -0,0 +1,132 @@ +'use strict' + +const FilterString = require('../filter-string') +const { search } = require('@ldapjs/protocol') + +/** + * Represents a set of filters that must all match for the filter to + * match, e.g. `(&(cn=foo)(sn=bar))`. + */ +class AndFilter extends FilterString { + /** + * @typedef {FilterStringParams} AndFilterParams + * @property {FilterString[]} [filters=[]] A set of filters which comprise + * the clauses of the `AND` filter. + */ + + /** + * @param {AndFilterParams} input + * + * @throws When a filter is not an instance of {@link FilterString}. + */ + constructor ({ filters = [] } = {}) { + super({}) + + // AND filters do not have an `attribute` property. + this.attribute = undefined + + for (const filter of filters) { + this.addClause(filter) + } + + Object.defineProperties(this, { + TAG: { value: search.FILTER_AND }, + type: { value: 'AndFilter' } + }) + } + + get json () { + return { + type: this.type, + filters: this.clauses.map(clause => clause.json) + } + } + + toString () { + let result = '(&' + for (const clause of this.clauses) { + result += clause.toString() + } + result += ')' + return result + } + + /** + * Determines if an object represents an equivalent filter instance. + * Both the filter attribute and filter value must match the comparison + * object. All clauses of the `AND` filter, that is all "sub filters", must + * match for the result to be `true`. + * + * @example + * const eqFilter = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + * const filter = new AndFilter({ filters: [eqFilter] }) + * assert.equal(filter.matches({ foo: 'bar' }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase = true) { + if (this.clauses.length === 0) { + // https://datatracker.ietf.org/doc/html/rfc4526#section-2 + return true + } + + for (const clause of this.clauses) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + // For each passed in attribute, we need to determine if the current + // clause matches the attribute name. If it does, we need to + // determine if the values match. + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (attr.type !== clause.attribute) { + continue + } + if (clause.matches(attr, strictAttrCase) === false) { + return false + } + } + } else { + if (clause.matches(obj, strictAttrCase) === false) { + return false + } + } + } + + return true + } + + _toBer (ber) { + for (const clause of this.clauses) { + const filterBer = clause.toBer() + ber.appendBuffer(filterBer.buffer) + } + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {AndFilter} + */ + static parse (buffer) { + const parseNestedFilter = require('./utils/parse-nested-filter') + return parseNestedFilter({ + buffer, + constructor: AndFilter, + startTag: search.FILTER_AND + }) + } +} + +module.exports = AndFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/and.test.js b/node_modules/@ldapjs/filter/lib/filters/and.test.js new file mode 100644 index 0000000..f5bc45a --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/and.test.js @@ -0,0 +1,134 @@ +'use strict' + +const tap = require('tap') +const Attribute = require('@ldapjs/attribute') +const EqualityFilter = require('./equality') +const AndFilter = require('./and') + +tap.test('constructs instance', async t => { + const f = new AndFilter({ + filters: [ + new EqualityFilter({ attribute: 'foo', value: 'bar' }), + new EqualityFilter({ attribute: 'zig', value: 'zag' }) + ] + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.toString(), '(&(foo=bar)(zig=zag))') + t.same(f.json, { + type: 'AndFilter', + filters: [ + { type: 'EqualityFilter', attribute: 'foo', value: 'bar' }, + { type: 'EqualityFilter', attribute: 'zig', value: 'zag' } + ] + }) +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new AndFilter() + f.addClause(new EqualityFilter({ + attribute: 'foo', + value: 'bar' + })) + f.addClause(new EqualityFilter({ + attribute: 'zig', + value: 'zag' + })) + t.ok(f) + t.ok(f.matches({ foo: 'bar', zig: 'zag' })) + }) + + t.test('match false', async t => { + const f = new AndFilter() + f.addClause(new EqualityFilter({ + attribute: 'foo', + value: 'bar' + })) + f.addClause(new EqualityFilter({ + attribute: 'zig', + value: 'zag' + })) + t.ok(f) + t.ok(!f.matches({ foo: 'bar', zig: 'zonk' })) + }) + + t.test('RFC-4526 - empty AND', async t => { + const f = new AndFilter() + t.ok(f.matches({})) + }) + + t.test('handles a set of attributes', async t => { + const attributes = Attribute.fromObject({ + cn: 'foo', + sn: 'bar' + }) + const f = new AndFilter() + f.addClause(new EqualityFilter({ + attribute: 'cn', + value: 'foo' + })) + f.addClause(new EqualityFilter({ + attribute: 'sn', + value: 'bar' + })) + t.ok(f.matches(attributes)) + }) + + t.test('throws if not an array of attributes', async t => { + const f = new AndFilter() + f.addClause(new EqualityFilter({ + attribute: 'cn', + value: 'foo' + })) + t.throws( + () => f.matches([{ bad: 'object' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa0, 0x0c, 0xa3, 0x0a, // and tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const eqFilter = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + const f = new AndFilter({ filters: [eqFilter] }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('parse', t => { + t.test('parses buffer', async t => { + const input = new AndFilter({ + filters: [new EqualityFilter({ attribute: 'cn', value: 'foo' })] + }) + const f = AndFilter.parse(input.toBer().buffer) + t.equal(f.clauses.length, 1) + t.equal(f.toString(), '(&(cn=foo))') + }) + + t.test('parses simple all-match filter', async t => { + const input = Buffer.from([0xa0, 0x00]) + const f = AndFilter.parse(input) + t.equal(f.toString(), '(&)') + }) + + t.test('throws for unexpected sequence', async t => { + const input = Buffer.from([ + 0xa3, 0x0c, 0xa3, 0x0a, // and tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => AndFilter.parse(input), + Error('expected filter tag 0xa0, got 0xa3') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/approximate.js b/node_modules/@ldapjs/filter/lib/filters/approximate.js new file mode 100644 index 0000000..079b458 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/approximate.js @@ -0,0 +1,86 @@ +'use strict' + +const FilterString = require('../filter-string') +const { BerReader } = require('@ldapjs/asn1') +const { search } = require('@ldapjs/protocol') +const escapeFilterValue = require('../utils/escape-filter-value') + +/** + * Represents a basic filter for determining if an LDAP entry contains a + * specified attribute that is approximately equal a given value, + * e.g. `(cn~=foo)`. + */ +class ApproximateFilter extends FilterString { + /** + * @typedef {FilterStringParams} AttributeParams + */ + + /** + * @param {AttributeParams} input + * + * @throws When either `attribute` or `value` is not a string of at least + * one character. + */ + constructor ({ attribute, value } = {}) { + if (typeof attribute !== 'string' || attribute.length < 1) { + throw Error('attribute must be a string of at least one character') + } + if (typeof value !== 'string' || value.length < 1) { + throw Error('value must be a string of at least one character') + } + + super({ attribute, value }) + + Object.defineProperties(this, { + TAG: { value: search.FILTER_APPROX }, + type: { value: 'ApproximateFilter' } + }) + } + + /** + * Not implemented. + * + * @throws In all cases. + */ + matches () { + throw Error('not implemented') + } + + toString () { + return ('(' + escapeFilterValue(this.attribute) + + '~=' + escapeFilterValue(this.value) + ')') + } + + _toBer (ber) { + ber.writeString(this.attribute) + ber.writeString(this.value) + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {ApproximateFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const seq = reader.readSequence() + if (seq !== search.FILTER_APPROX) { + const expected = '0x' + search.FILTER_APPROX.toString(16).padStart(2, '0') + const found = '0x' + seq.toString(16).padStart(2, '0') + throw Error(`expected approximate filter sequence ${expected}, got ${found}`) + } + + const attribute = reader.readString() + const value = reader.readString() + + return new ApproximateFilter({ attribute, value }) + } +} + +module.exports = ApproximateFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/approximate.test.js b/node_modules/@ldapjs/filter/lib/filters/approximate.test.js new file mode 100644 index 0000000..69b888f --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/approximate.test.js @@ -0,0 +1,127 @@ +'use strict' + +const tap = require('tap') +const ApproximateFilter = require('./approximate') +const { BerReader, BerWriter } = require('@ldapjs/asn1') + +tap.test('throws if input is invalid', async t => { + const attrError = Error('attribute must be a string of at least one character') + const valError = Error('value must be a string of at least one character') + + t.throws( + () => new ApproximateFilter(), + attrError + ) + t.throws( + () => new ApproximateFilter({ attribute: '' }), + attrError + ) + t.throws( + () => new ApproximateFilter({ attribute: 'foo' }), + valError + ) + t.throws( + () => new ApproximateFilter({ attribute: 'foo', value: '' }), + valError + ) +}) + +tap.test('Construct args', async t => { + const f = new ApproximateFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo~=bar)') + t.same(f.json, { + type: 'ApproximateFilter', + attribute: 'foo', + value: 'bar' + }) +}) + +tap.test('escape value only in toString()', async t => { + const f = new ApproximateFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + t.equal(f.toString(), '(foo~=ba\\28r\\29)') +}) + +tap.test('matches throws', async t => { + const f = new ApproximateFilter({ attribute: 'foo', value: 'bar' }) + t.throws( + () => f.matches({}), + Error('not implemented') + ) +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa8, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new ApproximateFilter({ attribute: 'foo', value: 'bar' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('#parse', t => { + t.test('parses buffer', async t => { + const input = Buffer.from([ + 0xa8, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = ApproximateFilter.parse(input) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo~=bar)') + }) + + t.test('throws for unexpected sequence', async t => { + const input = Buffer.from([ + 0xa4, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => ApproximateFilter.parse(input), + Error('expected approximate filter sequence 0xa8, got 0xa4') + ) + }) + + t.end() +}) + +tap.test('original node-ldap tests', t => { + // This set of subtests are from the original "filters/approx" test suite + // in the core `ldapjs` module code. + + t.test('GH-109 = to ber uses plain values', function (t) { + let f = new ApproximateFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + + const writer = new BerWriter() + writer.appendBuffer(f.toBer().buffer) + + const reader = new BerReader(writer.buffer) + f = ApproximateFilter.parse(reader.buffer) + + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + t.end() + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/equality.js b/node_modules/@ldapjs/filter/lib/filters/equality.js new file mode 100644 index 0000000..2e7773a --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/equality.js @@ -0,0 +1,186 @@ +'use strict' + +const FilterString = require('../filter-string') +const { BerReader, BerTypes } = require('@ldapjs/asn1') +const { search } = require('@ldapjs/protocol') +const escapeFilterValue = require('../utils/escape-filter-value') +const testValues = require('../utils/test-values') +const getAttributeValue = require('../utils/get-attribute-value') + +/** + * Represents a basic filter for determining if an LDAP entry contains a + * specified attribute that equals a given value, e.g. `(cn=foo)`. + */ +class EqualityFilter extends FilterString { + #raw + + /** + * @typedef {FilterStringParams} EqualityParams + * @property {string} attribute The name of the LDAP addtribute this + * filter will target. + * @property {string|Buffer} [value] A string or buffer value as the + * test for this filter. Required if `raw` is not provided. + * @property {Buffer} [raw] A buffer to use as the test for this filter. + * Required if `value` is not provided. + */ + + /** + * @param {EqualityParams} input + * + * @throws When no value, either through `value` or `raw`, is provided. + * Also throws when `attribute` is not a string. + */ + constructor ({ attribute, raw, value } = {}) { + if (typeof attribute !== 'string' || attribute.length < 1) { + throw Error('attribute must be a string of at least one character') + } + + super({ attribute, value }) + + if (raw) { + this.#raw = raw + } else { + if (!value) { + throw Error('must either provide a buffer via `raw` or some `value`') + } + this.#raw = Buffer.from(value) + } + + Object.defineProperties(this, { + TAG: { value: search.FILTER_EQUALITY }, + type: { value: 'EqualityFilter' } + }) + } + + get value () { + return Buffer.isBuffer(this.#raw) ? this.#raw.toString() : this.#raw + } + + set value (val) { + if (typeof val === 'string') { + this.#raw = Buffer.from(val) + } else if (Buffer.isBuffer(val)) { + this.#raw = Buffer.alloc(val.length) + val.copy(this.#raw) + } else { + this.#raw = val + } + } + + /** + * Determines if an object represents an equivalent filter instance. + * Both the filter attribute and filter value must match the comparison + * object. + * + * @example + * const filter = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + * assert.equal(filter.matches({ foo: 'bar' }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase = true) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (this.matches(attr, strictAttrCase) === true) { + return true + } + } + return false + } + + let testValue = this.value + + if (this.attribute.toLowerCase() === 'objectclass') { + // Perform a case-insensitive match for `objectClass` as most LDAP + // implementations behave in this manner. + const targetAttribute = getAttributeValue({ + sourceObject: obj, + attributeName: this.attribute, + strictCase: false + }) + testValue = testValue.toLowerCase() + return testValues({ + rule: v => testValue === v.toLowerCase(), + value: targetAttribute + }) + } + + const targetAttribute = getAttributeValue({ + sourceObject: obj, + attributeName: this.attribute, + strictCase: strictAttrCase + }) + return testValues({ + rule: v => testValue === v, + value: targetAttribute + }) + } + + /** + * @throws When `value` is not a string or a buffer. + */ + toString () { + let value + if (Buffer.isBuffer(this.#raw)) { + value = this.#raw + const decoded = this.#raw.toString('utf8') + const validate = Buffer.from(decoded, 'utf8') + + // Use the decoded UTF-8 if it is valid, otherwise fall back to bytes. + // Since Buffer.compare is missing in older versions of node, a simple + // length comparison is used as a heuristic. This can be updated later to + // a full compare if it is found lacking. + if (validate.length === this.#raw.length) { + value = decoded + } + } else if (typeof (this.#raw) === 'string') { + value = this.#raw + } else { + throw new Error('invalid value type') + } + return ('(' + escapeFilterValue(this.attribute) + + '=' + escapeFilterValue(value) + ')') + } + + _toBer (ber) { + ber.writeString(this.attribute) + ber.writeBuffer(this.#raw, BerTypes.OctetString) + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {EqualityFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const tag = reader.readSequence() + if (tag !== search.FILTER_EQUALITY) { + const expected = '0x' + search.FILTER_EQUALITY.toString(16).padStart(2, '0') + const found = '0x' + tag.toString(16).padStart(2, '0') + throw Error(`expected equality filter sequence ${expected}, got ${found}`) + } + + const attribute = reader.readString() + const value = reader.readString(BerTypes.OctetString, true) + + return new EqualityFilter({ attribute, value }) + } +} + +module.exports = EqualityFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/equality.test.js b/node_modules/@ldapjs/filter/lib/filters/equality.test.js new file mode 100644 index 0000000..193fbbe --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/equality.test.js @@ -0,0 +1,245 @@ +'use strict' + +const tap = require('tap') +const { search } = require('@ldapjs/protocol') +const Attribute = require('@ldapjs/attribute') +const EqualityFilter = require('./equality') + +tap.test('Construct invalid args', async t => { + t.throws( + () => new EqualityFilter(), + Error('attribute must be a string of at least one character') + ) + + t.throws( + () => new EqualityFilter({ attribute: 'foo' }), + Error('must either provide a buffer via `raw` or some `value`') + ) +}) + +tap.test('Construct args', async t => { + const f = new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.TAG, search.FILTER_EQUALITY) + t.equal(f.attribute, 'foo') + t.equal(f.type, 'EqualityFilter') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo=bar)') +}) + +tap.test('construct with raw', async t => { + const f = new EqualityFilter({ + attribute: 'foo', + raw: Buffer.from([126]) + }) + t.ok(f) + t.equal(f.value, '~') +}) + +tap.test('value setter', async t => { + let data = Buffer.from([126]) + const f = new EqualityFilter({ attribute: 'foo', raw: data }) + f.value = 'a' + t.not(f.value, data.toString(), 'preserve buffer') + + data = Buffer.from('a') + f.value = data.toString() + t.equal(f.value, data.toString(), 'convert string') + + f.value = true + t.equal(typeof (f.value), 'boolean', 'preserve other type') + t.ok(f.value) +}) + +tap.test('toString', t => { + t.test('buffer', async t => { + const f = new EqualityFilter({ attribute: 'foo', raw: Buffer.from('bar') }) + t.equal(f.toString(), '(foo=bar)') + }) + + t.test('string', async t => { + const f = new EqualityFilter({ attribute: 'foo', raw: 'bar' }) + t.equal(f.toString(), '(foo=bar)') + }) + + t.test('boolean', async t => { + const f = new EqualityFilter({ attribute: 'foo', raw: true }) + t.throws( + () => f.toString(), + Error('invalid value type') + ) + }) + + t.test('escape value only in toString()', async t => { + const f = new EqualityFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + t.equal(f.toString(), '(foo=ba\\28r\\29)') + }) + + t.end() +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: 'bar' }), true) + }) + + t.test('match multiple', async t => { + const f = new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: ['plop', 'bar'] }), true) + }) + + t.test('match false', async t => { + const f = new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: 'baz' }), false) + }) + + t.test('obj can be array of attributes', async t => { + const attributes = Attribute.fromObject({ cn: 'foo' }) + const f = new EqualityFilter({ + attribute: 'cn', + value: 'foo' + }) + t.equal(f.matches(attributes), true) + }) + + t.test('throws if element not an attribute', async t => { + const f = new EqualityFilter({ + attribute: 'cn', + value: 'foo' + }) + t.throws( + () => f.matches([{ cn: 'foo' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('escape EqualityFilter inputs', async t => { + const f = new EqualityFilter({ + attribute: '(|(foo', + value: 'bar))(' + }) + + t.equal(f.attribute, '(|(foo') + t.equal(f.value, 'bar))(') + t.equal(f.toString(), '(\\28|\\28foo=bar\\29\\29\\28)') + + f.value = Buffer.from([97, 115, 100, 102, 41, 40, 0, 255]) + t.equal(f.toString(), '(\\28|\\28foo=asdf\\29\\28\\00ÿ)') + + f.value = Buffer.from([195, 40]) + t.equal(f.toString(), '(\\28|\\28foo=\\c3\\28)') + + f.value = Buffer.from([195, 177]) + t.equal(f.toString(), '(\\28|\\28foo=\\c3\\b1)') +}) + +tap.test('encodes to BER correctly', t => { + t.test('basic ascii values', async t => { + const expected = Buffer.from([ + 0xa3, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.test('values with non-ascii', async t => { + const expected = Buffer.from([ + 0xa3, 0x0b, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x04, 0xc3, 0xad, 0xc3, 0xb8 // OctetString "íø" + ]) + const f = new EqualityFilter({ attribute: 'foo', value: 'íø' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parse', t => { + t.test('parses buffer', async t => { + const input = Buffer.from([ + 0xa3, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = EqualityFilter.parse(input) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo=bar)') + }) + + t.test('throws for unexpected sequence', async t => { + const input = Buffer.from([ + 0xa4, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => EqualityFilter.parse(input), + Error('expected equality filter sequence 0xa3, got 0xa4') + ) + }) + + t.end() +}) + +tap.test('original node-ldap tests', t => { + // This set of subtests are from the original "filters/eq" test suite + // in the core `ldapjs` module code. + + t.test('GH-277 objectClass should be case-insensitive', async t => { + const f = new EqualityFilter({ + attribute: 'objectClass', + value: 'CaseInsensitiveObj' + }) + t.ok(f) + t.equal(f.matches({ objectClass: 'CaseInsensitiveObj' }), true) + t.equal(f.matches({ OBJECTCLASS: 'CASEINSENSITIVEOBJ' }), true) + t.equal(f.matches({ objectclass: 'caseinsensitiveobj' }), true) + t.equal(f.matches({ objectclass: 'matchless' }), false) + }) + + t.test('escape EqualityFilter inputs', function (t) { + const f = new EqualityFilter({ + attribute: '(|(foo', + value: 'bar))(' + }) + + t.equal(f.attribute, '(|(foo') + t.equal(f.value, 'bar))(') + t.equal(f.toString(), '(\\28|\\28foo=bar\\29\\29\\28)') + t.end() + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/extensible.js b/node_modules/@ldapjs/filter/lib/filters/extensible.js new file mode 100644 index 0000000..1f0e3e5 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/extensible.js @@ -0,0 +1,188 @@ +'use strict' + +const FilterString = require('../filter-string') +const { search } = require('@ldapjs/protocol') +const { BerReader } = require('@ldapjs/asn1') + +/** + * Represents an extensible LDAP filter as defined in + * https://www.rfc-editor.org/rfc/rfc2251.html#section-4.5.1. + */ +class ExtensibleFilter extends FilterString { + #dnAttributes + #rule + + /** + * @typedef {FilterStringParams} ExtensibleParams + * @property {string|undefined} [attribute=''] Name of the attribute to + * match against, if any. + * @property {*} [value=''] Value to test for. + * @property {string} [rule] A matching rule OID if a speficic matching + * rule is to be used. + * @property {string|undefined} [matchType=''] An alias for `attribute`. + * This parameter is provided for backward compatibility. Use `attribute` + * instead. + * @property {boolean} [dnAttributes=false] Indicates if all attributes + * of a matching distinguished name should be tested. + */ + + /** + * @param {ExtensibleParams} input + * + * @throws When `dnAttbributes` or `rule` are not valid. + */ + constructor ({ attribute, value, rule, matchType, dnAttributes = false } = {}) { + // `attribute` and `matchType` are allowed to be `undefined` per the + // RFC. When either is not provided, an empty string will be used. + // This is covered in the `toString` and `toBer` methods. + + if (typeof dnAttributes !== 'boolean') { + throw Error('dnAttributes must be a boolean value') + } + if (rule && typeof rule !== 'string') { + throw Error('rule must be a string') + } + + super({ attribute, value }) + + if (matchType !== undefined) { + this.attribute = matchType + } + + this.#dnAttributes = dnAttributes + this.#rule = rule + this.value = value ?? '' + + Object.defineProperties(this, { + TAG: { value: search.FILTER_EXT }, + type: { value: 'ExtensibleFilter' } + }) + } + + get json () { + return { + type: this.type, + matchRule: this.#rule, + matchType: this.attribute, + matchValue: this.value, + dnAttributes: this.#dnAttributes + } + } + + get dnAttributes () { + return this.#dnAttributes + } + + get matchingRule () { + return this.#rule + } + + get matchValue () { + return this.value + } + + get matchType () { + return this.attribute + } + + toString () { + let result = '(' + + if (this.attribute) { + result += this.attribute + } + + result += ':' + + if (this.#dnAttributes === true) { + result += 'dn:' + } + + if (this.#rule) { + result += this.#rule + ':' + } + + result += '=' + this.value + ')' + return result + } + + /** + * Not implemented. + * + * @throws In all cases. + */ + matches () { + throw Error('not implemented') + } + + _toBer (ber) { + if (this.#rule) { ber.writeString(this.#rule, 0x81) } + if (this.attribute) { ber.writeString(this.attribute, 0x82) } + + ber.writeString(this.value, 0x83) + if (this.#dnAttributes === true) { + ber.writeBoolean(this.#dnAttributes, 0x84) + } + + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag, or an + * invalid context specific tag is encountered. + * + * @returns {ExtensibleFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const seq = reader.readSequence() + if (seq !== search.FILTER_EXT) { + const expected = '0x' + search.FILTER_EXT.toString(16).padStart(2, '0') + const found = '0x' + seq.toString(16).padStart(2, '0') + throw Error(`expected extensible filter sequence ${expected}, got ${found}`) + } + + let rule + let attribute + let value + let dnAttributes + + // Must set end outside of loop as the reader will update the + // length property as the buffer is read. + const end = reader.buffer.length + while (reader.offset < end) { + // Read the context specific tag and act accordingly. + const tag = reader.peek() + switch (tag) { + case 0x81: { + rule = reader.readString(tag) + break + } + case 0x82: { + attribute = reader.readString(tag) + break + } + case 0x83: { + value = reader.readString(tag) + break + } + case 0x84: { + dnAttributes = reader.readBoolean(tag) + break + } + default: { + throw Error('invalid extensible filter type: 0x' + tag.toString(16).padStart(2, '0')) + } + } + } + + return new ExtensibleFilter({ attribute, value, rule, dnAttributes }) + } +} + +module.exports = ExtensibleFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/extensible.test.js b/node_modules/@ldapjs/filter/lib/filters/extensible.test.js new file mode 100644 index 0000000..e65c5ee --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/extensible.test.js @@ -0,0 +1,168 @@ +'use strict' + +const tap = require('tap') + +const ExtensibleFilter = require('./extensible') +const { parseString } = require('../index') + +tap.test('constructor', t => { + t.test('throws for non-boolean dnAttributes', async t => { + const error = Error('dnAttributes must be a boolean value') + + t.throws( + () => new ExtensibleFilter({ attribute: 'foo', dnAttributes: 'bar' }), + error + ) + }) + + t.test('throws for non-string rule', async t => { + const error = Error('rule must be a string') + + t.throws( + () => new ExtensibleFilter({ attribute: 'foo', rule: 42 }), + error + ) + }) + + t.test('argument variations are covered', async t => { + let f = new ExtensibleFilter({ + matchType: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.matchType, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo:=bar)') + + f = new ExtensibleFilter({ + matchType: 'foo', + rule: '1.2', + dnAttributes: true, + value: 'baz' + }) + t.same(f.json, { + type: 'ExtensibleFilter', + matchRule: '1.2', + matchType: 'foo', + matchValue: 'baz', + dnAttributes: true + }) + t.equal(f.toString(), '(foo:dn:1.2:=baz)') + + f = new ExtensibleFilter({ + attribute: 'test', + value: 'bar' + }) + t.equal(f.matchType, 'test') + t.same(f.json, { + type: 'ExtensibleFilter', + matchRule: undefined, + matchType: 'test', + matchValue: 'bar', + dnAttributes: false + }) + + f = new ExtensibleFilter({ + dnAttributes: true, + value: 'foo' + }) + t.equal(f.toString(), '(:dn:=foo)') + t.same(f.json, { + type: 'ExtensibleFilter', + matchRule: undefined, + matchType: '', + matchValue: 'foo', + dnAttributes: true + }) + }) + + t.end() +}) + +tap.test('attribute synonym', async t => { + const f = parseString('foo:=bar') + t.equal(f.matchType, 'foo') + t.equal(f.attribute, 'foo') + f.attribute = 'baz' + t.equal(f.matchType, 'baz') + t.equal(f.attribute, 'baz') +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa9, 0x14, + 0x81, 0x05, 0x31, 0x2e, 0x32, 0x2e, 0x33, // OID 1.2.3 + 0x82, 0x03, 0x66, 0x6f, 0x6f, // attribute + 0x83, 0x03, 0x62, 0x61, 0x72, // value + 0x84, 0x01, 0xff // dnAttributes + ]) + const f = new ExtensibleFilter({ + attribute: 'foo', + value: 'bar', + rule: '1.2.3', + dnAttributes: true + }) + + const found = f.toBer() + t.equal(expected.compare(found.buffer), 0) +}) + +tap.test('parse', t => { + const fooArray = [0x03, 0x66, 0x6f, 0x6f] // length + string + const barArray = [0x03, 0x62, 0x61, 0x72] // length + string + + t.test('parses a basic representation', async t => { + const buffer = Buffer.from([ + 0xa9, 0x0a, + 0x82, ...fooArray, + 0x83, ...barArray + ]) + const f = ExtensibleFilter.parse(buffer) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo:=bar)') + }) + + t.test('parses a value only representation', async t => { + const buffer = Buffer.from([ + 0xa9, 0x0a, + 0x83, ...barArray, // value + 0x84, 0x01, 0xff // dnAttributes + ]) + const f = ExtensibleFilter.parse(buffer) + t.equal(f.attribute, '') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(:dn:=bar)') + }) + + t.test('parses a full representation', async t => { + const buffer = Buffer.from([ + 0xa9, 0x0a, + 0x81, 0x05, 0x31, 0x2e, 0x32, 0x2e, 0x33, // OID 1.2.3 + 0x82, ...fooArray, // attribute + 0x83, ...barArray, // value + 0x84, 0x01, 0xff // dnAttributes + ]) + const f = ExtensibleFilter.parse(buffer) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.matchingRule, '1.2.3') + t.equal(f.dnAttributes, true) + t.equal(f.toString(), '(foo:dn:1.2.3:=bar)') + }) + + t.test('throws for bad representation', async t => { + const buffer = Buffer.from([ + 0xa9, 0x0a, + 0x89, ...barArray, // value + 0x84, 0x01, 0xff // dnAttributes + ]) + t.throws( + () => ExtensibleFilter.parse(buffer), + Error('invalid extensible filter type: 0x89') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/greater-than-equals.js b/node_modules/@ldapjs/filter/lib/filters/greater-than-equals.js new file mode 100644 index 0000000..3242dac --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/greater-than-equals.js @@ -0,0 +1,119 @@ +'use strict' + +const FilterString = require('../filter-string') +const { BerReader } = require('@ldapjs/asn1') +const { search } = require('@ldapjs/protocol') +const escapeFilterValue = require('../utils/escape-filter-value') +const testValues = require('../utils/test-values') +const getAttributeValue = require('../utils/get-attribute-value') + +/** + * Represents a basic filter for determining if an LDAP entry contains a + * specified attribute that is greater than or equal to a given value, + * e.g. `(cn>=foo)`. + */ +class GreaterThanEqualsFilter extends FilterString { + /** + * @typedef {FilterStringParams} GreaterThanEqualsParams + * @property {string} attribute + * @property {string} value + */ + + /** + * @param {GreaterThanEqualsParams} input + * + * @throws When `attribute` or `value` is not a string. + */ + constructor ({ attribute, value } = {}) { + if (typeof attribute !== 'string' || attribute.length < 1) { + throw Error('attribute must be a string of at least one character') + } + if (typeof value !== 'string' || value.length < 1) { + throw Error('value must be a string of at least one character') + } + + super({ attribute, value }) + + Object.defineProperties(this, { + TAG: { value: search.FILTER_GE }, + type: { value: 'GreaterThanEqualsFilter' } + }) + } + + /** + * Determines if an object represents a greater-than-equals filter instance. + * Both the filter attribute and filter value must match the comparison + * object. + * + * @example + * const filter = new GreaterThanEqualsFilter({ attribute: 'foo', value: 'bar' }) + * assert.equal(filter.matches({ foo: 'bar' }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase = true) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (this.matches(attr, strictAttrCase) === true) { + return true + } + } + return false + } + + const testValue = this.value + const targetAttribute = getAttributeValue({ sourceObject: obj, attributeName: this.attribute, strictCase: strictAttrCase }) + + return testValues({ + rule: v => testValue <= v, + value: targetAttribute + }) + } + + toString () { + return ('(' + escapeFilterValue(this.attribute) + + '>=' + escapeFilterValue(this.value) + ')') + } + + _toBer (ber) { + ber.writeString(this.attribute) + ber.writeString(this.value) + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {GreaterThanEqualsFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const seq = reader.readSequence() + if (seq !== search.FILTER_GE) { + const expected = '0x' + search.FILTER_GE.toString(16).padStart(2, '0') + const found = '0x' + seq.toString(16).padStart(2, '0') + throw Error(`expected greater-than-equals filter sequence ${expected}, got ${found}`) + } + + const attribute = reader.readString() + const value = reader.readString() + + return new GreaterThanEqualsFilter({ attribute, value }) + } +} + +module.exports = GreaterThanEqualsFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/greater-than-equals.test.js b/node_modules/@ldapjs/filter/lib/filters/greater-than-equals.test.js new file mode 100644 index 0000000..cbd2380 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/greater-than-equals.test.js @@ -0,0 +1,164 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const Attribute = require('@ldapjs/attribute') +const GreaterThanEqualsFilter = require('./greater-than-equals') + +tap.test('requires attribute and value', async t => { + const attrErr = Error('attribute must be a string of at least one character') + const valErr = Error('value must be a string of at least one character') + + t.throws( + () => new GreaterThanEqualsFilter(), + attrErr + ) + t.throws( + () => new GreaterThanEqualsFilter({ attribute: '' }), + attrErr + ) + t.throws( + () => new GreaterThanEqualsFilter({ attribute: 'foo' }), + valErr + ) + t.throws( + () => new GreaterThanEqualsFilter({ attribute: 'foo', value: '' }), + valErr + ) +}) + +tap.test('basic construction', async t => { + const f = new GreaterThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo>=bar)') +}) + +tap.test('escape value only in toString()', async t => { + const f = new GreaterThanEqualsFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + t.equal(f.toString(), '(foo>=ba\\28r\\29)') +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new GreaterThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: 'baz' }), true) + }) + + t.test('match multiple', async t => { + const f = new GreaterThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: ['beuha', 'baz'] }), true) + }) + + t.test('match false', async t => { + const f = new GreaterThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: 'abc' }), false) + }) + + t.test('obj can be array of attributes', async t => { + const attributes = Attribute.fromObject({ cn: 'foo' }) + const f = new GreaterThanEqualsFilter({ + attribute: 'cn', + value: 'foo' + }) + t.equal(f.matches(attributes), true) + }) + + t.test('throws if element not an attribute', async t => { + const f = new GreaterThanEqualsFilter({ + attribute: 'cn', + value: 'foo' + }) + t.throws( + () => f.matches([{ cn: 'foo' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa5, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new GreaterThanEqualsFilter({ attribute: 'foo', value: 'bar' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('parse', t => { + tap.test('throws for bad sequence', async t => { + const input = Buffer.from([ + 0xa4, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => GreaterThanEqualsFilter.parse(input), + Error('expected greater-than-equals filter sequence 0xa5, got 0xa4') + ) + }) + + t.test('parses buffer', async t => { + const input = Buffer.from([ + 0xa5, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = GreaterThanEqualsFilter.parse(input) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo>=bar)') + }) + + t.end() +}) + +tap.test('original node-ldap tests', t => { + // This set of subtests are from the original "filters/ge" test suite + // in the core `ldapjs` module code. + + t.test('GH-109 = to ber uses plain values', async t => { + let f = new GreaterThanEqualsFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + + const writer = new BerWriter() + writer.appendBuffer(f.toBer().buffer) + + f = GreaterThanEqualsFilter.parse(writer.buffer) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/less-than-equals.js b/node_modules/@ldapjs/filter/lib/filters/less-than-equals.js new file mode 100644 index 0000000..bef9cd1 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/less-than-equals.js @@ -0,0 +1,120 @@ +'use strict' + +const FilterString = require('../filter-string') +const { BerReader } = require('@ldapjs/asn1') +const { search } = require('@ldapjs/protocol') + +const escapeFilterValue = require('../utils/escape-filter-value') +const testValues = require('../utils/test-values') +const getAttributeValue = require('../utils/get-attribute-value') + +/** + * Represents a basic filter for determining if an LDAP entry contains a + * specified attribute that is less than or equal to a given value, + * e.g. `(cn<=foo)`. + */ +class LessThanEqualsFilter extends FilterString { + /** + * @typedef {FilterStringParams} LessThanEqualsParams + * @property {string} attribute + * @property {string} value + */ + + /** + * @param {LessThanEqualsParams} input + * + * @throws When `attribute` or `value` is not a string. + */ + constructor ({ attribute, value } = {}) { + if (typeof attribute !== 'string' || attribute.length < 1) { + throw Error('attribute must be a string of at least one character') + } + if (typeof value !== 'string' || value.length < 1) { + throw Error('value must be a string of at least one character') + } + + super({ attribute, value }) + + Object.defineProperties(this, { + TAG: { value: search.FILTER_LE }, + type: { value: 'LessThanEqualsFilter' } + }) + } + + toString () { + return ('(' + escapeFilterValue(this.attribute) + + '<=' + escapeFilterValue(this.value) + ')') + } + + /** + * Determines if an object represents a less-than-equals filter instance. + * Both the filter attribute and filter value must match the comparison + * object. + * + * @example + * const filter = new LessThanEqualsFilter({ attribute: 'foo', value: 'bar' }) + * assert.equal(filter.matches({ foo: 'bar' }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase = true) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (this.matches(attr, strictAttrCase) === true) { + return true + } + } + return false + } + + const testValue = this.value + const targetAttribute = getAttributeValue({ sourceObject: obj, attributeName: this.attribute, strictCase: strictAttrCase }) + + return testValues({ + rule: v => v <= testValue, + value: targetAttribute + }) + } + + _toBer (ber) { + ber.writeString(this.attribute) + ber.writeString(this.value) + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {LessThanEqualsFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const seq = reader.readSequence() + if (seq !== search.FILTER_LE) { + const expected = '0x' + search.FILTER_LE.toString(16).padStart(2, '0') + const found = '0x' + seq.toString(16).padStart(2, '0') + throw Error(`expected less-than-equals filter sequence ${expected}, got ${found}`) + } + + const attribute = reader.readString() + const value = reader.readString() + + return new LessThanEqualsFilter({ attribute, value }) + } +} + +module.exports = LessThanEqualsFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/less-than-equals.test.js b/node_modules/@ldapjs/filter/lib/filters/less-than-equals.test.js new file mode 100644 index 0000000..9df6187 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/less-than-equals.test.js @@ -0,0 +1,174 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const Attribute = require('@ldapjs/attribute') +const LessThanEqualsFilter = require('./less-than-equals') + +tap.test('requires attribute and value', async t => { + const attrErr = Error('attribute must be a string of at least one character') + const valErr = Error('value must be a string of at least one character') + + t.throws( + () => new LessThanEqualsFilter(), + attrErr + ) + t.throws( + () => new LessThanEqualsFilter({ attribute: '' }), + attrErr + ) + t.throws( + () => new LessThanEqualsFilter({ attribute: 'foo' }), + valErr + ) + t.throws( + () => new LessThanEqualsFilter({ attribute: 'foo', value: '' }), + valErr + ) +}) + +tap.test('basic construction', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo<=bar)') +}) + +tap.test('escape value only in toString()', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + t.equal(f.toString(), '(foo<=ba\\28r\\29)') +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: 'abc' }), true) + }) + + t.test('match multiple', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: ['abc', 'beuha'] }), true) + }) + + t.test('match false', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'bar' + }) + t.ok(f) + t.equal(f.matches({ foo: 'baz' }), false) + }) + + t.test('obj can be array of attributes', async t => { + const attributes = Attribute.fromObject({ cn: 'foo' }) + const f = new LessThanEqualsFilter({ + attribute: 'cn', + value: 'foo' + }) + t.equal(f.matches(attributes), true) + }) + + t.test('throws if element not an attribute', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'cn', + value: 'foo' + }) + t.throws( + () => f.matches([{ cn: 'foo' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa6, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new LessThanEqualsFilter({ attribute: 'foo', value: 'bar' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('parse', t => { + tap.test('throws for bad sequence', async t => { + const input = Buffer.from([ + 0xa4, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => LessThanEqualsFilter.parse(input), + Error('expected less-than-equals filter sequence 0xa6, got 0xa4') + ) + }) + + t.test('parses buffer', async t => { + const input = Buffer.from([ + 0xa6, 0x0a, + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = LessThanEqualsFilter.parse(input) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar') + t.equal(f.toString(), '(foo<=bar)') + }) + + t.end() +}) + +tap.test('original node-ldap tests', t => { + // This set of subtests are from the original "filters/le" test suite + // in the core `ldapjs` module code. + + t.test('GH-109 = escape value only in toString()', async t => { + const f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + t.equal(f.toString(), '(foo<=ba\\28r\\29)') + }) + + t.test('GH-109 = to ber uses plain values', async t => { + let f = new LessThanEqualsFilter({ + attribute: 'foo', + value: 'ba(r)' + }) + t.ok(f) + + const writer = new BerWriter() + writer.appendBuffer(f.toBer().buffer) + f = LessThanEqualsFilter.parse(writer.buffer) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'ba(r)') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/not.js b/node_modules/@ldapjs/filter/lib/filters/not.js new file mode 100644 index 0000000..4ba1cb0 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/not.js @@ -0,0 +1,113 @@ +'use strict' + +const FilterString = require('../filter-string') +const { search } = require('@ldapjs/protocol') + +/** + * Represents a basic filter that negates other filters, e.g. + * `(!(cn=foo))`. A `NotFilter` may only have one direct negated + * filter, but that filter may represent a multiple clause filter + * such as an `AndFilter`. + */ +class NotFilter extends FilterString { + /** + * @typedef {FilterStringParams} NotParams + * @property {FilterString} filter The filter to negate. + */ + + /** + * @param {NotParams} input + * + * @throws If not filter is provided. + */ + constructor ({ filter } = {}) { + if (filter instanceof FilterString === false) { + throw Error('filter is required and must be a filter instance') + } + + super() + + // We set `attribute` to `undefined` because the NOT filter is a specal + // case: it must not have an attribute or an value. It must have an inner + // filter. + this.attribute = undefined + this.filter = filter + + Object.defineProperties(this, { + TAG: { value: search.FILTER_NOT }, + type: { value: 'NotFilter' } + }) + } + + get json () { + return { + type: this.type, + filter: this.filter.json + } + } + + get filter () { + return this.clauses[0] + } + + set filter (filter) { + if (filter instanceof FilterString === false) { + throw Error('filter must be a filter instance') + } + this.clauses[0] = filter + } + + setFilter (filter) { + this.clauses[0] = filter + } + + toString () { + return '(!' + this.filter.toString() + ')' + } + + /** + * Invokes the direct filter's `matches` routine and inverts the result. + * + * @example + * const eqFilter = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + * const filter = new NotFilter({ filter: eqFilter }) + * assert.equal(filter.matches({ foo: 'bar' }), false) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase = true) { + return !this.filter.matches(obj, strictAttrCase) + } + + _toBer (ber) { + const innerBer = this.filter.toBer(ber) + ber.appendBuffer(innerBer.buffer) + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {NotFilter} + */ + static parse (buffer) { + const parseNestedFilter = require('./utils/parse-nested-filter') + return parseNestedFilter({ + buffer, + constructor: NotFilter, + startTag: search.FILTER_NOT + }) + } +} + +module.exports = NotFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/not.test.js b/node_modules/@ldapjs/filter/lib/filters/not.test.js new file mode 100644 index 0000000..2899084 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/not.test.js @@ -0,0 +1,105 @@ +'use strict' + +const tap = require('tap') +const EqualityFilter = require('./equality') +const NotFilter = require('./not') + +tap.test('Construct args', async t => { + const f = new NotFilter({ + filter: new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.type, 'NotFilter') + t.equal(f.toString(), '(!(foo=bar))') + t.same(f.json, { + type: 'NotFilter', + filter: { + type: 'EqualityFilter', + attribute: 'foo', + value: 'bar' + } + }) +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new NotFilter({ + filter: new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + }) + t.ok(f) + t.ok(f.matches({ foo: 'baz' })) + }) + + t.test('match false', async t => { + const f = new NotFilter({ + filter: new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + }) + t.ok(f) + t.ok(!f.matches({ foo: 'bar' })) + }) + + t.end() +}) + +tap.test('setFilter', async t => { + const f = new NotFilter({ + filter: new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + }) + t.ok(f) + t.equal(f.toString(), '(!(foo=bar))') + f.setFilter(new EqualityFilter({ + attribute: 'new', + value: 'val' + })) + t.equal(f.toString(), '(!(new=val))') +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa2, 0x0c, 0xa3, 0x0a, // not tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const eqFilter = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + const f = new NotFilter({ filter: eqFilter }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('parse', t => { + t.test('parses buffer', async t => { + const input = new NotFilter({ + filter: new EqualityFilter({ attribute: 'cn', value: 'foo' }) + }) + const f = NotFilter.parse(input.toBer().buffer) + t.equal(f.clauses.length, 1) + t.equal(f.toString(), '(!(cn=foo))') + }) + + t.test('throws for unexpected sequence', async t => { + const input = Buffer.from([ + 0xa3, 0x0c, 0xa3, 0x0a, // not tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => NotFilter.parse(input), + Error('expected filter tag 0xa2, got 0xa3') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/or.js b/node_modules/@ldapjs/filter/lib/filters/or.js new file mode 100644 index 0000000..e64d621 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/or.js @@ -0,0 +1,132 @@ +'use strict' + +const FilterString = require('../filter-string') +const { search } = require('@ldapjs/protocol') + +/** + * Represents a set of filters that must all match for the filter to + * match, e.g. `(|(cn=foo)(sn=bar))`. + */ +class OrFilter extends FilterString { + /** + * @typedef {FilterStringParams} OrParams + * @property {FilterString[]} [filters=[]] A set of filters which comprise + * the clauses of the `OR` filter. + */ + + /** + * @param {OrParams} input + * + * @throws When a filter is not an instance of {@link FilterString}. + */ + constructor ({ filters = [] } = {}) { + super({}) + + // OR filters do not have an `attribute` property. + this.attribute = undefined + + for (const filter of filters) { + this.addClause(filter) + } + + Object.defineProperties(this, { + TAG: { value: search.FILTER_OR }, + type: { value: 'OrFilter' } + }) + } + + get json () { + return { + type: this.type, + filters: this.clauses.map(clause => clause.json) + } + } + + toString () { + let result = '(|' + for (const clause of this.clauses) { + result += clause.toString() + } + result += ')' + return result + } + + /** + * Determines if an object represents an equivalent filter instance. + * Both the filter attribute and filter value must match the comparison + * object. Any clause of the `OR` filter, that is all "sub filters", may + * match for the result to be `true`. + * + * @example + * const eqFilter = new EqualityFilter({ attribute: 'foo', value: 'bar' }) + * const filter = new OrFilter({ filters: [eqFilter] }) + * assert.equal(filter.matches({ foo: 'bar' }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase = true) { + if (this.clauses.length === 0) { + // https://datatracker.ietf.org/doc/html/rfc4526#section-2 + return false + } + + for (const clause of this.clauses) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + // For each passed in attribute, we need to determine if the current + // clause matches the attribute name. If it does, we need to + // determine if the values match. + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (attr.type !== clause.attribute) { + continue + } + if (clause.matches(attr, strictAttrCase) === true) { + return true + } + } + } else { + if (clause.matches(obj, strictAttrCase) === true) { + return true + } + } + } + + return false + } + + _toBer (ber) { + for (const clause of this.clauses) { + const filterBer = clause.toBer() + ber.appendBuffer(filterBer.buffer) + } + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {OrFilter} + */ + static parse (buffer) { + const parseNestedFilter = require('./utils/parse-nested-filter') + return parseNestedFilter({ + buffer, + constructor: OrFilter, + startTag: search.FILTER_OR + }) + } +} + +module.exports = OrFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/or.test.js b/node_modules/@ldapjs/filter/lib/filters/or.test.js new file mode 100644 index 0000000..509ac8b --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/or.test.js @@ -0,0 +1,185 @@ +'use strict' + +const tap = require('tap') +const Attribute = require('@ldapjs/attribute') +const EqualityFilter = require('./equality') +const SubstringFilter = require('./substring') +const OrFilter = require('./or') + +tap.test('constructs instance', async t => { + const f = new OrFilter({ + filters: [ + new EqualityFilter({ attribute: 'foo', value: 'bar' }), + new EqualityFilter({ attribute: 'zig', value: 'zag' }) + ] + }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.toString(), '(|(foo=bar)(zig=zag))') +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new OrFilter() + f.addClause(new EqualityFilter({ + attribute: 'foo', + value: 'bar' + })) + f.addClause(new EqualityFilter({ + attribute: 'zig', + value: 'zag' + })) + t.ok(f) + t.ok(f.matches({ foo: 'bar', zig: 'zonk' })) + t.same(f.json, { + type: 'OrFilter', + filters: [ + { type: 'EqualityFilter', attribute: 'foo', value: 'bar' }, + { type: 'EqualityFilter', attribute: 'zig', value: 'zag' } + ] + }) + }) + + t.test('match false', async t => { + const f = new OrFilter() + f.addClause(new EqualityFilter({ + attribute: 'foo', + value: 'bar' + })) + f.addClause(new EqualityFilter({ + attribute: 'zig', + value: 'zag' + })) + t.ok(f) + t.equal(f.matches({ foo: 'baz', zig: 'zonk' }), false) + }) + + t.test('RFC-4526 - empty OR', async t => { + const f = new OrFilter() + t.equal(f.matches({}), false) + }) + + t.test('handles a set of attributes', async t => { + const attributes = Attribute.fromObject({ + cn: 'foo', + sn: 'bar' + }) + const f = new OrFilter() + f.addClause(new EqualityFilter({ + attribute: 'cn', + value: 'foo' + })) + f.addClause(new EqualityFilter({ + attribute: 'sn', + value: 'bar' + })) + t.ok(f.matches(attributes)) + }) + + t.test('throws if not an array of attributes', async t => { + const f = new OrFilter() + f.addClause(new EqualityFilter({ + attribute: 'cn', + value: 'foo' + })) + t.throws( + () => f.matches([{ bad: 'object' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('encodes to BER correctly', async t => { + const expected = Buffer.from([ + 0xa1, 0x0c, 0xa3, 0x0a, // or tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const eqFilter = new EqualityFilter({ + attribute: 'foo', + value: 'bar' + }) + const f = new OrFilter({ filters: [eqFilter] }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.test('encodes substring filters', async t => { + const expected = Buffer.from([ + 0xa1, 0x0d, // or tag, 13 bytes + 0xa4, 0x0b, // sequence (substring tag), 11 bytes + 0x04, 0x02, // string, 2 bytes + // "cn" + 0x63, 0x6e, + 0x30, 0x05, // sequence, 5 bytes + 0x80, 0x03, // string (initial tag), 3 bytes + // "foo" + 0x66, 0x6f, 0x6f + ]) + const subFilter = new SubstringFilter({ + attribute: 'cn', + initial: 'foo' + }) + const f = new OrFilter({ filters: [subFilter] }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('parse', t => { + t.test('parses buffer', async t => { + const input = Buffer.from([ + 0xa1, 0x0c, 0xa3, 0x0a, // or tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = OrFilter.parse(input) + t.equal(f.clauses.length, 1) + t.equal(f.toString(), '(|(foo=bar))') + }) + + t.test('throws for unexpected sequence', async t => { + const input = Buffer.from([ + 0xa3, 0x0c, 0xa3, 0x0a, // or tag, length, eq tag, length + 0x04, 0x03, 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x04, 0x03, 0x62, 0x61, 0x72 // OctetString "bar" + ]) + t.throws( + () => OrFilter.parse(input), + Error('expected filter tag 0xa1, got 0xa3') + ) + }) + + t.test('parses a set of substring filters', async t => { + const input = Buffer.from([ + 0xa1, 0x1a, // or tag, 26 bytes + + 0xa4, 0x0b, // sequence (substring tag), 11 bytes + 0x04, 0x02, // string, 2 bytes + // "cn" + 0x63, 0x6e, + 0x30, 0x05, // sequence, 5 bytes + 0x80, 0x03, // string (initial tag), 3 bytes + // "foo" + 0x66, 0x6f, 0x6f, + + 0xa4, 0x0b, // sequence (substring tag), 11 bytes + 0x04, 0x02, // string, 2 bytes + // "sn" + 0x73, 0x6e, + 0x30, 0x05, // sequence, 5 bytes + 0x80, 0x03, // string (initial tag), 3 bytes + 0x66, 0x6f, 0x6f + ]) + + const filter = OrFilter.parse(input) + t.equal(filter.toString(), '(|(cn=foo*)(sn=foo*))') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/presence.js b/node_modules/@ldapjs/filter/lib/filters/presence.js new file mode 100644 index 0000000..accc1b5 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/presence.js @@ -0,0 +1,106 @@ +'use strict' + +const FilterString = require('../filter-string') +const { BerReader } = require('@ldapjs/asn1') +const { search } = require('@ldapjs/protocol') +const escapeFilterValue = require('../utils/escape-filter-value') +const getAttributeValue = require('../utils/get-attribute-value') + +/** + * Represents a basic filter for determining if an LDAP entry contains a + * specified attribute, e.g. `(cn=*)`. + */ +class PresenceFilter extends FilterString { + /** + * @typedef {FilterStringParams} PresenceParams + * @property {string} attribute The name of the attribute this filter targets. + */ + + /** + * @param {PresenceParams} input + * + * @throws If no attribute name is given. + */ + constructor ({ attribute } = {}) { + if (typeof attribute !== 'string' || attribute.length < 1) { + throw Error('attribute must be a string of at least one character') + } + + super({ attribute }) + + Object.defineProperties(this, { + TAG: { value: search.FILTER_PRESENT }, + type: { value: 'PresenceFilter' } + }) + } + + /** + * Determine if a given object matches the filter instance. + * + * @example + * const filter = new PresenceFilter({ attribute: 'foo' }) + * assert.equal(filter.matches({ foo: "bar" }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttributeCase=true] If `false`, "fOo" will match + * "foo". + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttributeCase = true) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (this.matches(attr, strictAttributeCase) === true) { + return true + } + } + return false + } + + return getAttributeValue({ + sourceObject: obj, + attributeName: this.attribute, + strictCase: strictAttributeCase + }) !== undefined + } + + toString () { + return `(${escapeFilterValue(this.attribute)}=*)` + } + + _toBer (ber) { + for (let i = 0; i < this.attribute.length; i++) { + ber.writeByte(this.attribute.charCodeAt(i)) + } + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {PresenceFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const tag = reader.peek() + if (tag !== search.FILTER_PRESENT) { + const expected = '0x' + search.FILTER_PRESENT.toString(16).padStart(2, '0') + const found = '0x' + tag.toString(16).padStart(2, '0') + throw Error(`expected presence filter sequence ${expected}, got ${found}`) + } + + const attribute = reader.readString(tag) + return new PresenceFilter({ attribute }) + } +} + +module.exports = PresenceFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/presence.test.js b/node_modules/@ldapjs/filter/lib/filters/presence.test.js new file mode 100644 index 0000000..d1d82e7 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/presence.test.js @@ -0,0 +1,111 @@ +'use strict' + +const tap = require('tap') +const { search } = require('@ldapjs/protocol') +const Attribute = require('@ldapjs/attribute') +const PresenceFilter = require('./presence') + +tap.test('Construct no args', async t => { + t.throws( + () => new PresenceFilter(), + Error('attribute must be a string of at least one character') + ) +}) + +tap.test('Construct args', async t => { + const f = new PresenceFilter({ attribute: 'foo' }) + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.TAG, search.FILTER_PRESENT) + t.equal(f.type, 'PresenceFilter') + t.equal(f.attribute, 'foo') + t.equal(f.toString(), '(foo=*)') +}) + +tap.test('escape value only in toString()', async t => { + const f = new PresenceFilter({ attribute: 'fo)o' }) + t.ok(f) + t.equal(f.attribute, 'fo)o') + t.equal(f.toString(), '(fo\\29o=*)') +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new PresenceFilter({ attribute: 'foo' }) + t.ok(f) + t.equal(f.matches({ foo: 'bar' }), true) + }) + + t.test('match false', async t => { + const f = new PresenceFilter({ attribute: 'foo' }) + t.ok(f) + t.equal(f.matches({ bar: 'foo' }), false) + }) + + t.test('obj can be array of attributes', async t => { + const attributes = Attribute.fromObject({ cn: 'foo' }) + const f = new PresenceFilter({ attribute: 'cn' }) + t.equal(f.matches(attributes), true) + }) + + t.test('throws if element not an attribute', async t => { + const f = new PresenceFilter({ attribute: 'cn' }) + t.throws( + () => f.matches([{ cn: 'foo' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('encodes to BER correctly', async t => { + const expected = Buffer.from([0x87, 0x03, 0x66, 0x6f, 0x6f]) + const f = new PresenceFilter({ attribute: 'foo' }) + const ber = f.toBer() + + t.equal(expected.compare(ber.buffer), 0) +}) + +tap.test('#parse', t => { + t.test('throws if starts with wrong sequence', async t => { + const buffer = Buffer.from([0x88, 0x03, 0x66, 0x6f, 0x6f]) + t.throws( + () => PresenceFilter.parse(buffer), + Error('expected presence filter sequence 0x87, got 0x88') + ) + }) + + t.test('parses buffer', async t => { + const buffer = Buffer.from([0x87, 0x03, 0x66, 0x6f, 0x6f]) + const f = PresenceFilter.parse(buffer) + t.equal(f.toString(), '(foo=*)') + }) + + t.end() +}) + +tap.test('original node-ldap tests', t => { + // This set of subtests are from the original "filters/presence" test suite + // in the core `ldapjs` module code. + + t.test('GH-109 = escape value only in toString()', async t => { + const f = new PresenceFilter({ attribute: 'fo)o' }) + t.ok(f) + t.equal(f.attribute, 'fo)o') + t.equal(f.toString(), '(fo\\29o=*)') + }) + + t.test('GH-109 = to ber uses plain values', async t => { + let f = new PresenceFilter({ attribute: 'f(o)o' }) + t.ok(f) + + const ber = f.toBer() + f = PresenceFilter.parse(ber.buffer) + + t.equal(f.attribute, 'f(o)o') + t.end() + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/substring.js b/node_modules/@ldapjs/filter/lib/filters/substring.js new file mode 100644 index 0000000..d7134b2 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/substring.js @@ -0,0 +1,307 @@ +'use strict' + +const FilterString = require('../filter-string') +const { BerReader } = require('@ldapjs/asn1') +const { search } = require('@ldapjs/protocol') +const escapeFilterValue = require('../utils/escape-filter-value') +const testValues = require('../utils/test-values') +const getAttributeValue = require('../utils/get-attribute-value') +const warning = require('../deprecations') + +/** + * Represents a filter that matches substrings withing LDAP entry attribute + * values, e.g. `(cn=*f*o*o)`. + */ +class SubstringFilter extends FilterString { + #initial + #any = [] + #final + + /** + * Internal helper for backwards compatibility. + * @type {Boolean} + */ + #constructedWithSubPrefix + + /** + * @typedef {FilterStringParams} SubstringParams + * @property {string} input.attribute The attribute to test against. + * @property {string} [initial] Text that must appear at the start + * of a value and may not overlap any value of `any` or `final`. + * @property {string} [subInitial] Deprecated, use `initial`. + * @property {string[]} [any] Text items that must appear in the + * attribute value that do not overlap with `initial`, `final`, or + * any other `any` item. + * @property {string[]} [subAny] Deprecated, use `any`. + * @property {string} [final] Text that must appear at the end of + * the attribute value. May not overlap with `initial` or any `any` + * item. + * @property {string} [subFinal] Deprecated, use `final`. + */ + + /** + * @param {SubstringParams} input + * + * @throws When any input parameter is of an incorrect type. + */ + constructor ({ attribute, initial, subInitial, any = [], subAny = [], final, subFinal } = {}) { + if (subInitial) { + warning.emit('LDAP_FILTER_DEP_002') + initial = subInitial + } + + if (Array.isArray(subAny) && subAny.length > 0) { + warning.emit('LDAP_FILTER_DEP_003') + any = subAny + } + + if (subFinal) { + warning.emit('LDAP_FILTER_DEP_004') + final = subFinal + } + + if (typeof attribute !== 'string' || attribute.length < 1) { + throw Error('attribute must be a string of at least one character') + } + if (Array.isArray(any) === false) { + throw Error('any must be an array of items') + } + if (Array.isArray(subAny) === false) { + throw Error('subAny must be an array of items') + } + if (final && typeof final !== 'string') { + throw Error('final must be a string') + } + + super({ attribute }) + + this.#initial = initial + Array.prototype.push.apply(this.#any, any) + this.#final = final + this.#constructedWithSubPrefix = subInitial || subFinal || subAny.length > 0 + + Object.defineProperties(this, { + TAG: { value: search.FILTER_SUBSTRINGS }, + type: { value: 'SubstringFilter' } + }) + } + + /** + * @type {string} + */ + get initial () { + return this.#initial + } + + /** + * @type {string[]} + */ + get any () { + return this.#any + } + + /** + * @type {string} + */ + get final () { + return this.#final + } + + /** + * @deprecated 2023-06-29 Use `initial` instead. + * @type {string} + */ + get subInitial () { + return this.#initial + } + + /** + * @deprecated 2023-06-29 Use `any` instead. + * @type {string[]} + */ + get subAny () { + return this.#any + } + + /** + * @deprecated 2023-06-29 Use `final` instead. + * @type {string} + */ + get subFinal () { + return this.#final + } + + get json () { + if (this.#constructedWithSubPrefix) { + return { + type: this.type, + subInitial: this.#initial, + subAny: this.#any, + subFinal: this.#final + } + } else { + return { + type: this.type, + initial: this.#initial, + any: this.#any, + final: this.#final + } + } + } + + toString () { + let result = '(' + escapeFilterValue(this.attribute) + '=' + + if (this.#initial) { + result += escapeFilterValue(this.#initial) + } + + result += '*' + + for (const any of this.#any) { + result += escapeFilterValue(any) + '*' + } + + if (this.#final) { + result += escapeFilterValue(this.#final) + } + + result += ')' + return result + } + + /** + * Determines if an object represents an equivalent filter instance. + * Both the filter attribute and filter value must match the comparison + * object. + * + * @example + * const filter = new EqualityFilter({ attribute: 'foo', initial: 'bar' }) + * assert.equal(filter.matches({ foo: 'bar' }), true) + * + * @param {object} obj An object to check for match. + * @param {boolean} [strictAttrCase=true] If `false`, "fOo" will match + * "foo" in the attribute position (left hand side). + * + * @throws When input types are not correct. + * + * @returns {boolean} + */ + matches (obj, strictAttrCase) { + if (Array.isArray(obj) === true) { + for (const attr of obj) { + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('array element must be an instance of LdapAttribute') + } + if (this.matches(attr, strictAttrCase) === true) { + return true + } + } + return false + } + + const targetValue = getAttributeValue({ sourceObject: obj, attributeName: this.attribute, strictCase: strictAttrCase }) + + if (targetValue === undefined || targetValue === null) { + return false + } + + let re = '' + + if (this.#initial) { re += '^' + escapeRegExp(this.#initial) + '.*' } + this.#any.forEach(function (s) { + re += escapeRegExp(s) + '.*' + }) + if (this.#final) { re += escapeRegExp(this.#final) + '$' } + + const matcher = new RegExp(re) + return testValues({ + rule: v => matcher.test(v), + value: targetValue + }) + } + + _toBer (ber) { + // Tag sequence as already been started via FilterString.toBer, so + // start by writing the "type" field. + ber.writeString(this.attribute) + ber.startSequence() + + if (this.#initial) { ber.writeString(this.#initial, 0x80) } + + if (this.#any.length > 0) { + for (const sub of this.#any) { + ber.writeString(sub, 0x81) + } + } + + if (this.#final) { ber.writeString(this.#final, 0x82) } + + ber.endSequence() + + return ber + } + + /** + * Parses a BER encoded `Buffer` and returns a new filter. + * + * @param {Buffer} buffer BER encoded buffer. + * + * @throws When the buffer does not start with the proper BER tag. + * + * @returns {AndFilter} + */ + static parse (buffer) { + const reader = new BerReader(buffer) + + const seq = reader.readSequence() + if (seq !== search.FILTER_SUBSTRINGS) { + const expected = '0x' + search.FILTER_SUBSTRINGS.toString(16).padStart(2, '0') + const found = '0x' + seq.toString(16).padStart(2, '0') + throw Error(`expected substring filter sequence ${expected}, got ${found}`) + } + + let initial + const any = [] + let final + + const attribute = reader.readString() + reader.readSequence() + + // Must set end outside of loop as the reader will update the + // length property as the buffer is read. + const end = reader.offset + reader.length + while (reader.offset < end) { + const tag = reader.peek() + switch (tag) { + case 0x80: { // Initial + initial = reader.readString(tag) + break + } + + case 0x81: { // Any + const anyVal = reader.readString(tag) + any.push(anyVal) + break + } + + case 0x82: { // Final + final = reader.readString(tag) + break + } + + default: { + throw new Error('Invalid substrings filter type: 0x' + tag.toString(16)) + } + } + } + + return new SubstringFilter({ attribute, initial, any, final }) + } +} + +function escapeRegExp (str) { + return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') // eslint-disable-line +} + +module.exports = SubstringFilter diff --git a/node_modules/@ldapjs/filter/lib/filters/substring.test.js b/node_modules/@ldapjs/filter/lib/filters/substring.test.js new file mode 100644 index 0000000..3e17971 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/substring.test.js @@ -0,0 +1,337 @@ +'use strict' + +const tap = require('tap') +const { BerWriter } = require('@ldapjs/asn1') +const Attribute = require('@ldapjs/attribute') +const SubstringFilter = require('./substring') +const warning = require('../deprecations') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +tap.test('Construct args', async t => { + const f = new SubstringFilter({ + attribute: 'foo', + initial: 'bar', + any: ['zig', 'zag'], + final: 'baz' + }) + + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.attribute, 'foo') + t.equal(f.initial, 'bar') + t.equal(f.any.length, 2) + t.equal(f.any[0], 'zig') + t.equal(f.any[1], 'zag') + t.equal(f.final, 'baz') + t.equal(f.toString(), '(foo=bar*zig*zag*baz)') + t.strictSame(f.json, { + type: 'SubstringFilter', + initial: 'bar', + any: ['zig', 'zag'], + final: 'baz' + }) +}) + +tap.test('Construct with deprecated args', async t => { + const f = new SubstringFilter({ + attribute: 'foo', + subInitial: 'bar', + subAny: ['zig', 'zag'], + subFinal: 'baz' + }) + + t.ok(f) + t.equal(Object.prototype.toString.call(f), '[object FilterString]') + t.equal(f.attribute, 'foo') + t.equal(f.initial, 'bar') + t.equal(f.subInitial, 'bar') + t.equal(f.any.length, 2) + t.equal(f.any[0], 'zig') + t.equal(f.any[1], 'zag') + t.equal(f.subAny.length, 2) + t.equal(f.subAny[0], 'zig') + t.equal(f.subAny[1], 'zag') + t.equal(f.final, 'baz') + t.equal(f.subFinal, 'baz') + t.equal(f.toString(), '(foo=bar*zig*zag*baz)') + t.strictSame(f.json, { + type: 'SubstringFilter', + subInitial: 'bar', + subAny: ['zig', 'zag'], + subFinal: 'baz' + }) +}) + +tap.test('Emits warnings about sub prefix deprecation', t => { + process.on('warning', handler) + + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_FILTER_DEP_002', false) + warning.emitted.set('LDAP_FILTER_DEP_003', false) + warning.emitted.set('LDAP_FILTER_DEP_004', false) + }) + + // eslint-disable-next-line no-new + new SubstringFilter({ + attribute: 'foo', + subInitial: 'bar', + subAny: ['zig', 'zag'], + subFinal: 'baz' + }) + + const warnings = [] + + function handler ({ message }) { + warnings.push(message) + + if (warnings.length === 3) { + t.same(warnings, [ + 'subInitial is deprecated. Use initial instead.', + 'subAny is deprecated. Use any instead.', + 'subFinal is deprecated. Use final instead.' + ]) + + t.end() + } + } +}) + +tap.test('escape value only in toString()', async t => { + const f = new SubstringFilter({ + attribute: 'fo(o', + initial: 'ba(r)', + any: ['zi)g', 'z(ag'], + final: '(baz)' + }) + t.ok(f) + t.equal(f.attribute, 'fo(o') + t.equal(f.initial, 'ba(r)') + t.equal(f.any.length, 2) + t.equal(f.any[0], 'zi)g') + t.equal(f.any[1], 'z(ag') + t.equal(f.final, '(baz)') + t.equal(f.toString(), '(fo\\28o=ba\\28r\\29*zi\\29g*z\\28ag*\\28baz\\29)') +}) + +tap.test('matches', t => { + t.test('match true', async t => { + const f = new SubstringFilter({ + attribute: 'foo', + initial: 'bar', + any: ['zig', 'zag'], + final: 'baz' + }) + t.ok(f) + t.equal(f.matches({ foo: 'barmoozigbarzagblahbaz' }), true) + }) + + t.test('match false', async t => { + const f = new SubstringFilter({ + attribute: 'foo', + initial: 'bar', + any: ['biz', 'biz'], + final: 'baz' + }) + t.ok(f) + t.ok(!f.matches({ foo: 'bafmoozigbarzagblahbaz' })) + t.ok(!f.matches({ baz: 'barbizbizbaz' })) + }) + + t.test('match any', async t => { + const f = new SubstringFilter({ + attribute: 'foo', + initial: 'bar' + }) + t.ok(f) + t.ok(f.matches({ foo: ['beuha', 'barista'] })) + }) + + t.test('match no-initial', async t => { + const f = new SubstringFilter({ + attribute: 'foo', + any: ['foo'] + }) + t.ok(f) + t.equal(f.toString(), '(foo=*foo*)') + t.ok(f.matches({ foo: 'foobar' })) + t.ok(f.matches({ foo: 'barfoo' })) + t.ok(!f.matches({ foo: 'bar' })) + }) + + t.test('escape for regex in matches', async t => { + const f = new SubstringFilter({ + attribute: 'fo(o', + initial: 'ba(r)', + any: ['zi)g', 'z(ag'], + final: '(baz)' + }) + t.ok(f) + t.ok(f.matches({ 'fo(o': ['ba(r)_zi)g-z(ag~(baz)'] })) + }) + + t.test('obj can be array of attributes', async t => { + const attributes = Attribute.fromObject({ cn: 'foobar' }) + const f = new SubstringFilter({ + attribute: 'cn', + initial: 'foo' + }) + t.equal(f.matches(attributes), true) + }) + + t.test('throws if element not an attribute', async t => { + const f = new SubstringFilter({ + attribute: 'cn', + initial: 'foo' + }) + t.throws( + () => f.matches([{ cn: 'foo' }]), + 'array element must be an instance of LdapAttribute' + ) + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('encodes initial', async t => { + const expected = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x80, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new SubstringFilter({ attribute: 'foo', initial: 'bar' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.test('encodes any', async t => { + const expected = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x81, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new SubstringFilter({ attribute: 'foo', any: ['bar'] }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.test('encodes final', async t => { + const expected = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x82, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = new SubstringFilter({ attribute: 'foo', final: 'bar' }) + const ber = f.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('parse', async t => { + t.test('parses initial', async t => { + const buffer = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x80, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = SubstringFilter.parse(buffer) + const ber = f.toBer() + t.equal(buffer.compare(ber.buffer), 0) + t.equal(f.attribute, 'foo') + t.equal(f.initial, 'bar') + }) + + t.test('parses any', async t => { + const buffer = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x81, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = SubstringFilter.parse(buffer) + const ber = f.toBer() + t.equal(buffer.compare(ber.buffer), 0) + t.equal(f.attribute, 'foo') + t.strictSame(f.any, ['bar']) + }) + + t.test('parses final', async t => { + const buffer = Buffer.from([ + 0xa4, 0x0c, 0x04, 0x03, // substring tag, length, string tag, length + 0x66, 0x6f, 0x6f, // OctetString "foo" + 0x30, 0x05, 0x82, 0x03, // sequence tag, length, context tag, length + 0x62, 0x61, 0x72 // OctetString "bar" + ]) + const f = SubstringFilter.parse(buffer) + const ber = f.toBer() + t.equal(buffer.compare(ber.buffer), 0) + t.equal(f.attribute, 'foo') + t.equal(f.final, 'bar') + }) +}) + +tap.test('original node-ldap tests', t => { + // This set of subtests are from the original "filters/substr" test suite + // in the core `ldapjs` module code. + + t.test('GH-109 = escape value only in toString()', async t => { + const f = new SubstringFilter({ + attribute: 'fo(o', + initial: 'ba(r)', + any: ['zi)g', 'z(ag'], + final: '(baz)' + }) + t.ok(f) + t.equal(f.attribute, 'fo(o') + t.equal(f.initial, 'ba(r)') + t.equal(f.any.length, 2) + t.equal(f.any[0], 'zi)g') + t.equal(f.any[1], 'z(ag') + t.equal(f.final, '(baz)') + t.equal(f.toString(), '(fo\\28o=ba\\28r\\29*zi\\29g*z\\28ag*\\28baz\\29)') + }) + + t.test('GH-109 = escape for regex in matches', async t => { + const f = new SubstringFilter({ + attribute: 'fo(o', + initial: 'ba(r)', + any: ['zi)g', 'z(ag'], + final: '(baz)' + }) + t.ok(f) + t.ok(f.matches({ 'fo(o': ['ba(r)_zi)g-z(ag~(baz)'] })) + }) + + t.test('GH-109 = to ber uses plain values', async t => { + let f = new SubstringFilter({ + attribute: 'fo(o', + initial: 'ba(r)', + any: ['zi)g', 'z(ag'], + final: '(baz)' + }) + t.ok(f) + + const writer = new BerWriter() + writer.appendBuffer(f.toBer().buffer) + + f = SubstringFilter.parse(writer.buffer) + t.ok(f) + t.equal(f.attribute, 'fo(o') + t.equal(f.initial, 'ba(r)') + t.equal(f.any.length, 2) + t.equal(f.any[0], 'zi)g') + t.equal(f.any[1], 'z(ag') + t.equal(f.final, '(baz)') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/filters/utils/parse-nested-filter.js b/node_modules/@ldapjs/filter/lib/filters/utils/parse-nested-filter.js new file mode 100644 index 0000000..89a1d17 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/utils/parse-nested-filter.js @@ -0,0 +1,47 @@ +'use strict' + +const { search } = require('@ldapjs/protocol') +const { BerReader } = require('@ldapjs/asn1') + +module.exports = function parseNestedFilter ({ startTag, buffer, constructor }) { + // We need to import all of the filter objects within the function + // because this function is meant to be used within each of the objects's + // `parse` methods. If we import outside of this function, we will get + // circular import errors. + const FILTERS = { + [search.FILTER_AND]: require('../and'), + [search.FILTER_APPROX]: require('../approximate'), + [search.FILTER_EQUALITY]: require('../equality'), + [search.FILTER_EXT]: require('../extensible'), + [search.FILTER_GE]: require('../greater-than-equals'), + [search.FILTER_LE]: require('../less-than-equals'), + [search.FILTER_NOT]: require('../not'), + [search.FILTER_OR]: require('../or'), + [search.FILTER_PRESENT]: require('../presence'), + [search.FILTER_SUBSTRINGS]: require('../substring') + } + + const reader = new BerReader(buffer) + + const seq = reader.readSequence() + if (seq !== startTag) { + const expected = '0x' + startTag.toString(16).padStart(2, '0') + const found = '0x' + seq.toString(16).padStart(2, '0') + throw Error(`expected filter tag ${expected}, got ${found}`) + } + + const filters = [] + const currentFilterLength = reader.length + while (reader.offset < currentFilterLength) { + const tag = reader.peek() + const tagBuffer = reader.readRawBuffer(tag) + const filter = FILTERS[tag].parse(tagBuffer) + filters.push(filter) + } + + if (constructor === FILTERS[search.FILTER_NOT]) { + return new constructor({ filter: filters[0] }) + } + + return new constructor({ filters }) +} diff --git a/node_modules/@ldapjs/filter/lib/filters/utils/parse-nested-filter.test.js b/node_modules/@ldapjs/filter/lib/filters/utils/parse-nested-filter.test.js new file mode 100644 index 0000000..922b2d9 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/filters/utils/parse-nested-filter.test.js @@ -0,0 +1,162 @@ +'use strict' + +const tap = require('tap') +const { search } = require('@ldapjs/protocol') +const parseString = require('../../string-parsing/parse-string') +const parseNestedFilter = require('./parse-nested-filter') + +tap.test('and filter', t => { + const AndFilter = require('../and') + const startTag = search.FILTER_AND + const constructor = AndFilter + + t.test('basic', async t => { + const target = '(&)' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('approximate', async t => { + const target = '(&(cn~=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('equality', async t => { + const target = '(&(cn=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('extensible', async t => { + const target = '(&(:caseExactMatch:=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('greater-than-equals', async t => { + const target = '(&(cn>=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('less-than-equals', async t => { + const target = '(&(cn<=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('not', async t => { + const target = '(&(objectClass=Person)(!(cn=foo)))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('or', async t => { + const target = '(&(objectClass=Person)(|(sn=Jensen)(cn=Babs J*)))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('present', async t => { + const target = '(&(cn=*))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.test('substring', async t => { + const target = '(&(cn=foo*))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.end() +}) + +tap.test('not filter', t => { + const NotFilter = require('../not') + const startTag = search.FILTER_NOT + const constructor = NotFilter + + t.test('basic', async t => { + const target = '(!(cn=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.end() +}) + +tap.test('or filter', t => { + const OrFilter = require('../or') + const startTag = search.FILTER_OR + const constructor = OrFilter + + t.test('basic', async t => { + const target = '(|(cn=foo))' + const input = parseString(target) + const f = parseNestedFilter({ + buffer: input.toBer().buffer, + startTag, + constructor + }) + t.equal(f.toString(), target) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/index.js b/node_modules/@ldapjs/filter/lib/index.js new file mode 100644 index 0000000..302c5ce --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/index.js @@ -0,0 +1,50 @@ +'use strict' + +const testValues = require('./utils/test-values') +const getAttributeValue = require('./utils/get-attribute-value') + +const FilterString = require('./filter-string') +const AndFilter = require('./filters/and') +const ApproximateFilter = require('./filters/approximate') +const EqualityFilter = require('./filters/equality') +const ExtensibleFilter = require('./filters/extensible') +const GreaterThanEqualsFilter = require('./filters/greater-than-equals') +const LessThanEqualsFilter = require('./filters/less-than-equals') +const NotFilter = require('./filters/not') +const OrFilter = require('./filters/or') +const PresenceFilter = require('./filters/presence') +const SubstringFilter = require('./filters/substring') + +const deprecations = require('./deprecations') +const parseString = require('./string-parsing/parse-string') + +module.exports = { + parseBer: require('./ber-parsing'), + + /** + * @deprecated 2022-06-26 Use `parseString` instead. + */ + parse: (string) => { + deprecations.emit('LDAP_FILTER_DEP_001') + return parseString(string) + }, + parseString, + + // Helper utilties for writing custom matchers + testValues, + getAttrValue: getAttributeValue, + getAttributeValue, + + // Filter definitions + FilterString, + AndFilter, + ApproximateFilter, + EqualityFilter, + ExtensibleFilter, + GreaterThanEqualsFilter, + LessThanEqualsFilter, + NotFilter, + OrFilter, + PresenceFilter, + SubstringFilter +} diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/escape-substring.js b/node_modules/@ldapjs/filter/lib/string-parsing/escape-substring.js new file mode 100644 index 0000000..9a51e87 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/escape-substring.js @@ -0,0 +1,33 @@ +'use strict' + +const escapeFilterValue = require('../utils/escape-filter-value') + +/** + * In an extensible filter, the righthand size of the filter can have + * substrings delimeted by `*` characters, e.g. `foo=*foo*bar*baz*`. This + * function is used to encode those substrings. + * + * @param {string} str In `*foo*bar*baz*` it would be `foo*bar*baz`. + * + * @returns {object} An object with extensible filter properties. + * + * @throws When the separator is missing from the input string. + */ +module.exports = function escapeSubstring (str) { + const fields = str.split('*') + const out = { + initial: '', + final: '', + any: [] + } + + if (fields.length <= 1) { + throw Error('extensible filter delimiter missing') + } + + out.initial = escapeFilterValue(fields.shift()) + out.final = escapeFilterValue(fields.pop()) + Array.prototype.push.apply(out.any, fields.map(escapeFilterValue)) + + return out +} diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/escape-substring.test.js b/node_modules/@ldapjs/filter/lib/string-parsing/escape-substring.test.js new file mode 100644 index 0000000..0c429ae --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/escape-substring.test.js @@ -0,0 +1,29 @@ +'use strict' + +const tap = require('tap') +const escapeSubstring = require('./escape-substring') + +tap.test('throws if separator missing', async t => { + t.throws( + () => escapeSubstring('foo'), + Error('extensible filter delimiter missing') + ) +}) + +tap.test('escapes an initial only string', async t => { + const expected = { initial: 'f\\28o', final: '', any: [] } + const result = escapeSubstring('f(o*') + t.strictSame(expected, result) +}) + +tap.test('escapes string with initial and final', async t => { + const expected = { initial: 'f\\28o', final: 'bar', any: [] } + const result = escapeSubstring('f(o*bar') + t.strictSame(expected, result) +}) + +tap.test('escapes string with initial, final, and any', async t => { + const expected = { initial: 'f\\28o', final: 'b\\29f', any: ['bar', 'baz'] } + const result = escapeSubstring('f(o*bar*baz*b)f') + t.strictSame(expected, result) +}) diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-expression.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-expression.js new file mode 100644 index 0000000..7ea3309 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-expression.js @@ -0,0 +1,75 @@ +'use strict' + +const ApproximateFilter = require('../filters/approximate') +const EqualityFilter = require('../filters/equality') +const GreaterThanEqualsFilter = require('../filters/greater-than-equals') +const LessThanEqualsFilter = require('../filters/less-than-equals') +const PresenceFilter = require('../filters/presence') +const SubstringFilter = require('../filters/substring') +const escapeSubstring = require('./escape-substring') +const parseExtensibleFilterString = require('./parse-extensible-filter-string') + +const attrRegex = /^[-_a-zA-Z0-9]+/ + +/** + * Given the expression part of a filter string, e.g. `cn=foo` in `(cn=foo)`, + * parse it into the corresponding filter instance(s). + * + * @param {string} inputString The filter expression to parse. + * + * @returns {FilterString} + * + * @throws When some parsing error occurs. + */ +module.exports = function parseExpr (inputString) { + let attribute + let match + let remainder + + if (inputString[0] === ':' || inputString.indexOf(':=') > 0) { + // An extensible filter can have no attribute name. + return parseExtensibleFilterString(inputString) + } else if ((match = inputString.match(attrRegex)) !== null) { + attribute = match[0] + remainder = inputString.substring(attribute.length) + } else { + throw new Error('invalid attribute name') + } + + if (remainder === '=*') { + return new PresenceFilter({ attribute }) + } else if (remainder[0] === '=') { + remainder = remainder.substring(1) + if (remainder.indexOf('*') !== -1) { + const val = escapeSubstring(remainder) + return new SubstringFilter({ + attribute, + initial: val.initial, + any: val.any, + final: val.final + }) + } else { + return new EqualityFilter({ + attribute, + value: remainder + }) + } + } else if (remainder[0] === '>' && remainder[1] === '=') { + return new GreaterThanEqualsFilter({ + attribute, + value: remainder.substring(2) + }) + } else if (remainder[0] === '<' && remainder[1] === '=') { + return new LessThanEqualsFilter({ + attribute, + value: remainder.substring(2) + }) + } else if (remainder[0] === '~' && remainder[1] === '=') { + return new ApproximateFilter({ + attribute, + value: remainder.substring(2) + }) + } + + throw new Error('invalid expression') +} diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-expression.test.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-expression.test.js new file mode 100644 index 0000000..e90d33e --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-expression.test.js @@ -0,0 +1,106 @@ +'use strict' + +const tap = require('tap') +const parse = require('./parse-expression') + +const ApproximateFilter = require('../filters/approximate') +const EqualityFilter = require('../filters/equality') +const ExtensibleFilter = require('../filters/extensible') +const GreaterThanEqualsFilter = require('../filters/greater-than-equals') +const LessThanEqualsFilter = require('../filters/less-than-equals') +const PresenceFilter = require('../filters/presence') +const SubstringFilter = require('../filters/substring') + +tap.test('throws for invalid attribute name', async t => { + t.throws( + () => parse('$foo=bar'), + Error('invalid attribute name') + ) +}) + +tap.test('throws for invalid exspression', async t => { + t.throws( + () => parse('this is invalid'), + Error('invalid expression') + ) +}) + +tap.test('parses PresenceFilter', async t => { + const result = parse('cn=*') + t.type(result, PresenceFilter) + t.equal(result.toString(), '(cn=*)') +}) + +tap.test('parses a complete SubstringFilter', async t => { + const result = parse('cn=J*o*h*n*D*o*e') + t.type(result, SubstringFilter) + t.equal(result.toString(), '(cn=J*o*h*n*D*o*e)') + t.equal(result.initial, 'J') + t.equal(result.final, 'e') + t.strictSame(result.any, ['o', 'h', 'n', 'D', 'o']) +}) + +tap.test('parses an EqualityFilter', async t => { + const result = parse('cn=foo') + t.type(result, EqualityFilter) + t.equal(result.toString(), '(cn=foo)') +}) + +tap.test('parses an GreaterThanEqualsFilter', async t => { + const result = parse('cn>=foo') + t.type(result, GreaterThanEqualsFilter) + t.equal(result.toString(), '(cn>=foo)') +}) + +tap.test('parses an LessThanEqualsFilter', async t => { + const result = parse('cn<=foo') + t.type(result, LessThanEqualsFilter) + t.equal(result.toString(), '(cn<=foo)') +}) + +tap.test('parses an ApproximateFilter', async t => { + const result = parse('cn~=foo') + t.type(result, ApproximateFilter) + t.equal(result.toString(), '(cn~=foo)') +}) + +tap.test('ExtensibleFilter', t => { + t.test('when expression starts with :', async t => { + const result = parse(':caseExactMatch:=foo') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(:caseExactMatch:=foo)') + }) + + t.test('when expression contains :=', async t => { + const result = parse('sn:caseExactMatch:=foo') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(sn:caseExactMatch:=foo)') + }) + + t.test('missing :=', async t => { + t.throws( + () => parse(':dn:oops'), + Error('missing := in extensible filter string') + ) + }) + + t.end() +}) + +tap.test('parses filter with non-ascii characters', t => { + t.test('í', async t => { + const result = parse('cn=í') + t.type(result, EqualityFilter) + t.equal(result.value, 'í') + t.equal(result.toString(), '(cn=\\c3\\ad)') + }) + + t.test('ø', async t => { + const result = parse('cn=ø') + t.type(result, EqualityFilter) + t.equal(result.value, 'ø') + t.equal(result.toString(), '(cn=\\c3\\b8)') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-extensible-filter-string.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-extensible-filter-string.js new file mode 100644 index 0000000..8751be1 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-extensible-filter-string.js @@ -0,0 +1,46 @@ +'use strict' + +const ExtensibleFilter = require('../filters/extensible') +const escapeFilterValue = require('../utils/escape-filter-value') + +/** + * Parses the string representation of an extensible filter into an + * {@link ExtensibleFilter} instance. Note, the opening and closing + * parentheticals should not be present in the string. + * + * @param {string} filterString Extensible filter string without parentheticals. + * + * @returns {ExtensibleFilter} + * + * @throws When the filter string is missing a `:=`. + */ +module.exports = function parseExtensibleFilterString (filterString) { + const fields = filterString.split(':') + const attribute = escapeFilterValue(fields.shift()) + + const params = { + attribute, + dnAttributes: false, + rule: undefined, + value: undefined + } + + if (fields[0].toLowerCase() === 'dn') { + params.dnAttributes = true + fields.shift() + } + if (fields.length !== 0 && fields[0][0] !== '=') { + params.rule = fields.shift() + } + if (fields.length === 0 || fields[0][0] !== '=') { + // With matchType, dnAttribute, and rule consumed, the := must be next. + throw new Error('missing := in extensible filter string') + } + + // Trim the leading = (from the :=) and reinsert any extra ':' charachters + // which may have been present in the value field. + filterString = fields.join(':').substr(1) + params.value = escapeFilterValue(filterString) + + return new ExtensibleFilter(params) +} diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-extensible-filter-string.test.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-extensible-filter-string.test.js new file mode 100644 index 0000000..8cbb35d --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-extensible-filter-string.test.js @@ -0,0 +1,54 @@ +'use strict' + +const tap = require('tap') +const ExtensibleFilter = require('../filters/extensible') +const parse = require('./parse-extensible-filter-string') + +tap.test('parses simple filter', async t => { + const result = parse('givenName:=John') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(givenName:=John)') +}) + +tap.test('parses dn filter', async t => { + const result = parse('givenName:dn:=John') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(givenName:dn:=John)') +}) + +tap.test('parses rule modified filter', async t => { + const result = parse('givenName:caseExactMatch:=John') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(givenName:caseExactMatch:=John)') +}) + +tap.test('parses oid rule modified filter', async t => { + const result = parse('givenName:dn:2.5.13.5:=John') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(givenName:dn:2.5.13.5:=John)') +}) + +tap.test('parses empty attribute filter', async t => { + const result = parse(':caseExactMatch:=John') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(:caseExactMatch:=John)') +}) + +tap.test('parses empty attribute oid modified with dn filter', async t => { + const result = parse(':dn:2.5.13.5:=John') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(:dn:2.5.13.5:=John)') +}) + +tap.test('re-adds : characters in filter value', async t => { + const result = parse('givenName:=J:o:h:n') + t.type(result, ExtensibleFilter) + t.equal(result.toString(), '(givenName:=J:o:h:n)') +}) + +tap.test('throws if missing : before equals', async t => { + t.throws( + () => parse('givenName:dn:2.5.13.5=John'), + Error('missing := in extensible filter string') + ) +}) diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-filter.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-filter.js new file mode 100644 index 0000000..1fc53bf --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-filter.js @@ -0,0 +1,86 @@ +'use strict' + +const AndFilter = require('../filters/and') +const OrFilter = require('../filters/or') +const NotFilter = require('../filters/not') +const parseExpression = require('./parse-expression') + +const unbalancedError = Error('unbalanced parentheses') + +/** + * @type {object} ParseFilterResult + * @property {number} end The ending position of the most recent iteration + * of the function. + * @property {FilterString} filter The parsed filter instance. + */ + +/** + * Recursively parse an LDAP filter string into a set of {@link FilterString} + * instances. For example, the filter `(&(cn=foo)(sn=bar))` will return an + * {@link AndFilter} instance that has two {@link EqualityFilter} clauses. + * + * @param {string} inputString The filter string, including starting and ending + * parentheticals, to parse. + * @param {number} [start=0] The starting position in the string to start the + * parsing from. Used during recursion when a new sub-expression is encounterd. + * + * @returns {ParseFilterResult} + * + * @throws When any error occurs during parsing. + */ +module.exports = function parseFilter (inputString, start = 0) { + let cur = start + const len = inputString.length + let res + let end + let output + const children = [] + + if (inputString[cur++] !== '(') { + throw Error('missing opening parentheses') + } + + if (inputString[cur] === '&') { + cur++ + if (inputString[cur] === ')') { + output = new AndFilter({}) + } else { + do { + res = parseFilter(inputString, cur) + children.push(res.filter) + cur = res.end + 1 + } while (cur < len && inputString[cur] !== ')') + + output = new AndFilter({ filters: children }) + } + } else if (inputString[cur] === '|') { + cur++ + do { + res = parseFilter(inputString, cur) + children.push(res.filter) + cur = res.end + 1 + } while (cur < len && inputString[cur] !== ')') + + output = new OrFilter({ filters: children }) + } else if (inputString[cur] === '!') { + res = parseFilter(inputString, cur + 1) + output = new NotFilter({ filter: res.filter }) + cur = res.end + 1 + if (inputString[cur] !== ')') { + throw unbalancedError + } + } else { + end = inputString.indexOf(')', cur) + if (end === -1) { + throw unbalancedError + } + + output = parseExpression(inputString.substring(cur, end)) + cur = end + } + + return { + end: cur, + filter: output + } +} diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-filter.test.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-filter.test.js new file mode 100644 index 0000000..bfc2934 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-filter.test.js @@ -0,0 +1,112 @@ +'use strict' + +const tap = require('tap') +const parse = require('./parse-filter') + +const AndFilter = require('../filters/and') +const EqualityFilter = require('../filters/equality') +const NotFilter = require('../filters/not') +const OrFilter = require('../filters/or') + +tap.test('throws if missing opening parentheses', async t => { + t.throws( + () => parse('cn=foo'), + Error('missing opening parentheses') + ) +}) + +tap.test('throws for unbalanced parentheses', async t => { + t.throws( + () => parse('(cn=foo'), + Error('unbalanced parentheses') + ) +}) + +tap.test('AndFilter', t => { + t.test('match all', async t => { + const result = parse('(&)') + t.equal(result.end, 2) + t.type(result.filter, AndFilter) + t.equal(result.filter.toString(), '(&)') + }) + + t.test('simple', async t => { + const result = parse('(&(cn=foo))') + t.equal(result.end, 10) + t.type(result.filter, AndFilter) + t.equal(result.filter.clauses.length, 1) + t.type(result.filter.clauses[0], EqualityFilter) + }) + + t.test('multiple clauses', async t => { + const inputString = '(&(cn=foo)(sn=bar))' + const result = parse(inputString) + t.equal(result.end, inputString.length - 1) + t.type(result.filter, AndFilter) + t.equal(result.filter.clauses.length, 2) + + for (const filter of result.filter.clauses) { + t.type(filter, EqualityFilter) + } + }) + + t.end() +}) + +tap.test('OrFilter', t => { + t.test('simple', async t => { + const result = parse('(|(cn=foo))') + t.equal(result.end, 10) + t.type(result.filter, OrFilter) + t.equal(result.filter.clauses.length, 1) + t.type(result.filter.clauses[0], EqualityFilter) + }) + + t.test('multiple clauses', async t => { + const inputString = '(|(cn=foo)(sn=bar))' + const result = parse(inputString) + t.equal(result.end, inputString.length - 1) + t.type(result.filter, OrFilter) + t.equal(result.filter.clauses.length, 2) + + for (const filter of result.filter.clauses) { + t.type(filter, EqualityFilter) + } + }) + + t.end() +}) + +tap.test('NotFilter', t => { + t.test('simple', async t => { + const result = parse('(!(cn=foo))') + t.equal(result.end, 10) + t.type(result.filter, NotFilter) + t.equal(result.filter.clauses.length, 1) + t.type(result.filter.clauses[0], EqualityFilter) + }) + + t.test('complex', async t => { + const inputString = '(!(&(cn=foo)(sn=bar)))' + const result = parse(inputString) + t.equal(result.end, inputString.length - 1) + t.type(result.filter, NotFilter) + t.equal(result.filter.clauses.length, 1) + + const andFilter = result.filter.clauses[0] + t.type(andFilter, AndFilter) + + for (const filter of andFilter.filter.clauses) { + t.type(filter, EqualityFilter) + } + }) + + t.test('throws for unbalanced parentheses', async t => { + t.throws( + () => parse('(!(cn=foo)'), + Error('unbalanced parentheses') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-string.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-string.js new file mode 100644 index 0000000..2e45134 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-string.js @@ -0,0 +1,35 @@ +'use strict' + +const parseFilter = require('./parse-filter') + +/** + * Parse and LDAP filter string into a {@link FilterString} instance. + * + * @param {string} inputString The LDAP filter string to parse. Can omit the + * leading and terminating parentheses. + * + * @returns {FilterString} + * + * @throws For any error while parsing. + */ +module.exports = function parseString (inputString) { + if (typeof inputString !== 'string') { + throw Error('input must be a string') + } + if (inputString.length < 1) { + throw Error('input string cannot be empty') + } + + let normalizedString = inputString + if (normalizedString.charAt(0) !== '(') { + // Wrap the filter in parentheses since it is not already wrapped. + normalizedString = `(${normalizedString})` + } + + const parsed = parseFilter(normalizedString) + if (parsed.end < inputString.length - 1) { + throw Error('unbalanced parentheses') + } + + return parsed.filter +} diff --git a/node_modules/@ldapjs/filter/lib/string-parsing/parse-string.test.js b/node_modules/@ldapjs/filter/lib/string-parsing/parse-string.test.js new file mode 100644 index 0000000..0f8947d --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/string-parsing/parse-string.test.js @@ -0,0 +1,485 @@ +'use strict' + +const tap = require('tap') +const parse = require('./parse-string') + +const EqualityFilter = require('../filters/equality') +function checkFilters (t, expectedObjects) { + for (const expected of expectedObjects) { + const f = parse(expected.str) + t.ok(f, 'Parsed "' + expected.str + '"') + t.equal(f.type, expected.type) + t.equal(f.attribute, 'foo') + t.equal(f.value, expected.val) + t.equal(f.toString(), expected.output) + } +} + +tap.test('requires valid input', async t => { + t.throws( + () => parse(), + Error('input must be a string') + ) + t.throws( + () => parse(''), + Error('input string cannot be empty') + ) +}) + +tap.test('wraps a string with parentheses', async t => { + const f = parse('cn=foo') + t.type(f, EqualityFilter) + t.equal(f.toString(), '(cn=foo)') +}) + +tap.test('parses a filter', async t => { + const f = parse('(cn=foo)') + t.type(f, EqualityFilter) + t.equal(f.toString(), '(cn=foo)') +}) + +tap.test('XML Strings in filter', async t => { + const str = '(&(CentralUIEnrollments=*)(objectClass=User))' + const f = parse(str) + t.ok(f) + t.ok(f.filters) + t.equal(f.filters.length, 2) + + for (const filter of f.filters) { + t.ok(filter.attribute) + } +}) + +tap.test('= in filter', async t => { + const str = '(uniquemember=uuid=930896af-bf8c-48d4-885c-6573a94b1853, ' + + 'ou=users, o=smartdc)' + const f = parse(str) + t.ok(f) + t.equal(f.attribute, 'uniquemember') + t.equal(f.value, + 'uuid=930896af-bf8c-48d4-885c-6573a94b1853, ou=users, o=smartdc') + t.equal(f.toString(), + '(uniquemember=uuid=930896af-bf8c-48d4-885c-6573a94b1853, ' + + 'ou=users, o=smartdc)') +}) + +tap.test('( in filter', async t => { + const str = 'foo=bar\\28' + const f = parse(str) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar\\28') + t.equal(f.toString(), '(foo=bar\\28)') +}) + +tap.test(') in filter', async t => { + const str = '(foo=bar\\29)' + const f = parse(str) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar\\29') + t.equal(f.toString(), '(foo=bar\\29)') +}) + +tap.test('newlines in filter', async t => { + const v1 = '\\0a' + const v1Literal = '\n' + const v2 = 'bar\\0a' + const v2Literal = 'bar\n' + const v3 = '\\0abar' + const v3Literal = '\nbar' + checkFilters(t, [ + { str: '(foo=\n)', type: 'EqualityFilter', val: v1Literal, output: '(foo=\\0a)' }, + { str: '(foo<=\n)', type: 'LessThanEqualsFilter', val: v1Literal, output: '(foo<=\\0a)' }, + { str: '(foo>=\n)', type: 'GreaterThanEqualsFilter', val: v1Literal, output: '(foo>=\\0a)' }, + { str: '(foo=\\0a)', type: 'EqualityFilter', val: v1, output: '(foo=\\0a)' }, + { str: '(foo<=\\0a)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\0a)' }, + { str: '(foo>=\\0a)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\0a)' }, + { str: '(foo=bar\n)', type: 'EqualityFilter', val: v2Literal, output: '(foo=bar\\0a)' }, + { str: '(foo<=bar\n)', type: 'LessThanEqualsFilter', val: v2Literal, output: '(foo<=bar\\0a)' }, + { str: '(foo>=bar\n)', type: 'GreaterThanEqualsFilter', val: v2Literal, output: '(foo>=bar\\0a)' }, + { str: '(foo=bar\\0a)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\0a)' }, + { str: '(foo<=bar\\0a)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\0a)' }, + { str: '(foo>=bar\\0a)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\0a)' }, + { str: '(foo=\nbar)', type: 'EqualityFilter', val: v3Literal, output: '(foo=\\0abar)' }, + { str: '(foo<=\nbar)', type: 'LessThanEqualsFilter', val: v3Literal, output: '(foo<=\\0abar)' }, + { str: '(foo>=\nbar)', type: 'GreaterThanEqualsFilter', val: v3Literal, output: '(foo>=\\0abar)' }, + { str: '(foo=\\0abar)', type: 'EqualityFilter', val: v3, output: '(foo=\\0abar)' }, + { str: '(foo<=\\0abar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\0abar)' }, + { str: '(foo>=\\0abar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\0abar)' } + ]) +}) + +tap.test('carriage returns in filter', async t => { + const v1 = '\\0d' + const v1Literal = '\r' + const v2 = 'bar\\0d' + const v2Literal = 'bar\r' + const v3 = '\\0dbar' + const v3Literal = '\rbar' + checkFilters(t, [ + { str: '(foo=\r)', type: 'EqualityFilter', val: v1Literal, output: '(foo=\\0d)' }, + { str: '(foo<=\r)', type: 'LessThanEqualsFilter', val: v1Literal, output: '(foo<=\\0d)' }, + { str: '(foo>=\r)', type: 'GreaterThanEqualsFilter', val: v1Literal, output: '(foo>=\\0d)' }, + { str: '(foo=\\0d)', type: 'EqualityFilter', val: v1, output: '(foo=\\0d)' }, + { str: '(foo<=\\0d)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\0d)' }, + { str: '(foo>=\\0d)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\0d)' }, + { str: '(foo=bar\r)', type: 'EqualityFilter', val: v2Literal, output: '(foo=bar\\0d)' }, + { str: '(foo<=bar\r)', type: 'LessThanEqualsFilter', val: v2Literal, output: '(foo<=bar\\0d)' }, + { str: '(foo>=bar\r)', type: 'GreaterThanEqualsFilter', val: v2Literal, output: '(foo>=bar\\0d)' }, + { str: '(foo=bar\\0d)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\0d)' }, + { str: '(foo<=bar\\0d)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\0d)' }, + { str: '(foo>=bar\\0d)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\0d)' }, + { str: '(foo=\rbar)', type: 'EqualityFilter', val: v3Literal, output: '(foo=\\0dbar)' }, + { str: '(foo<=\rbar)', type: 'LessThanEqualsFilter', val: v3Literal, output: '(foo<=\\0dbar)' }, + { str: '(foo>=\rbar)', type: 'GreaterThanEqualsFilter', val: v3Literal, output: '(foo>=\\0dbar)' }, + { str: '(foo=\\0dbar)', type: 'EqualityFilter', val: v3, output: '(foo=\\0dbar)' }, + { str: '(foo<=\\0dbar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\0dbar)' }, + { str: '(foo>=\\0dbar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\0dbar)' } + ]) +}) + +tap.test('tabs in filter', async t => { + const v1 = '\\09' + const v1Literal = '\t' + const v2 = 'bar\\09' + const v2Literal = 'bar\t' + const v3 = '\\09bar' + const v3Literal = '\tbar' + checkFilters(t, [ + { str: '(foo=\t)', type: 'EqualityFilter', val: v1Literal, output: '(foo=\\09)' }, + { str: '(foo<=\t)', type: 'LessThanEqualsFilter', val: v1Literal, output: '(foo<=\\09)' }, + { str: '(foo>=\t)', type: 'GreaterThanEqualsFilter', val: v1Literal, output: '(foo>=\\09)' }, + { str: '(foo=\\09)', type: 'EqualityFilter', val: v1, output: '(foo=\\09)' }, + { str: '(foo<=\\09)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=\\09)' }, + { str: '(foo>=\\09)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=\\09)' }, + { str: '(foo=bar\t)', type: 'EqualityFilter', val: v2Literal, output: '(foo=bar\\09)' }, + { str: '(foo<=bar\t)', type: 'LessThanEqualsFilter', val: v2Literal, output: '(foo<=bar\\09)' }, + { str: '(foo>=bar\t)', type: 'GreaterThanEqualsFilter', val: v2Literal, output: '(foo>=bar\\09)' }, + { str: '(foo=bar\\09)', type: 'EqualityFilter', val: v2, output: '(foo=bar\\09)' }, + { str: '(foo<=bar\\09)', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar\\09)' }, + { str: '(foo>=bar\\09)', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar\\09)' }, + { str: '(foo=\tbar)', type: 'EqualityFilter', val: v3Literal, output: '(foo=\\09bar)' }, + { str: '(foo<=\tbar)', type: 'LessThanEqualsFilter', val: v3Literal, output: '(foo<=\\09bar)' }, + { str: '(foo>=\tbar)', type: 'GreaterThanEqualsFilter', val: v3Literal, output: '(foo>=\\09bar)' }, + { str: '(foo=\\09bar)', type: 'EqualityFilter', val: v3, output: '(foo=\\09bar)' }, + { str: '(foo<=\\09bar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\09bar)' }, + { str: '(foo>=\\09bar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\09bar)' } + ]) +}) + +tap.test('spaces in filter', async t => { + const v1 = ' ' + const v2 = 'bar ' + const v3 = ' bar' + checkFilters(t, [ + { str: '(foo= )', type: 'EqualityFilter', val: v1, output: '(foo= )' }, + { str: '(foo<= )', type: 'LessThanEqualsFilter', val: v1, output: '(foo<= )' }, + { str: '(foo>= )', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>= )' }, + { str: '(foo=\\20)', type: 'EqualityFilter', val: '\\20', output: '(foo=\\20)' }, + { str: '(foo<=\\20)', type: 'LessThanEqualsFilter', val: '\\20', output: '(foo<=\\20)' }, + { str: '(foo>=\\20)', type: 'GreaterThanEqualsFilter', val: '\\20', output: '(foo>=\\20)' }, + { str: '(foo=bar )', type: 'EqualityFilter', val: v2, output: '(foo=bar )' }, + { str: '(foo<=bar )', type: 'LessThanEqualsFilter', val: v2, output: '(foo<=bar )' }, + { str: '(foo>=bar )', type: 'GreaterThanEqualsFilter', val: v2, output: '(foo>=bar )' }, + { str: '(foo=bar\\20)', type: 'EqualityFilter', val: 'bar\\20', output: '(foo=bar\\20)' }, + { str: '(foo<=bar\\20)', type: 'LessThanEqualsFilter', val: 'bar\\20', output: '(foo<=bar\\20)' }, + { str: '(foo>=bar\\20)', type: 'GreaterThanEqualsFilter', val: 'bar\\20', output: '(foo>=bar\\20)' }, + { str: '(foo= bar)', type: 'EqualityFilter', val: v3, output: '(foo= bar)' }, + { str: '(foo<= bar)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<= bar)' }, + { str: '(foo>= bar)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>= bar)' }, + { str: '(foo=\\20bar)', type: 'EqualityFilter', val: '\\20bar', output: '(foo=\\20bar)' }, + { str: '(foo<=\\20bar)', type: 'LessThanEqualsFilter', val: '\\20bar', output: '(foo<=\\20bar)' }, + { str: '(foo>=\\20bar)', type: 'GreaterThanEqualsFilter', val: '\\20bar', output: '(foo>=\\20bar)' } + ]) +}) + +tap.test('literal \\ in filter', async t => { + const v1 = 'bar\\5c' + const v2 = '\\5cbar\\5cbaz\\5c' + const v3 = '\\5c' + checkFilters(t, [ + { str: '(foo=bar\\5c)', type: 'EqualityFilter', val: v1, output: '(foo=bar\\5c)' }, + { str: '(foo<=bar\\5c)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=bar\\5c)' }, + { str: '(foo>=bar\\5c)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=bar\\5c)' }, + { + str: '(foo=\\5cbar\\5cbaz\\5c)', + type: 'EqualityFilter', + val: v2, + output: '(foo=\\5cbar\\5cbaz\\5c)' + }, + { + str: '(foo>=\\5cbar\\5cbaz\\5c)', + type: 'GreaterThanEqualsFilter', + val: v2, + output: '(foo>=\\5cbar\\5cbaz\\5c)' + }, + { + str: '(foo<=\\5cbar\\5cbaz\\5c)', + type: 'LessThanEqualsFilter', + val: v2, + output: '(foo<=\\5cbar\\5cbaz\\5c)' + }, + { str: '(foo=\\5c)', type: 'EqualityFilter', val: v3, output: '(foo=\\5c)' }, + { str: '(foo<=\\5c)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\5c)' }, + { str: '(foo>=\\5c)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\5c)' } + ]) +}) + +tap.test('\\0 in filter', async t => { + const str = '(foo=bar\\00)' + const f = parse(str) + t.ok(f) + t.equal(f.attribute, 'foo') + t.equal(f.value, 'bar\\00') + t.equal(f.toString(), '(foo=bar\\00)') +}) + +tap.test('literal * in filters', async t => { + const v1 = 'bar\\2a' + const v2 = '\\2abar\\2abaz\\2a' + const v3 = '\\2a' + checkFilters(t, [ + { str: '(foo=bar\\2a)', type: 'EqualityFilter', val: v1, output: '(foo=bar\\2a)' }, + { str: '(foo<=bar\\2a)', type: 'LessThanEqualsFilter', val: v1, output: '(foo<=bar\\2a)' }, + { str: '(foo>=bar\\2a)', type: 'GreaterThanEqualsFilter', val: v1, output: '(foo>=bar\\2a)' }, + { + str: '(foo=\\2abar\\2abaz\\2a)', + type: 'EqualityFilter', + val: v2, + output: '(foo=\\2abar\\2abaz\\2a)' + }, + { + str: '(foo>=\\2abar\\2abaz\\2a)', + type: 'GreaterThanEqualsFilter', + val: v2, + output: '(foo>=\\2abar\\2abaz\\2a)' + }, + { + str: '(foo<=\\2abar\\2abaz\\2a)', + type: 'LessThanEqualsFilter', + val: v2, + output: '(foo<=\\2abar\\2abaz\\2a)' + }, + { str: '(foo=\\2a)', type: 'EqualityFilter', val: v3, output: '(foo=\\2a)' }, + { str: '(foo<=\\2a)', type: 'LessThanEqualsFilter', val: v3, output: '(foo<=\\2a)' }, + { str: '(foo>=\\2a)', type: 'GreaterThanEqualsFilter', val: v3, output: '(foo>=\\2a)' } + ]) +}) + +tap.test('escaped * in substr filter (prefix)', async t => { + const str = '(foo=bar\\2a*)' + const f = parse(str) + t.ok(f) + t.equal(f.type, 'SubstringFilter') + t.equal(f.attribute, 'foo') + t.equal(f.initial, 'bar\\2a') + t.equal(f.any.length, 0) + t.equal(f.final, '') + t.equal(f.toString(), '(foo=bar\\2a*)') +}) + +tap.test('<= in filters', async t => { + checkFilters(t, [ + { str: '(foo=<=)', type: 'EqualityFilter', val: '<=', output: '(foo=<=)' }, + { str: '(foo<=<=)', type: 'LessThanEqualsFilter', val: '<=', output: '(foo<=<=)' }, + { str: '(foo>=<=)', type: 'GreaterThanEqualsFilter', val: '<=', output: '(foo>=<=)' }, + { + str: '(foo=bar<=baz)', + type: 'EqualityFilter', + val: 'bar<=baz', + output: '(foo=bar<=baz)' + }, + { + str: '(foo<=bar<=baz)', + type: 'LessThanEqualsFilter', + val: 'bar<=baz', + output: '(foo<=bar<=baz)' + }, + { + str: '(foo>=bar<=baz)', + type: 'GreaterThanEqualsFilter', + val: 'bar<=baz', + output: '(foo>=bar<=baz)' + }, + { + str: '(foo=bar<=)', + type: 'EqualityFilter', + val: 'bar<=', + output: '(foo=bar<=)' + }, + { str: '(foo<=bar<=)', type: 'LessThanEqualsFilter', val: 'bar<=', output: '(foo<=bar<=)' }, + { str: '(foo>=bar<=)', type: 'GreaterThanEqualsFilter', val: 'bar<=', output: '(foo>=bar<=)' } + ]) +}) + +tap.test('>= in filters', async t => { + checkFilters(t, [ + { str: '(foo=>=)', type: 'EqualityFilter', val: '>=', output: '(foo=>=)' }, + { str: '(foo<=>=)', type: 'LessThanEqualsFilter', val: '>=', output: '(foo<=>=)' }, + { str: '(foo>=>=)', type: 'GreaterThanEqualsFilter', val: '>=', output: '(foo>=>=)' }, + { + str: '(foo=bar>=baz)', + type: 'EqualityFilter', + val: 'bar>=baz', + output: '(foo=bar>=baz)' + }, + { + str: '(foo<=bar>=baz)', + type: 'LessThanEqualsFilter', + val: 'bar>=baz', + output: '(foo<=bar>=baz)' + }, + { + str: '(foo>=bar>=baz)', + type: 'GreaterThanEqualsFilter', + val: 'bar>=baz', + output: '(foo>=bar>=baz)' + }, + { str: '(foo=bar>=)', type: 'EqualityFilter', val: 'bar>=', output: '(foo=bar>=)' }, + { str: '(foo<=bar>=)', type: 'LessThanEqualsFilter', val: 'bar>=', output: '(foo<=bar>=)' }, + { str: '(foo>=bar>=)', type: 'GreaterThanEqualsFilter', val: 'bar>=', output: '(foo>=bar>=)' } + ]) +}) + +tap.test('& in filters', async t => { + checkFilters(t, [ + { str: '(foo=&)', type: 'EqualityFilter', val: '&', output: '(foo=&)' }, + { str: '(foo<=&)', type: 'LessThanEqualsFilter', val: '&', output: '(foo<=&)' }, + { str: '(foo>=&)', type: 'GreaterThanEqualsFilter', val: '&', output: '(foo>=&)' }, + { + str: '(foo=bar&baz)', + type: 'EqualityFilter', + val: 'bar&baz', + output: '(foo=bar&baz)' + }, + { + str: '(foo<=bar&baz)', + type: 'LessThanEqualsFilter', + val: 'bar&baz', + output: '(foo<=bar&baz)' + }, + { + str: '(foo>=bar&baz)', + type: 'GreaterThanEqualsFilter', + val: 'bar&baz', + output: '(foo>=bar&baz)' + }, + { str: '(foo=bar&)', type: 'EqualityFilter', val: 'bar&', output: '(foo=bar&)' }, + { str: '(foo<=bar&)', type: 'LessThanEqualsFilter', val: 'bar&', output: '(foo<=bar&)' }, + { str: '(foo>=bar&)', type: 'GreaterThanEqualsFilter', val: 'bar&', output: '(foo>=bar&)' } + ]) +}) + +tap.test('| in filters', async t => { + checkFilters(t, [ + { str: '(foo=|)', type: 'EqualityFilter', val: '|', output: '(foo=|)' }, + { str: '(foo<=|)', type: 'LessThanEqualsFilter', val: '|', output: '(foo<=|)' }, + { str: '(foo>=|)', type: 'GreaterThanEqualsFilter', val: '|', output: '(foo>=|)' }, + { + str: '(foo=bar|baz)', + type: 'EqualityFilter', + val: 'bar|baz', + output: '(foo=bar|baz)' + }, + { + str: '(foo<=bar|baz)', + type: 'LessThanEqualsFilter', + val: 'bar|baz', + output: '(foo<=bar|baz)' + }, + { + str: '(foo>=bar|baz)', + type: 'GreaterThanEqualsFilter', + val: 'bar|baz', + output: '(foo>=bar|baz)' + }, + { str: '(foo=bar|)', type: 'EqualityFilter', val: 'bar|', output: '(foo=bar|)' }, + { str: '(foo<=bar|)', type: 'LessThanEqualsFilter', val: 'bar|', output: '(foo<=bar|)' }, + { str: '(foo>=bar|)', type: 'GreaterThanEqualsFilter', val: 'bar|', output: '(foo>=bar|)' } + ]) +}) + +tap.test('! in filters', async t => { + checkFilters(t, [ + { str: '(foo=!)', type: 'EqualityFilter', val: '!', output: '(foo=!)' }, + { str: '(foo<=!)', type: 'LessThanEqualsFilter', val: '!', output: '(foo<=!)' }, + { str: '(foo>=!)', type: 'GreaterThanEqualsFilter', val: '!', output: '(foo>=!)' }, + { + str: '(foo=bar!baz)', + type: 'EqualityFilter', + val: 'bar!baz', + output: '(foo=bar!baz)' + }, + { + str: '(foo<=bar!baz)', + type: 'LessThanEqualsFilter', + val: 'bar!baz', + output: '(foo<=bar!baz)' + }, + { + str: '(foo>=bar!baz)', + type: 'GreaterThanEqualsFilter', + val: 'bar!baz', + output: '(foo>=bar!baz)' + }, + { str: '(foo=bar!)', type: 'EqualityFilter', val: 'bar!', output: '(foo=bar!)' }, + { str: '(foo<=bar!)', type: 'LessThanEqualsFilter', val: 'bar!', output: '(foo<=bar!)' }, + { str: '(foo>=bar!)', type: 'GreaterThanEqualsFilter', val: 'bar!', output: '(foo>=bar!)' } + ]) +}) + +tap.test('bogus filters', async t => { + t.throws(() => parse('foo>1'), 'junk') + + t.throws(() => parse('(&(valid=notquite)())'), 'empty parens') + + t.throws(() => parse('(&(valid=notquite)wut)'), 'cruft inside AndFilter') + + t.throws(() => parse('foo!=1'), 'fake operator') +}) + +tap.test('mismatched parens', async t => { + t.throws(() => parse('(foo=1'), 'missing last paren') + + t.throws(() => parse('(foo=1\\29'), 'missing last paren') + + t.throws(() => parse('foo=1)a)'), 'trailing paren') + + t.throws(() => parse('(foo=1)trailing'), 'trailing text') + + t.throws(() => parse('leading(foo=1)'), 'leading text') +}) + +tap.test('garbage in subfilter not allowed', async t => { + t.throws(() => parse('(&(foo=bar)|(baz=quux)(hello=world))'), '| subfilter without parens not allowed') + + t.throws(() => parse('(&(foo=bar)!(baz=quux)(hello=world))'), '! subfilter without parens not allowed') + + t.throws(() => parse('(&(foo=bar)&(baz=quux)(hello=world))'), '& subfilter without parens not allowed') + + t.throws(() => parse('(&(foo=bar)g(baz=quux)(hello=world))')) + + t.throws(() => parse('(&(foo=bar)=(baz=quux)(hello=world))')) + + t.throws(() => parse('(&foo=bar)')) + + t.throws(() => parse('(|foo=bar)')) + + t.throws(() => parse('(!foo=bar)')) + + t.throws(() => parse('(!(foo=bar)a')) +}) + +tap.test('nested parens', async t => { + t.throws(() => parse('((foo=bar))')) +}) + +tap.test('tolerate underscores in names', async t => { + let f = parse('(foo_bar=val)') + t.ok(f) + t.equal(f.attribute, 'foo_bar') + f = parse('(_leading=val)') + t.ok(f) + t.equal(f.attribute, '_leading') +}) diff --git a/node_modules/@ldapjs/filter/lib/traverse.test.js b/node_modules/@ldapjs/filter/lib/traverse.test.js new file mode 100644 index 0000000..ca168c3 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/traverse.test.js @@ -0,0 +1,174 @@ +// Copyright 2014 Patrick Mooney. All rights reserved. +'use strict' + +const { test } = require('tap') + +const filters = require('./index') + +test('foreach single', function (t) { + const f = filters.parseString('(foo=bar)') + let count = 0 + f.forEach(function (item) { + t.equal(item.attribute, 'foo') + t.equal(item.value, 'bar') + count++ + }) + t.equal(count, 1) + t.end() +}) + +test('foreach not', function (t) { + const f = filters.parseString('(!(foo=bar))') + const order = [] + let count = 0 + + f.forEach(function (item) { + order.push(item.type) + if (item.type === 'EqualityFilter') { + t.equal(item.attribute, 'foo') + t.equal(item.value, 'bar') + } + count++ + }) + t.equal(count, 2) + t.same(order, ['EqualityFilter', 'NotFilter']) + t.end() +}) + +test('foreach multiple', function (t) { + const f = filters.parseString('(|(foo=bar)(baz>=bip))') + const order = [] + let count = 0 + + f.forEach(function (item) { + order.push(item.type) + switch (item.type) { + case 'EqualityFilter': + t.equal(item.attribute, 'foo') + t.equal(item.value, 'bar') + break + case 'ge': + t.equal(item.attribute, 'baz') + t.equal(item.value, 'bip') + break + case 'or': + t.equal(item.filters.length, 2) + break + default: + break + } + count++ + }) + t.equal(count, 3) + t.same(order, ['EqualityFilter', 'GreaterThanEqualsFilter', 'OrFilter']) + t.end() +}) + +test('foreach complex', function (t) { + const f = filters.parseString('(|(!(&(foo=bar)(num<=5)))(baz>=bip))') + const correct = ['EqualityFilter', 'LessThanEqualsFilter', 'AndFilter', 'NotFilter', 'GreaterThanEqualsFilter', 'OrFilter'] + const order = [] + let count = 0 + + f.forEach(function (item) { + order.push(item.type) + count++ + }) + t.same(order, correct) + t.equal(count, correct.length) + t.end() +}) + +test('map single valid', function (t) { + const f = filters.parseString('(foo=bar)') + const n = f.map(function (item) { + item.value = 'new' + return item + }) + t.ok(n) + t.equal(n.value, 'new') + t.end() +}) + +test('map single null', function (t) { + const f = filters.parseString('(foo=bar)') + const n = f.map(function (item) { + return null + }) + t.equal(n, null) + t.end() +}) + +test('map not valid', function (t) { + const f = filters.parseString('(!(foo=bar))') + f.map(function (item) { + if (item.attribute) { + item.value = 'new' + } + return item + }) + t.equal(f.toString(), '(!(foo=new))') + t.end() +}) + +test('map not null', function (t) { + const f = filters.parseString('(!(foo=bar))') + const n = f.map(function (item) { + if (item.attribute) { + return null + } + return item + }) + t.equal(n, null) + t.end() +}) + +test('map multiple', function (t) { + const f = filters.parseString('(|(foo=1)(bar=2))') + const n = f.map(function (item) { + if (item.attribute) { + item.value = '' + (parseInt(item.value, 10) + 1) + } + return item + }) + t.equal(n.toString(), '(|(foo=2)(bar=3))') + t.end() +}) + +test('map multiple some-null', function (t) { + const f = filters.parseString('(|(foo=1)(bar=2))') + const n = f.map(function (item) { + if (item.attribute && item.attribute === 'foo') { + return null + } + return item + }) + t.equal(n.toString(), '(|(bar=2))') + t.end() +}) + +test('map multiple all-null', function (t) { + const f = filters.parseString('(|(foo=1)(bar=2))') + const n = f.map(function (item) { + if (item.attribute) { + return null + } + return item + }) + t.equal(n, null) + t.end() +}) + +test('map complex', function (t) { + const f = filters.parseString('(|(bad=foo)(num>=1)(!(bad=bar))(&(ok=foo)(good=bar)))') + const n = f.map(function (item) { + if (item.attribute && item.attribute === 'bad') { + return null + } else if (item.type === 'GreaterThanEqualsFilter') { + item.value = '' + (parseInt(item.value, 10) + 1) + } + return item + }) + t.equal(n.toString(), '(|(num>=2)(&(ok=foo)(good=bar)))') + t.end() +}) diff --git a/node_modules/@ldapjs/filter/lib/utils/escape-filter-value.js b/node_modules/@ldapjs/filter/lib/utils/escape-filter-value.js new file mode 100644 index 0000000..62808e7 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/utils/escape-filter-value.js @@ -0,0 +1,158 @@ +'use strict' + +module.exports = escapeFilterValue + +/** + * Escapes LDAP filter attribute values. For example, + * in the filter `(cn=föo)`, this function would be used + * to encode `föo` to `f\c3\b6o`. Already encoded values + * will be left intact. + * + * @param {string|Buffer} toEscape + * + * @returns {string} + * + * @see https://datatracker.ietf.org/doc/html/rfc4515 + */ +function escapeFilterValue (toEscape) { + if (typeof toEscape === 'string') { + return escapeBuffer(Buffer.from(toEscape)) + } + + if (Buffer.isBuffer(toEscape)) { + return escapeBuffer(toEscape) + } + + throw Error('toEscape must be a string or a Buffer') +} + +function escapeBuffer (buf) { + let result = '' + for (let i = 0; i < buf.length; i += 1) { + if (buf[i] >= 0xc0 && buf[i] <= 0xdf) { + // Represents the first byte in a 2-byte UTF-8 character. + result += '\\' + buf[i].toString(16) + '\\' + buf[i + 1].toString(16) + i += 1 + continue + } + + if (buf[i] >= 0xe0 && buf[i] <= 0xef) { + // Represents the first byte in a 3-byte UTF-8 character. + result += [ + '\\', buf[i].toString(16), + '\\', buf[i + 1].toString(16), + '\\', buf[i + 2].toString(16) + ].join('') + i += 2 + continue + } + + if (buf[i] <= 31) { + // It's an ASCII control character so we will straight + // encode it (excluding the "space" character). + result += '\\' + buf[i].toString(16).padStart(2, '0') + continue + } + + const char = String.fromCharCode(buf[i]) + switch (char) { + case '*': { + result += '\\2a' + break + } + + case '(': { + result += '\\28' + break + } + + case ')': { + result += '\\29' + break + } + + case '\\': { + // result += '\\5c' + // It looks like we have encountered an already escaped sequence + // of characters. So we will attempt to read that sequence as-is. + const escapedChars = readEscapedCharacters(buf, i) + i += escapedChars.length + result += escapedChars.join('') + break + } + + default: { + result += char + break + } + } + } + return result +} + +/** + * In a buffer that represents a string with escaped character code + * sequences, e.g. `'foo\\2a'`, read the escaped character code sequence + * and return it as a string. If an invalid escape sequence is encountered, + * it will be assumed that the sequence needs to be escaped and the returned + * string will include the escaped sequence. + * + * @param {Buffer} buf + * @param {number} start Starting offset of the escaped character sequence + * in the buffer + * + * @returns {string} + */ +function readEscapedCharacters (buf, start) { + const chars = [] + + for (let i = start; ;) { + if (buf[i] === undefined) { + // The sequence was a terminating `\`. So we actually want + // to escape it. Therefore, replace the read `\` with the + // ecape sequence. + chars[-1] = '\\5c' + break + } + + if (buf[i] === 0x5c) { // read `\` character + chars.push('\\') + i += 1 + continue + } + + const strHexCode = String.fromCharCode(buf[i]) + String.fromCharCode(buf[i + 1]) + const hexCode = parseInt(strHexCode, 16) + if (Number.isNaN(hexCode)) { + // The next two bytes do not comprise a hex code. Therefore, + // we really want to escape the previous `\` character and append + // the next two characters. + chars.push('5c' + strHexCode) + break + } + + if (hexCode >= 0xc0 && hexCode <= 0xdf) { + // Handle 2-byte character code. + chars.push(hexCode.toString(16).padEnd(2, '0')) + for (let x = i + 2; x < i + 4; x += 1) { + chars.push(String.fromCharCode(buf[x])) + } + break + } + + if (hexCode >= 0xe0 && hexCode <= 0xef) { + // Handle 3-byte character code. + chars.push(hexCode.toString(16).padStart(2, '0')) + for (let x = i + 2; x < i + 8; x += 1) { + chars.push(String.fromCharCode(buf[x])) + } + break + } + + // Single byte escaped code. + chars.push(hexCode.toString(16).padStart(2, '0')) + break + } + + return chars +} diff --git a/node_modules/@ldapjs/filter/lib/utils/escape-filter-value.test.js b/node_modules/@ldapjs/filter/lib/utils/escape-filter-value.test.js new file mode 100644 index 0000000..e7ac53d --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/utils/escape-filter-value.test.js @@ -0,0 +1,85 @@ +'use strict' + +const tap = require('tap') +const escapeFilterValue = require('./escape-filter-value') + +// See https://datatracker.ietf.org/doc/html/rfc4515#section-4 +tap.test('escapes all rfc defined characters (string)', async t => { + const expected = [ + 'Parens R Us \\28for all your parenthetical needs\\29', + '\\2a', + 'C:\\5cMyFile', + '\\00\\00\\00\\04', + 'Lu\\c4\\8di\\c5\\87', + 'f\\c3\\b6o' + ] + const inputs = [ + 'Parens R Us (for all your parenthetical needs)', + '*', + 'C:\\MyFile', + Buffer.from([0x00, 0x00, 0x00, 0x04]).toString(), + 'LučiŇ', + 'föo' + ] + + for (let i = 0; i < expected.length; i += 1) { + t.equal(escapeFilterValue(inputs[i]), expected[i]) + } +}) + +// See https://datatracker.ietf.org/doc/html/rfc4515#section-4 +tap.test('escapes all rfc defined characters (buffer)', async t => { + const expected = [ + 'Parens R Us \\28for all your parenthetical needs\\29', + '\\2a', + 'C:\\5cMyFile', + '\\00\\00\\00\\04', + 'Lu\\c4\\8di\\c5\\87', + 'f\\c3\\b6o' + ] + const inputs = [ + Buffer.from('Parens R Us (for all your parenthetical needs)'), + Buffer.from('*'), + Buffer.from('C:\\MyFile'), + Buffer.from([0x00, 0x00, 0x00, 0x04]), + Buffer.from('LučiŇ'), + Buffer.from('föo') + ] + + for (let i = 0; i < expected.length; i += 1) { + t.equal(escapeFilterValue(inputs[i]), expected[i]) + } +}) + +tap.test('needs string or buffer', async t => { + t.throws(() => escapeFilterValue([42])) +}) + +tap.test('encodes 3-byte utf-8', async t => { + const input = 'ᎢᏣᎵᏍᎠᏁᏗ' + const expected = '\\e1\\8e\\a2\\e1\\8f\\a3\\e1\\8e\\b5\\e1\\8f\\8d\\e1\\8e\\a0\\e1\\8f\\81\\e1\\8f\\97' + t.equal(escapeFilterValue(input), expected) +}) + +tap.test('leaves encoded characters intact', async t => { + const inputs = [ + 'foo\\2a', // 'foo* + 'f\\c3\\b6o', // 'föo' + '\\e1\\8e\\a2cp', // 'Ꭲcp' + 'a*\\2ab*c', + 'bar\\', + 'foo>=\\5c' + ] + const expected = [ + 'foo\\2a', + 'f\\c3\\b6o', + '\\e1\\8e\\a2cp', + 'a\\2a\\2ab\\2ac', + 'bar\\', + 'foo>=\\5c' + ] + for (let i = 0; i < inputs.length; i += 1) { + const result = escapeFilterValue(inputs[i]) + t.equal(result, expected[i]) + } +}) diff --git a/node_modules/@ldapjs/filter/lib/utils/get-attribute-value.js b/node_modules/@ldapjs/filter/lib/utils/get-attribute-value.js new file mode 100644 index 0000000..32cf180 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/utils/get-attribute-value.js @@ -0,0 +1,40 @@ +'use strict' + +module.exports = getAttributeValue + +/** + * Fetch value for named object attribute. + * + * @param {object} input + * @param {object} input.sourceObject object to fetch value from + * @param {string} input.attributeName name of attribute to fetch + * @param {boolean} [input.strictCase=false] attribute name is case-sensitive + */ +function getAttributeValue ({ sourceObject, attributeName, strictCase = false }) { + if (Object.prototype.toString.call(sourceObject) === '[object LdapAttribute]') { + sourceObject = { + [sourceObject.type]: sourceObject.values + } + } + + if (Object.prototype.toString.call(sourceObject) !== '[object Object]') { + throw Error('sourceObject must be an object') + } + if (typeof attributeName !== 'string') { + throw Error('attributeName must be a string') + } + + // Check for exact case match first + if (Object.prototype.hasOwnProperty.call(sourceObject, attributeName)) { + return sourceObject[attributeName] + } else if (strictCase === true) { + return undefined + } + + // Perform case-insensitive enumeration after that + const lowerName = attributeName.toLowerCase() + const foundName = Object.getOwnPropertyNames(sourceObject).find((name) => + name.toLowerCase() === lowerName + ) + return foundName && sourceObject[foundName] +} diff --git a/node_modules/@ldapjs/filter/lib/utils/get-attribute-value.test.js b/node_modules/@ldapjs/filter/lib/utils/get-attribute-value.test.js new file mode 100644 index 0000000..d4bfb76 --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/utils/get-attribute-value.test.js @@ -0,0 +1,65 @@ +'use strict' + +const tap = require('tap') +const Attribute = require('@ldapjs/attribute') +const getAttributeValue = require('./get-attribute-value') + +tap.test('exact match', async (t) => { + let result = getAttributeValue({ sourceObject: { attr: 'testval' }, attributeName: 'attr' }) + t.equal(result, 'testval') + + result = getAttributeValue({ sourceObject: { attr: 'testval' }, attributeName: 'missing' }) + t.equal(result, undefined) +}) + +tap.test('getAttributeValue insensitive match', async (t) => { + const sourceObject = { + lower: 'lower', + UPPER: 'upper', + MiXeD: 'mixed' + } + let result = getAttributeValue({ sourceObject, attributeName: 'lower' }) + t.equal(result, 'lower') + + result = getAttributeValue({ sourceObject, attributeName: 'upper' }) + t.equal(result, 'upper') + + result = getAttributeValue({ sourceObject, attributeName: 'mixed' }) + t.equal(result, 'mixed') + + result = getAttributeValue({ sourceObject, attributeName: 'missing' }) + t.equal(result, undefined) +}) + +tap.test('getAttributeValue strict match', async (t) => { + const sourceObject = { + lower: 'lower', + UPPER: 'upper', + MiXeD: 'mixed' + } + const strictCase = true + + let result = getAttributeValue({ sourceObject, attributeName: 'lower', strictCase }) + t.equal(result, 'lower') + + result = getAttributeValue({ sourceObject, attributeName: 'upper', strictCase }) + t.equal(result, undefined) + + result = getAttributeValue({ sourceObject, attributeName: 'UPPER', strictCase }) + t.equal(result, 'upper') + + result = getAttributeValue({ sourceObject, attributeName: 'mixed', strictCase }) + t.equal(result, undefined) + + result = getAttributeValue({ sourceObject, attributeName: 'MiXeD', strictCase }) + t.equal(result, 'mixed') + + result = getAttributeValue({ sourceObject, attributeName: 'missing', strictCase }) + t.equal(result, undefined) +}) + +tap.test('supports Attribute objects', async t => { + const sourceObject = Attribute.fromObject({ cn: 'foo' }).pop() + const result = getAttributeValue({ sourceObject, attributeName: 'cn' }) + t.strictSame(result, ['foo']) +}) diff --git a/node_modules/@ldapjs/filter/lib/utils/test-values.js b/node_modules/@ldapjs/filter/lib/utils/test-values.js new file mode 100644 index 0000000..f630f1c --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/utils/test-values.js @@ -0,0 +1,47 @@ +'use strict' + +module.exports = testValues + +/** + * Tests if the given input matches some condition. + * + * @callback ruleCallback + * @param {*} input Value to test. + * @returns {boolean} + */ + +/** + * Check value or array with test function. + * + * @param {object} input + * @param {ruleCallback} input.rule Synchronous function that tests if an input + * matches some condition. Must return `true` or `false`. + * @param {*|*[]} input.value An item, or list of items, to verify with the + * rule function. + * @param {boolean} [input.requireAllMatch=false] require all array values to match. + * + * @returns {boolean} + */ +function testValues ({ rule, value, requireAllMatch = false }) { + if (Array.isArray(value) === false) { + return rule(value) + } + + if (requireAllMatch === true) { + // Do all entries match rule? + for (let i = 0; i < value.length; i++) { + if (rule(value[i]) === false) { + return false + } + } + return true + } + + // Do any entries match rule? + for (let i = 0; i < value.length; i++) { + if (rule(value[i])) { + return true + } + } + return false +} diff --git a/node_modules/@ldapjs/filter/lib/utils/test-values.test.js b/node_modules/@ldapjs/filter/lib/utils/test-values.test.js new file mode 100644 index 0000000..f2a74eb --- /dev/null +++ b/node_modules/@ldapjs/filter/lib/utils/test-values.test.js @@ -0,0 +1,52 @@ +'use strict' + +const tap = require('tap') +const testValues = require('./test-values') + +tap.test('matches a single value', async t => { + const result = testValues({ + value: 42, + rule (input) { + return input === 42 + } + }) + t.equal(result, true) +}) + +tap.test('requires all match', async t => { + let result = testValues({ + value: [42, 35], + requireAllMatch: true, + rule (input) { + return input >= 35 + } + }) + t.equal(result, true) + + result = testValues({ + value: [42, 35], + requireAllMatch: true, + rule (input) { + return input === 42 + } + }) + t.equal(result, false) +}) + +tap.test('requires any match', async t => { + let result = testValues({ + value: [42, 35], + rule (input) { + return input === 42 + } + }) + t.equal(result, true) + + result = testValues({ + value: [42, 35], + rule (input) { + return input === 99 + } + }) + t.equal(result, false) +}) diff --git a/node_modules/@ldapjs/filter/package.json b/node_modules/@ldapjs/filter/package.json new file mode 100644 index 0000000..313d08a --- /dev/null +++ b/node_modules/@ldapjs/filter/package.json @@ -0,0 +1,48 @@ +{ + "originalAuthor": "Patrick Mooney", + "originalContributors": [ + "Mark Cavage ", + "Cody Peter Mello " + ], + "name": "@ldapjs/filter", + "homepage": "https://github.com/ldapjs/filter", + "description": "API for handling LDAP-style filters", + "version": "2.1.1", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:ldapjs/filter.git" + }, + "main": "lib/index.js", + "directories": { + "lib": "./lib" + }, + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + }, + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "@ldapjs/attribute": "1.0.0-rc.5", + "eslint": "^8.34.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^15.6.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.4" + }, + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report", + "test:cov": "tap", + "test:cov:html": "tap --coverage-report=html", + "test:watch": "tap -w --no-coverage-report" + }, + "precommit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/messages/.eslintrc b/node_modules/@ldapjs/messages/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/messages/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/messages/.github/workflows/main.yml b/node_modules/@ldapjs/messages/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/messages/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/messages/.taprc.yaml b/node_modules/@ldapjs/messages/.taprc.yaml new file mode 100644 index 0000000..1f33096 --- /dev/null +++ b/node_modules/@ldapjs/messages/.taprc.yaml @@ -0,0 +1,5 @@ +reporter: terse +coverage-map: coverage-map.js + +files: + - 'lib/**/*.test.js' diff --git a/node_modules/@ldapjs/messages/LICENSE b/node_modules/@ldapjs/messages/LICENSE new file mode 100644 index 0000000..923d87e --- /dev/null +++ b/node_modules/@ldapjs/messages/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2014 Patrick Mooney. All rights reserved. +Copyright (c) 2014 Mark Cavage, Inc. All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/messages/README.md b/node_modules/@ldapjs/messages/README.md new file mode 100644 index 0000000..ca80782 --- /dev/null +++ b/node_modules/@ldapjs/messages/README.md @@ -0,0 +1,7 @@ +# @ldapjs/messages + +Provides methods and objects to represent LDAP messages. + +## License + +MIT. diff --git a/node_modules/@ldapjs/messages/coverage-map.js b/node_modules/@ldapjs/messages/coverage-map.js new file mode 100644 index 0000000..fc2046a --- /dev/null +++ b/node_modules/@ldapjs/messages/coverage-map.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = testFile => testFile.replace(/\.test\.js$/, '.js') diff --git a/node_modules/@ldapjs/messages/index.js b/node_modules/@ldapjs/messages/index.js new file mode 100644 index 0000000..646f4ec --- /dev/null +++ b/node_modules/@ldapjs/messages/index.js @@ -0,0 +1,41 @@ +'use strict' + +module.exports = { + // Base objects. + LdapMessage: require('./lib/ldap-message'), + LdapResult: require('./lib/ldap-result'), + + // Request objects. + AbandonRequest: require('./lib/messages/abandon-request'), + AddRequest: require('./lib/messages/add-request'), + BindRequest: require('./lib/messages/bind-request'), + CompareRequest: require('./lib/messages/compare-request'), + DeleteRequest: require('./lib/messages/delete-request'), + ExtensionRequest: require('./lib/messages/extension-request'), + ModifyRequest: require('./lib/messages/modify-request'), + ModifyDnRequest: require('./lib/messages/modifydn-request'), + SearchRequest: require('./lib/messages/search-request'), + UnbindRequest: require('./lib/messages/unbind-request'), + + // Response objects. + AbandonResponse: require('./lib/messages/abandon-response'), + AddResponse: require('./lib/messages/add-response'), + BindResponse: require('./lib/messages/bind-response'), + CompareResponse: require('./lib/messages/compare-response'), + DeleteResponse: require('./lib/messages/delete-response'), + ExtensionResponse: require('./lib/messages/extension-response'), + ModifyResponse: require('./lib/messages/modify-response'), + ModifyDnResponse: require('./lib/messages/modifydn-response'), + + // Search request messages. + SearchResultEntry: require('./lib/messages/search-result-entry'), + SearchResultReference: require('./lib/messages/search-result-reference'), + SearchResultDone: require('./lib/messages/search-result-done'), + + // Specific extension response implementations. + PasswordModifyResponse: require('./lib/messages/extension-responses/password-modify'), + WhoAmIResponse: require('./lib/messages/extension-responses/who-am-i'), + + // Miscellaneous objects. + IntermediateResponse: require('./lib/messages/intermediate-response') +} diff --git a/node_modules/@ldapjs/messages/lib/_fixtures/evolution-filter-req.js b/node_modules/@ldapjs/messages/lib/_fixtures/evolution-filter-req.js new file mode 100644 index 0000000..46c9684 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/_fixtures/evolution-filter-req.js @@ -0,0 +1,149 @@ +'use strict' + +module.exports = [ + 0x30, 0x82, 0x04, 0xe4, // sequence, 1_252 bytes + 0x02, 0x01, 0x01, // message id (1) + 0x63, 0x82, 0x04, 0xdd, // protocol op (0x63), 1_245 bytes + + 0x04, 0x23, // string (baseObject), 35 bytes + // "dc=dc3d09f8c56386aff779f0a9a7bc9514" + 0x64, 0x63, 0x3d, 0x64, 0x63, 0x33, 0x64, 0x30, 0x39, 0x66, + 0x38, 0x63, 0x35, 0x36, 0x33, 0x38, 0x36, 0x61, 0x66, 0x66, + 0x37, 0x37, 0x39, 0x66, 0x30, 0x61, 0x39, 0x61, 0x37, 0x62, + 0x63, 0x39, 0x35, 0x31, 0x34, + + 0x0a, 0x01, // scope, 1 byte + 0x00, // "base" + 0x0a, 0x01, // derefAliases, 1 byte + 0x00, // "never" + 0x02, 0x01, 0x00, // sizeLimit = 0 + 0x02, 0x01, 0x0a, // timeLimit = 10 + 0x01, 0x01, 0x00, // typesOnly = false + + // See the `evolution-filter.js` fixture in `@ldapjs/filter` for a + // complete breakdown of the filter bytes. + // https://github.com/ldapjs/filter/blob/8a5892c/lib/ber-parsing/_fixtures/evolution-filter.js + 0xa1, 0x82, 0x04, 0xa3, // filter, 1_187 bytes + 0xa4, 0x0b, 0x04, + 0x02, 0x63, 0x6e, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x12, 0x04, 0x09, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x6e, + 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x0b, 0x04, 0x02, 0x73, 0x6e, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x0d, 0x04, 0x04, 0x6d, 0x61, 0x69, + 0x6c, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0f, + 0x04, 0x06, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x15, 0x04, 0x0c, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x18, + 0x04, 0x0f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x12, 0x04, 0x09, 0x68, 0x6f, + 0x6d, 0x65, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0f, 0x04, 0x06, 0x6d, 0x6f, + 0x62, 0x69, 0x6c, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, + 0x6f, 0xa4, 0x11, 0x04, 0x08, 0x63, 0x61, 0x72, 0x70, 0x68, + 0x6f, 0x6e, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x21, 0x04, 0x18, 0x66, 0x61, 0x63, 0x73, 0x69, 0x6d, + 0x69, 0x6c, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, + 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x25, 0x04, 0x1c, 0x68, + 0x6f, 0x6d, 0x65, 0x66, 0x61, 0x63, 0x73, 0x69, 0x6d, 0x69, + 0x6c, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, 0x6e, + 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x13, 0x04, 0x0a, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x26, 0x04, 0x1d, 0x6f, + 0x74, 0x68, 0x65, 0x72, 0x66, 0x61, 0x63, 0x73, 0x69, 0x6d, + 0x69, 0x6c, 0x65, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x68, 0x6f, + 0x6e, 0x65, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x20, 0x04, 0x17, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x61, 0x6c, 0x69, 0x73, 0x64, 0x6e, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, + 0x0e, 0x04, 0x05, 0x70, 0x61, 0x67, 0x65, 0x72, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0e, 0x04, 0x05, 0x72, + 0x61, 0x64, 0x69, 0x6f, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, + 0x6f, 0xa4, 0x0e, 0x04, 0x05, 0x74, 0x65, 0x6c, 0x65, 0x78, + 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x17, 0x04, + 0x0e, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, + 0x67, 0x6f, 0xa4, 0x15, 0x04, 0x0c, 0x63, 0x6f, 0x6d, 0x70, + 0x61, 0x6e, 0x79, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x16, 0x04, 0x0d, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x70, 0x68, 0x6f, + 0x6e, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, + 0x0c, 0x04, 0x03, 0x74, 0x74, 0x79, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x0a, 0x04, 0x01, 0x6f, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0b, 0x04, 0x02, 0x6f, + 0x75, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x13, + 0x04, 0x0a, 0x72, 0x6f, 0x6f, 0x6d, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, + 0x0e, 0x04, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x30, 0x05, + 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x15, 0x04, 0x0c, 0x62, + 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x72, 0x6f, 0x6c, + 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x14, + 0x04, 0x0b, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x16, 0x04, 0x0d, 0x61, 0x73, 0x73, 0x69, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x16, 0x04, 0x0d, 0x70, 0x6f, + 0x73, 0x74, 0x61, 0x6c, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0a, + 0x04, 0x01, 0x6c, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x0b, 0x04, 0x02, 0x73, 0x74, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x16, 0x04, 0x0d, 0x70, 0x6f, 0x73, + 0x74, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x62, 0x6f, 0x78, + 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x13, 0x04, + 0x0a, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x63, 0x6f, 0x64, + 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0a, + 0x04, 0x01, 0x63, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x1a, 0x04, 0x11, 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x6f, + 0x73, 0x74, 0x61, 0x6c, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x20, + 0x04, 0x17, 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, 0x68, + 0x6f, 0x6d, 0x65, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, + 0x79, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, + 0x67, 0x6f, 0xa4, 0x19, 0x04, 0x10, 0x6d, 0x6f, 0x7a, 0x69, + 0x6c, 0x6c, 0x61, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, + 0x1e, 0x04, 0x15, 0x6d, 0x6f, 0x7a, 0x69, 0x6c, 0x6c, 0x61, + 0x68, 0x6f, 0x6d, 0x65, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, + 0x63, 0x6f, 0x64, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, + 0x6f, 0xa4, 0x1f, 0x04, 0x16, 0x6d, 0x6f, 0x7a, 0x69, 0x6c, + 0x6c, 0x61, 0x68, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x72, 0x79, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x1b, 0x04, 0x12, 0x6f, 0x74, + 0x68, 0x65, 0x72, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x12, 0x04, 0x09, 0x6a, 0x70, 0x65, + 0x67, 0x70, 0x68, 0x6f, 0x74, 0x6f, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x18, 0x04, 0x0f, 0x75, 0x73, 0x65, + 0x72, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, + 0x13, 0x04, 0x0a, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x64, + 0x75, 0x72, 0x69, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x14, 0x04, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, + 0x67, 0x6f, 0xa4, 0x13, 0x04, 0x0a, 0x73, 0x70, 0x6f, 0x75, + 0x73, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x0d, 0x04, 0x04, 0x6e, 0x6f, 0x74, + 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x14, + 0x04, 0x0b, 0x61, 0x6e, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x72, 0x79, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x12, 0x04, 0x09, 0x62, 0x69, 0x72, 0x74, 0x68, 0x64, + 0x61, 0x74, 0x65, 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, + 0xa4, 0x0f, 0x04, 0x06, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, + 0x30, 0x05, 0x80, 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x0f, 0x04, + 0x06, 0x66, 0x69, 0x6c, 0x65, 0x61, 0x73, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, 0xa4, 0x11, 0x04, 0x08, 0x63, 0x61, + 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x12, 0x04, 0x09, 0x63, 0x61, 0x6c, + 0x63, 0x61, 0x6c, 0x75, 0x72, 0x69, 0x30, 0x05, 0x80, 0x03, + 0x6f, 0x67, 0x6f, 0xa4, 0x11, 0x04, 0x08, 0x63, 0x61, 0x6c, + 0x66, 0x62, 0x75, 0x72, 0x6c, 0x30, 0x05, 0x80, 0x03, 0x6f, + 0x67, 0x6f, 0xa4, 0x14, 0x04, 0x0b, 0x69, 0x63, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x30, 0x05, 0x80, + 0x03, 0x6f, 0x67, 0x6f, + + 0x30, 0x00 // attributes set, 0 bytes +] diff --git a/node_modules/@ldapjs/messages/lib/deprecations.js b/node_modules/@ldapjs/messages/lib/deprecations.js new file mode 100644 index 0000000..3d58ac0 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/deprecations.js @@ -0,0 +1,16 @@ +'use strict' + +const warning = require('process-warning')() +const clazz = 'LdapjsMessageWarning' + +warning.create(clazz, 'LDAP_MESSAGE_DEP_001', 'messageID is deprecated. Use messageId instead.') + +warning.create(clazz, 'LDAP_MESSAGE_DEP_002', 'The .json property is deprecated. Use .pojo instead.') + +warning.create(clazz, 'LDAP_MESSAGE_DEP_003', 'abandonID is deprecated. Use abandonId instead.') + +warning.create(clazz, 'LDAP_MESSAGE_DEP_004', 'errorMessage is deprecated. Use diagnosticMessage instead.') + +warning.create(clazz, 'LDAP_ATTRIBUTE_SPEC_ERR_001', 'received attempt to define attribute with an empty name: attribute skipped.', { unlimited: true }) + +module.exports = warning diff --git a/node_modules/@ldapjs/messages/lib/ldap-message.js b/node_modules/@ldapjs/messages/lib/ldap-message.js new file mode 100644 index 0000000..f3596ac --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/ldap-message.js @@ -0,0 +1,282 @@ +'use strict' + +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const warning = require('./deprecations') + +/** + * Implements a base LDAP message as defined in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.1.1. + */ +class LdapMessage { + #messageId = 0 + #protocolOp + #controls = [] + + /** + * @typedef {object} LdapMessageOptions + * @property {number} [messageId=1] An identifier for the message. + * @property {number} [protocolOp] The tag for the message operation. + * @property {import('@ldapjs/controls').Control[]} [controls] A set of LDAP + * controls to send with the message. See the `@ldapjs/controls` package. + */ + + /** + * @param {LdapMessageOptions} [options] + */ + constructor (options = {}) { + this.#messageId = parseInt(options.messageId ?? options.messageID ?? '1', 10) + if (options.messageID !== undefined) { + warning.emit('LDAP_MESSAGE_DEP_001') + } + + if (typeof options.protocolOp === 'number') { + this.#protocolOp = options.protocolOp + } + + this.controls = options.controls ?? [] + } + + get [Symbol.toStringTag] () { + return 'LdapMessage' + } + + /** + * A copy of the list of controls that will be sent with the request. + * + * @returns {import('@ldapjs/controls').Control[]} + */ + get controls () { + return this.#controls.slice(0) + } + + /** + * Define the list of controls that will be sent with the request. Any + * existing controls will be discarded. + * + * @param {import('@ldapjs/controls').Control[]} values + * + * @throws When a control value is invalid. + */ + set controls (values) { + if (Array.isArray(values) !== true) { + throw Error('controls must be an array') + } + const newControls = [] + for (const val of values) { + if (Object.prototype.toString.call(val) !== '[object LdapControl]') { + throw Error('control must be an instance of LdapControl') + } + newControls.push(val) + } + this.#controls = newControls + } + + /** + * The message identifier. + * + * @type {number} + */ + get id () { + return this.#messageId + } + + /** + * Define the message identifier for the request. + * + * @param {number} value + */ + set id (value) { + if (Number.isInteger(value) === false) { + throw Error('id must be an integer') + } + this.#messageId = value + } + + /** + * Alias for {@link id}. + * + * @returns {number} + */ + get messageId () { + return this.id + } + + /** + * Alias for {@link id}. + * + * @param {number} value + */ + set messageId (value) { + this.id = value + } + + /** + * Alias for {@link id}. + * + * @returns {number} + * + * @deprecated + */ + get messageID () { + warning.emit('LDAP_MESSAGE_DEP_001') + return this.id + } + + /** + * Alias for {@link id}. + * + * @param {number} value + * + * @deprecated + */ + set messageID (value) { + warning.emit('LDAP_MESSAGE_DEP_001') + this.id = value + } + + /** + * Message type specific. Each message type must implement a `_dn` property + * that provides this value. + * + * @type {import('@ldapjs/dn').DN} + */ + get dn () { + return this._dn + } + + /** + * The LDAP protocol operation code for the message. + * + * @type {number} + */ + get protocolOp () { + return this.#protocolOp + } + + /** + * The name of the message class. + * + * @type {string} + */ + get type () { + return 'LdapMessage' + } + + /** + * Use {@link pojo} instead. + * + * @deprecated + */ + get json () { + warning.emit('LDAP_MESSAGE_DEP_002') + return this.pojo + } + + /** + * A serialized representation of the message as a plain JavaScript object. + * Specific message types must implement the `_pojo(obj)` method. The passed + * in `obj` must be extended with the specific message's unique properties + * and returned as the result. + * + * @returns {object} + */ + get pojo () { + let result = { + messageId: this.id, + protocolOp: this.#protocolOp, + type: this.type + } + + if (typeof this._pojo === 'function') { + result = this._pojo(result) + } + + result.controls = this.#controls.map(c => c.pojo) + + return result + } + + addControl (control) { + this.#controls.push(control) + } + + /** + * Converts an {@link LdapMessage} object into a set of BER bytes that can + * be sent across the wire. Specific message implementations must implement + * the `_toBer(ber)` method. This method will write its unique sequence(s) + * to the passed in `ber` object. + * + * @returns {import('@ldapjs/asn1').BerReader} + */ + toBer () { + if (typeof this._toBer !== 'function') { + throw Error(`${this.type} does not implement _toBer`) + } + + const writer = new BerWriter() + writer.startSequence() + writer.writeInt(this.id) + + this._toBer(writer) + + if (this.#controls.length > 0) { + writer.startSequence(0xa0) + for (const control of this.#controls) { + control.toBer(writer) + } + writer.endSequence() + } + + writer.endSequence() + return new BerReader(writer.buffer) + } + + /** + * Serializes the message into a JSON representation. + * + * @returns {string} + */ + toString () { + return JSON.stringify(this.pojo) + } + + /** + * Parses a BER into a message object. The offset of the BER _must_ point + * to the start of an LDAP Message sequence. That is, the first few bytes + * must indicate: + * + * 1. a sequence tag and how many bytes are in that sequence + * 2. an integer representing the message identifier + * 3. a protocol operation, e.g. BindRequest, and the number of bytes in + * that operation + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {LdapMessage} + */ + static parse (ber) { + // We must require here because `parseToMessage` imports subclasses + // that need `LdapMessage` to be defined. If we try importing earlier, + // then `LdapMessage` will not be available, and we will get errors about + // trying to subclass null objects. + return require('./parse-to-message')(ber) + } + + /** + * When invoked on specific message types, e.g. {@link BindRequest}, this + * method will parse a BER into a plain JavaScript object that is usable as + * an options object for constructing that specific message object. + * + * @param {import('@ldapjs/asn1').BerReader} ber A BER to parse. The reader + * offset must point to the start of a valid sequence, i.e. the "tag" byte + * in the TLV tuple, that represents the message to be parsed. For example, + * in a {@link BindRequest} the starting sequence and message identifier must + * already be read such that the offset is at the protocol operation sequence + * byte. + */ + static parseToPojo (ber) { + throw Error('Use LdapMessage.parse, or a specific message type\'s parseToPojo, instead.') + } +} + +module.exports = LdapMessage diff --git a/node_modules/@ldapjs/messages/lib/ldap-message.test.js b/node_modules/@ldapjs/messages/lib/ldap-message.test.js new file mode 100644 index 0000000..9dd5e83 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/ldap-message.test.js @@ -0,0 +1,315 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const warning = require('./deprecations') +const { Control } = require('@ldapjs/controls') +const LdapMessage = require('./ldap-message') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +const { + abandonRequestBytes, + bindRequestBytes, + deleteRequestBytes +} = require('./messages/_fixtures/message-byte-arrays') + +tap.test('constructor', t => { + t.test('no args', async t => { + const message = new LdapMessage() + t.strictSame(message.pojo, { + messageId: 1, + protocolOp: undefined, + type: 'LdapMessage', + controls: [] + }) + }) + + t.test('all options supplied', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_001', false) + }) + + const message = new LdapMessage({ + messageID: 10, + protocolOp: 0x01, + controls: [new Control({ type: 'foo', value: 'foo' })] + }) + t.strictSame(message.pojo, { + messageId: 10, + protocolOp: 0x01, + type: 'LdapMessage', + controls: [{ + type: 'foo', + value: 'foo', + criticality: false + }] + }) + + function handler (error) { + t.equal(error.message, 'messageID is deprecated. Use messageId instead.') + t.end() + } + }) + + t.end() +}) + +tap.test('misc', t => { + t.test('toStringTag is correct', async t => { + const message = new LdapMessage() + t.equal(Object.prototype.toString.call(message), '[object LdapMessage]') + }) + + t.test('dn returns _dn', async t => { + class Foo extends LdapMessage { + get _dn () { + return 'foo' + } + } + + const message = new Foo() + t.equal(message.dn, 'foo') + }) + + t.test('protocolOp returns code', async t => { + const message = new LdapMessage({ protocolOp: 1 }) + t.equal(message.protocolOp, 1) + }) + + t.test('json emits warning', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_002', false) + }) + + const message = new LdapMessage() + t.ok(message.json) + + function handler (error) { + t.equal( + error.message, + 'The .json property is deprecated. Use .pojo instead.' + ) + t.end() + } + }) + + t.test('toString returns JSON', async t => { + const message = new LdapMessage() + const expected = JSON.stringify(message.pojo) + t.equal(message.toString(), expected) + }) + + t.end() +}) + +tap.test('.controls', t => { + t.test('sets/gets', async t => { + const req = new LdapMessage() + t.strictSame(req.controls, []) + + req.controls = [new Control()] + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: undefined, + type: 'LdapMessage', + controls: [{ + type: '', + value: null, + criticality: false + }] + }) + }) + + t.test('rejects for non-array', async t => { + const req = new LdapMessage() + t.throws( + () => { + req.controls = {} + }, + 'controls must be an array' + ) + }) + + t.test('rejects if array item is not a control', async t => { + const req = new LdapMessage() + t.throws( + () => { + req.controls = ['foo'] + }, + 'control must be an instance of LdapControl' + ) + }) + + t.end() +}) + +tap.test('.id', t => { + t.test('sets/gets', async t => { + const req = new LdapMessage() + t.equal(req.id, 1) + + req.id = 2 + t.equal(req.id, 2) + t.equal(req.messageId, 2) + + req.messageId = 3 + t.equal(req.id, 3) + }) + + t.test('throws if not an integer', async t => { + const req = new LdapMessage() + t.throws( + () => { + req.id = 1.5 + }, + 'id must be an integer' + ) + }) + + t.test('get messageID is deprecated', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_001', false) + }) + + const message = new LdapMessage() + t.ok(message.messageID) + + function handler (error) { + t.equal( + error.message, + 'messageID is deprecated. Use messageId instead.' + ) + t.end() + } + }) + + t.test('set messageID is deprecated', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_001', false) + }) + + const message = new LdapMessage() + message.messageID = 2 + + function handler (error) { + t.equal( + error.message, + 'messageID is deprecated. Use messageId instead.' + ) + t.end() + } + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('throws for bad subclass', async t => { + class Foo extends LdapMessage { + } + + const message = new Foo() + + t.throws( + () => message.toBer(), + Error('LdapMessage does not implement _toBer') + ) + }) + + t.test('converts BindRequest to BER', async t => { + const reqBuffer = Buffer.from(bindRequestBytes) + const reader = new BerReader(reqBuffer) + const message = LdapMessage.parse(reader) + + const ber = message.toBer() + t.equal('[object BerReader]', Object.prototype.toString.call(ber)) + t.equal(reqBuffer.compare(ber.buffer), 0) + }) + + t.test('converts DeleteRequest to BER', async t => { + const reqBuffer = Buffer.from(deleteRequestBytes) + const reader = new BerReader(reqBuffer) + const message = LdapMessage.parse(reader) + + const ber = message.toBer() + t.equal(reqBuffer.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parse', t => { + t.test('parses an abandon request', async t => { + const reader = new BerReader(Buffer.from(abandonRequestBytes)) + const message = LdapMessage.parse(reader) + + t.strictSame(message.pojo, { + messageId: 6, + protocolOp: 0x50, + type: 'AbandonRequest', + abandonId: 5, + controls: [] + }) + }) + + t.test('parses a bind request', async t => { + const reader = new BerReader(Buffer.from(bindRequestBytes)) + const message = LdapMessage.parse(reader) + + t.strictSame(message.pojo, { + messageId: 1, + protocolOp: 0x60, + type: 'BindRequest', + version: 3, + name: 'uid=admin,ou=system', + authenticationType: 'simple', + credentials: 'secret', + controls: [] + }) + + t.equal(message.name, 'uid=admin,ou=system') + }) + + t.test('parses a delete request with controls', async t => { + const reader = new BerReader(Buffer.from(deleteRequestBytes)) + const message = LdapMessage.parse(reader) + + // We need to parse the JSON representation because stringSame will return + // false when comparing a plain object to an instance of Control. + t.strictSame(JSON.parse(message.toString()), { + messageId: 5, + protocolOp: 0x4a, + type: 'DeleteRequest', + entry: 'dc=example,dc=com', + controls: [{ + type: '1.2.840.113556.1.4.805', + criticality: true, + value: null + }] + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws because not implemented', async t => { + const expected = Error('Use LdapMessage.parse, or a specific message type\'s parseToPojo, instead.') + t.throws( + () => LdapMessage.parseToPojo(), + expected + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/ldap-result.js b/node_modules/@ldapjs/messages/lib/ldap-result.js new file mode 100644 index 0000000..de53d3d --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/ldap-result.js @@ -0,0 +1,244 @@ +'use strict' + +const LdapMessage = require('./ldap-message') +const { resultCodes, operations } = require('@ldapjs/protocol') +const warning = require('./deprecations') + +/** + * Implements the base LDAP response message as defined in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.1.9. + */ +class LdapResult extends LdapMessage { + #connection = null + #diagnosticMessage + #matchedDN + #referrals = [] + #status + + /** + * @typedef {LdapMessageOptions} LdapResultOptions + * @property {number} [status=0] An LDAP status code. + * @param {string} [matchedDN=''] The DN that matched the request. + * @param {string[]} [referrals=[]] A set of servers to query for references. + * @param {string} [diagnosticMessage] A message indicating why a request + * failed. + */ + + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + super(options) + + this.#status = options.status ?? resultCodes.SUCCESS + this.#matchedDN = options.matchedDN || '' + this.#referrals = options.referrals || [] + this.#diagnosticMessage = options.diagnosticMessage || options.errorMessage || '' + if (options.errorMessage) { + warning.emit('LDAP_MESSAGE_DEP_004') + } + } + + /** + * The failure message as returned by the server if one is present. + * + * @returns {string} + */ + get diagnosticMessage () { + return this.#diagnosticMessage + } + + /** + * Add a diagnostic message to the instance. + * + * @param {string} message + */ + set diagnosticMessage (message) { + this.#diagnosticMessage = message + } + + /** + * The DN that a request matched. + * + * @returns {string} + */ + get matchedDN () { + return this.#matchedDN + } + + /** + * Define which DN a request matched. + * + * @param {string} dn + */ + set matchedDN (dn) { + this.#matchedDN = dn + } + + /** + * A serialized representation of the message as a plain JavaScript object. + * Specific message types must implement the `_pojo(obj)` method. The passed + * in `obj` must be extended with the specific message's unique properties + * and returned as the result. + * + * @returns {object} + */ + get pojo () { + let result = { + status: this.status, + matchedDN: this.matchedDN, + diagnosticMessage: this.diagnosticMessage, + referrals: this.referrals + } + + if (typeof this._pojo === 'function') { + result = this._pojo(result) + } + + return result + } + + /** + * The list of servers that should be consulted to get an answer + * to the query. + * + * @returns {string[]} + */ + get referrals () { + return this.#referrals.slice(0) + } + + /** + * The LDAP response code for the request. + * + * @returns {number} + */ + get status () { + return this.#status + } + + /** + * Set the response code for the request. + * + * @param {number} s + */ + set status (s) { + this.#status = s + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'LdapResult' + } + + /** + * Add a new server to the list of servers that should be + * consulted for an answer to the query. + * + * @param {string} referral + */ + addReferral (referral) { + this.#referrals.push(referral) + } + + /** + * Internal use only. Subclasses may implement a `_writeResponse` + * method to add to the sequence after any referrals. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + * + * @private + */ + _toBer (ber) { + ber.startSequence(this.protocolOp) + ber.writeEnumeration(this.status) + ber.writeString(this.matchedDN) + ber.writeString(this.diagnosticMessage) + + if (this.referrals.length > 0) { + ber.startSequence(operations.LDAP_RES_REFERRAL) + ber.writeStringArray(this.referrals) + ber.endSequence() + } + + if (typeof this._writeResponse === 'function') { + this._writeResponse(ber) + } + + ber.endSequence() + } + + /** + * When invoked on specific message types, e.g. {@link AddResponse}, this + * method will parse a BER into a plain JavaScript object that is usable as + * an options object for constructing that specific message object. + * + * @param {import('@ldapjs/asn1').BerReader} ber A BER to parse. The reader + * offset must point to the start of a valid sequence, i.e. the "tag" byte + * in the TLV tuple, that represents the message to be parsed. For example, + * in a {@link AddResponse} the starting sequence and message identifier must + * already be read such that the offset is at the protocol operation sequence + * byte. + */ + static parseToPojo (ber) { + throw Error('Use LdapMessage.parse, or a specific message type\'s parseToPojo, instead.') + } + + /** + * Internal use only. + * + * Response messages are a little more generic to parse than request messages. + * However, they still need to recognize the correct protocol operation. So + * the public {@link parseToPojo} for each response object should invoke this + * private static method to parse the BER and indicate the correct protocol + * operation to recognize. + * + * @param {object} input + * @param {number} input.opCode The expected protocol operation to look for. + * @param {import('@ldapjs/asn1').BerReader} berReader The BER to process. It + * must start at an offset representing a protocol operation tag. + * @param {object} [input.pojo] A plain JavaScript object to populate with + * the parsed keys and values. + * + * @returns {object} + * + * @private + */ + static _parseToPojo ({ opCode, berReader, pojo = {} }) { + const protocolOp = berReader.readSequence() + if (protocolOp !== opCode) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const status = berReader.readEnumeration() + const matchedDN = berReader.readString() + const diagnosticMessage = berReader.readString() + const referrals = [] + + if (berReader.peek() === operations.LDAP_RES_REFERRAL) { + // Advance the offset to the start of the value and + // put the sequence length into the `reader.length` field. + berReader.readSequence(operations.LDAP_RES_REFERRAL) + const end = berReader.length + while (berReader.offset < end) { + referrals.push(berReader.readString()) + } + } + + pojo.status = status + pojo.matchedDN = matchedDN + pojo.diagnosticMessage = diagnosticMessage + pojo.referrals = referrals + + return pojo + } +} + +module.exports = LdapResult diff --git a/node_modules/@ldapjs/messages/lib/ldap-result.test.js b/node_modules/@ldapjs/messages/lib/ldap-result.test.js new file mode 100644 index 0000000..c6806d9 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/ldap-result.test.js @@ -0,0 +1,283 @@ +'use strict' + +const tap = require('tap') +const warning = require('./deprecations') +const { resultCodes, operations } = require('@ldapjs/protocol') +const { BerReader } = require('@ldapjs/asn1') +const { + addResponseBasicBytes, + addResponseNoSuchObjectBytes, + addResponseReferralsBytes, + extensionDisconnectionNotificationResponseBytes +} = require('./messages/_fixtures/message-byte-arrays') +const RECOGNIZED_OIDS = require('./messages/extension-utils/recognized-oids') +const LdapResult = require('./ldap-result') +const ExtensionResponse = require('./messages/extension-response') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +tap.test('constructor', t => { + t.test('no args', async t => { + const res = new LdapResult() + t.equal(res.status, 0) + t.equal(res.matchedDN, '') + t.strictSame(res.referrals, []) + t.equal(res.diagnosticMessage, '') + }) + + t.test('emits warning for abandonID', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_004', false) + }) + + const res = new LdapResult({ + errorMessage: 'foo' + }) + t.ok(res) + + function handler (error) { + t.equal( + error.message, + 'errorMessage is deprecated. Use diagnosticMessage instead.' + ) + t.end() + } + }) + + t.test('with options', async t => { + const res = new LdapResult({ + status: 1, + matchedDN: 'foo', + referrals: ['foo.example.com'], + diagnosticMessage: 'bar' + }) + t.equal(res.status, 1) + t.equal(res.matchedDN, 'foo') + t.strictSame(res.referrals, ['foo.example.com']) + t.equal(res.diagnosticMessage, 'bar') + }) + + t.end() +}) + +tap.test('.diagnosticMessage', t => { + t.test('sets and gets', async t => { + const res = new LdapResult() + t.equal(res.diagnosticMessage, '') + res.diagnosticMessage = 'foo' + t.equal(res.diagnosticMessage, 'foo') + }) + + t.end() +}) + +tap.test('.matchedDN', t => { + t.test('sets and gets', async t => { + const res = new LdapResult() + t.equal(res.matchedDN, '') + res.matchedDN = 'foo' + t.equal(res.matchedDN, 'foo') + }) + + t.end() +}) + +tap.test('.pojo', t => { + t.test('returns a plain JavaScript object', async t => { + const res = new LdapResult() + t.strictSame(res.pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('returns a plain JavaScript object from subclass', async t => { + class Foo extends LdapResult { + _pojo (obj) { + obj.foo = 'foo' + return obj + } + } + + const res = new Foo() + t.strictSame(res.pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [], + foo: 'foo' + }) + }) + + t.end() +}) + +tap.test('.referrals', t => { + t.test('gets', async t => { + const res = new LdapResult({ referrals: ['foo'] }) + t.strictSame(res.referrals, ['foo']) + }) + + t.end() +}) + +tap.test('.status', t => { + t.test('sets and gets', async t => { + const res = new LdapResult() + t.equal(res.status, 0) + res.status = 1 + t.equal(res.status, 1) + }) + + t.end() +}) + +tap.test('.type', t => { + t.test('gets', async t => { + const res = new LdapResult() + t.equal(res.type, 'LdapResult') + }) + + t.end() +}) + +tap.test('addReferral', t => { + t.test('adds to existing list', async t => { + const res = new LdapResult({ referrals: ['foo'] }) + t.strictSame(res.referrals, ['foo']) + res.addReferral('bar') + t.strictSame(res.referrals, ['foo', 'bar']) + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('returns basic bytes', async t => { + const res = new LdapResult({ + protocolOp: operations.LDAP_RES_ADD, + messageId: 2 + }) + const ber = res.toBer() + const expected = Buffer.from(addResponseBasicBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.test('returns bytes with referrals', async t => { + const res = new LdapResult({ + protocolOp: operations.LDAP_RES_ADD, + messageId: 3, + status: resultCodes.REFERRAL, + diagnosticMessage: 'This server is read-only. Try a different one.', + referrals: [ + 'ldap://alternate1.example.com:389/uid=jdoe,ou=Remote,dc=example,dc=com', + 'ldap://alternate2.example.com:389/uid=jdoe,ou=Remote,dc=example,dc=com' + ] + }) + const ber = res.toBer() + const expected = Buffer.from(addResponseReferralsBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.test('hands off to _writeResponse', async t => { + const res = new ExtensionResponse({ + protocolOp: operations.LDAP_RES_EXTENSION, + messageId: 0, + status: resultCodes.UNAVAILABLE, + diagnosticMessage: 'The Directory Server is shutting down', + referrals: [], + responseName: RECOGNIZED_OIDS.get('DISCONNECTION_NOTIFICATION') + }) + const ber = res.toBer() + const expected = Buffer.from(extensionDisconnectionNotificationResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws because not implemented', async t => { + const expected = Error('Use LdapMessage.parse, or a specific message type\'s parseToPojo, instead.') + t.throws( + () => LdapResult.parseToPojo(), + expected + ) + }) + + t.end() +}) + +tap.test('#_parseToPojo', async t => { + t.test('throws if protocol op is wrong', async t => { + const bytes = addResponseBasicBytes.slice(5) + bytes[0] = 0x68 + const berReader = new BerReader(Buffer.from(bytes)) + t.throws( + () => LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_ADD, + berReader + }), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.test('parses a basic object', async t => { + const bytes = addResponseBasicBytes.slice(5) + const berReader = new BerReader(Buffer.from(bytes)) + const pojo = { foo: 'foo' } + LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_ADD, + berReader, + pojo + }) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [], + foo: 'foo' + }) + }) + + t.test('parses object with matched dn and diagnostic message', async t => { + const bytes = addResponseNoSuchObjectBytes.slice(6) + const berReader = new BerReader(Buffer.from(bytes)) + const pojo = LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_ADD, + berReader + }) + t.strictSame(pojo, { + status: resultCodes.NO_SUCH_OBJECT, + referrals: [], + matchedDN: 'ou=People, dc=example, dc=com', + diagnosticMessage: [ + 'Entry uid=missing1, ou=missing2, ou=People, dc=example, dc=com cannot', + ' be created because its parent does not exist.' + ].join('') + }) + }) + + t.test('parses object with referrals', async t => { + const bytes = addResponseReferralsBytes.slice(6) + const berReader = new BerReader(Buffer.from(bytes)) + const pojo = LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_ADD, + berReader + }) + t.strictSame(pojo, { + status: resultCodes.REFERRAL, + referrals: [ + 'ldap://alternate1.example.com:389/uid=jdoe,ou=Remote,dc=example,dc=com', + 'ldap://alternate2.example.com:389/uid=jdoe,ou=Remote,dc=example,dc=com' + ], + matchedDN: '', + diagnosticMessage: 'This server is read-only. Try a different one.' + }) + }) +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/_fixtures/message-byte-arrays.js b/node_modules/@ldapjs/messages/lib/messages/_fixtures/message-byte-arrays.js new file mode 100644 index 0000000..04fdeea --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/_fixtures/message-byte-arrays.js @@ -0,0 +1,828 @@ +'use strict' + +// The byte arrays in this file are used by the +// `parseToMessage` function test suite. Any byte block +// added to this file will automatically get picked up by +// that test suite. Thus, any byte block added here should be +// parseable, and serializable, by the generic LDAP object +// type associated with that byte block. + +module.exports.abandonRequestBytes = [ + 0x30, 0x06, // sequence, 6 bytes + 0x02, 0x01, 0x06, // message id (integer value "6") + 0x50, 0x01, 0x05 // abandon request protocol op (application primitive integer 5) +] + +/** + * Technically, this is nonsense. The spec does not define an abandon response. + * We are making something up here just to test the ldapjs specific response + * object. + */ +module.exports.abandonResponseBytes = [ + 0x30, 0x0c, // start sequence, 12 bytes + 0x02, 0x01, 0x01, // message id (integer value 1) + 0x00, 0x07, // protocol op (0x61) bind response + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00 // no diagnostic message (0-byte octet string) +] + +/** + * Represents a basic ADD response. + * Taken from https://web.archive.org/web/20220630073105/https://nawilson.com/ldapv3-wire-protocol-reference-add/ + */ +module.exports.addResponseBasicBytes = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id 2 + 0x69, 0x07, // add response op, 7 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00 // no diagnostic message (0-byte octet string) +] + +/** + * Represents an ADD response with an error and a diagnostic message. + * Taken from https://web.archive.org/web/20220630073105/https://nawilson.com/ldapv3-wire-protocol-reference-add/ + */ +module.exports.addResponseNoSuchObjectBytes = [ + 0x30, 0x81, 0x9d, // sequence, 157 bytes + 0x02, 0x01, 0x03, // message id 3 + 0x69, 0x81, 0x97, // add response op, 151 bytes + 0x0a, 0x01, 0x20, // noSuchObject result code (enumerated value 32) + + 0x04, 0x1d, // octet string, 29 bytes (matched dn) + 0x6f, 0x75, 0x3d, 0x50, 0x65, 0x6f, 0x70, 0x6c, // "ou=Peopl" + 0x65, 0x2c, 0x20, 0x64, 0x63, 0x3d, 0x65, 0x78, // "e, dc=ex" + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, 0x64, // "ample, d" + 0x63, 0x3d, 0x63, 0x6f, 0x6d, // "c=com" + + 0x04, 0x73, // octet string, 115 bytes (diagnostic message) + // "Entry uid=missing1, ou=missing2, ou=People, dc=example, dc=com cannot be + // created because its parent does not exist." + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x75, 0x69, + 0x64, 0x3d, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, + 0x67, 0x31, 0x2c, 0x20, 0x6f, 0x75, 0x3d, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x32, 0x2c, + 0x20, 0x6f, 0x75, 0x3d, 0x50, 0x65, 0x6f, 0x70, + 0x6c, 0x65, 0x2c, 0x20, 0x64, 0x63, 0x3d, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x20, + 0x64, 0x63, 0x3d, 0x63, 0x6f, 0x6d, 0x20, 0x63, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, + 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x62, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x20, 0x64, 0x6f, 0x65, 0x73, + 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x65, 0x78, 0x69, + 0x73, 0x74, 0x2e +] + +/** + * Represents an ADD response with referrals. + * Taken from https://web.archive.org/web/20220630073105/https://nawilson.com/ldapv3-wire-protocol-reference-add/ + */ +module.exports.addResponseReferralsBytes = [ + 0x30, 0x81, 0xcf, // sequence, 207 bytes + 0x02, 0x01, 0x03, // message id 3 + 0x69, 0x81, 0xc9, // add response op, 201 bytes + 0x0a, 0x01, 0x0a, // referral result code (enumerated value 10) + 0x04, 0x00, // no matched dn (0-byte octet string) + + 0x04, 0x2f, // octet string, 47 bytes (diagnostic message) + // "This server is read-only. Try a different one." + 0x54, 0x68, 0x69, 0x73, 0x20, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x72, + 0x65, 0x61, 0x64, 0x2d, 0x6f, 0x6e, 0x6c, 0x79, + 0x2e, 0x20, 0x20, 0x54, 0x72, 0x79, 0x20, 0x61, + 0x20, 0x64, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x6f, 0x6e, 0x65, 0x2e, + + 0xa3, 0x81, 0x90, // referrals sequence, 144 bytes + 0x04, 0x46, // string, 70 bytes (first url) + // "ldap://alternate1.example.com:389/uid=jdoe,ou=Remote,dc=example,dc=com" + 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x61, + 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, + 0x31, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x33, 0x38, + 0x39, 0x2f, 0x75, 0x69, 0x64, 0x3d, 0x6a, 0x64, + 0x6f, 0x65, 0x2c, 0x6f, 0x75, 0x3d, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x2c, 0x64, 0x63, 0x3d, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, + 0x64, 0x63, 0x3d, 0x63, 0x6f, 0x6d, + + 0x04, 0x46, // string, 70 bytes (second url) + // "ldap://alternate2.example.com:389/uid=jdoe,ou=Remote,dc=example,dc=com" + 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x61, + 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, + 0x32, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x33, 0x38, + 0x39, 0x2f, 0x75, 0x69, 0x64, 0x3d, 0x6a, 0x64, + 0x6f, 0x65, 0x2c, 0x6f, 0x75, 0x3d, 0x52, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x2c, 0x64, 0x63, 0x3d, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, + 0x64, 0x63, 0x3d, 0x63, 0x6f, 0x6d +] + +/** + * Represents an ADD request with attributes. + * Taken from https://web.archive.org/web/20220630073105/https://nawilson.com/ldapv3-wire-protocol-reference-add/ + */ +module.exports.addRequestBytes = [ + 0x30, 0x49, // start sequence, 73 bytes + 0x02, 0x01, 0x02, // message id 2 + 0x68, 0x44, // add op, 68 bytes + + 0x04, 0x11, // entry dn string, 17 bytes + 0x64, 0x63, 0x3d, 0x65, // "dc=example,dc=com" + 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2c, 0x64, + 0x63, 0x3d, 0x63, 0x6f, + 0x6d, + + 0x30, 0x2f, // start attributes sequence, 47 bytes + 0x30, 0x1c, // start first attribute sequence, 28 bytes + + 0x04, 0x0b, // string, 11 bytes + 0x6f, 0x62, 0x6a, 0x65, // "objectclass" + 0x63, 0x74, 0x63, 0x6c, + 0x61, 0x73, 0x73, + 0x31, 0x0d, // start value sequence, 13 bytes + 0x04, 0x03, 0x74, 0x6f, 0x70, // string: "top" + 0x04, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, // string: "domain" + + 0x30, 0x0f, // start second attribute sequence, 15 bytes + 0x04, 0x02, 0x64, 0x63, // string: "dc" + 0x31, 0x09, // start second value sequence, 9 bytes + 0x04, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65 // string: "example" +] + +/** + * Represents an LDAP BIND Request Message as defined by + * RFC 4511 §4.2. It has a message id of "1" and attempts to bind + * with simple authentication as user "uid=admin,ou=sys" with the password + * "secret". + */ +module.exports.bindRequestBytes = [ + 0x30, 0x25, // sequence, 37 bytes + 0x02, 0x01, 0x01, // message id (integer value "1") + 0x60, 0x20, // protocol op (0x60), 32 bytes + 0x02, 0x01, 0x03, // version (integer value "3") + 0x04, 0x13, // string, 19 bytes + 0x75, 0x69, 0x64, 0x3d, // "uid=" + 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2c, // "admin," + 0x6f, 0x75, 0x3d, 0x73, 0x79, 0x73, // "ou=sys" + 0x74, 0x65, 0x6d, // "tem" + 0x80, 0x06, // auth choice 0 ("simple"), 6 bytes + 0x73, 0x65, 0x63, 0x72, 0x65, 0x74 // "secret" +] + +/** + * Represents an anonymous BIND request. + */ +module.exports.bindRequestAnonymousBytes = [ + 0x30, 0x0c, + 0x02, 0x01, 0x01, + 0x60, 0x07, + 0x02, 0x01, 0x03, + 0x04, 0x00, + 0x80, 0x00 +] + +/** + * Represents a BIND response with attributes. + * Taken from https://web.archive.org/web/20220518232654/https://nawilson.com/ldapv3-wire-protocol-reference-bind/ + */ +module.exports.bindResponseBytes = [ + 0x30, 0x0c, // start sequence, 12 bytes + 0x02, 0x01, 0x01, // message id (integer value 1) + 0x61, 0x07, // protocol op (0x61) bind response + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00 // no diagnostic message (0-byte octet string) +] + +/** + * Represents a COMPARE request with attributes. + * Taken from https://web.archive.org/web/20220630080454/https://nawilson.com/ldapv3-wire-protocol-reference-compare/ + */ +module.exports.compareRequestBytes = [ + 0x30, 0x45, // start sequence, 69 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x6e, 0x40, // protocol op (0x6e) compare request + + 0x04, 0x24, // string (target entry dn), 36 bytes + // "uid=jdoe,ou=People,dc=example,dc=com") + 0x75, 0x69, 0x64, 0x3d, 0x6a, 0x64, 0x6f, 0x65, + 0x2c, 0x6f, 0x75, 0x3d, 0x50, 0x65, 0x6f, 0x70, + 0x6c, 0x65, 0x2c, 0x64, 0x63, 0x3d, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, + 0x3d, 0x63, 0x6f, 0x6d, + + 0x30, 0x18, // sequence, 24 bytes + 0x04, 0x0c, // string (attribute name), 12 bytes + // "employeeType" + 0x65, 0x6d, 0x70, 0x6c, + 0x6f, 0x79, 0x65, 0x65, + 0x54, 0x79, 0x70, 0x65, + + 0x04, 0x08, // string (assertion value), 8 bytes + // "salaried" + 0x73, 0x61, 0x6c, 0x61, + 0x72, 0x69, 0x65, 0x64 +] + +/** + * Represents a COMPARE response with attributes. + * Taken from https://web.archive.org/web/20220630080454/https://nawilson.com/ldapv3-wire-protocol-reference-compare/ + */ +module.exports.compareResponseBytes = [ + 0x30, 0x0c, // start sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x6f, 0x07, // protocol op (0x6f), 7 bytes + 0x0a, 0x01, 0x06, // compareTrue result code (enumerated value 6) + 0x04, 0x00, // No matched DN (0-byte octet string) + 0x04, 0x00 // No diagnostic message (0-byte octet string) +] + +/** + * Represents a DELETE request with controls supplied for recursive removal. + * Taken from https://web.archive.org/web/20220629203240/https://ldap.com/ldapv3-wire-protocol-reference-ldap-message/#ldapmessage-example + */ +module.exports.deleteRequestBytes = [ + 0x30, 0x35, // start sequence, 53 bytes + 0x02, 0x01, 0x05, // message id 5 + 0x4a, 0x11, // delete request op (entry), 17 bytes + 0x64, 0x63, 0x3d, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, // dc=exampl + 0x65, 0x2c, 0x64, 0x63, 0x3d, 0x63, 0x6f, 0x6d, // e,dc=com + + 0xa0, 0x1d, // start sequence (controls), 29 bytes + 0x30, 0x1b, // start first control sequence, 27 bytes + 0x04, 0x16, 0x31, 0x2e, // control OID (octet string): + 0x32, 0x2e, 0x38, 0x34, // 1.2.840.113556.1.4.805 + 0x30, 0x2e, 0x31, 0x31, + 0x33, 0x35, 0x35, 0x36, + 0x2e, 0x31, 0x2e, 0x34, + 0x2e, 0x38, 0x30, 0x35, + 0x01, 0x01, 0xff // control criticality (boolean true) +] + +/** + * Represents a DELETE response. + * Taken from https://web.archive.org/web/20220518193408/https://nawilson.com/ldapv3-wire-protocol-reference-delete/ + */ +module.exports.deleteResponseBytes = [ + 0x30, 0x0c, // start sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x6b, 0x07, // protocol op (0x6b), 7 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00 // no diagnostic message (0-byte octet string) +] + +/** + * Represents a simple EXTENSION request with a string name + * and string value. + */ +module.exports.extensionNameAndValueRequestBytes = [ + 0x30, 0x18, // start sequence, 24 bytes + 0x02, 0x01, 0x01, // message ID (integer value 1) + 0x77, 0x13, // protocol op (0x77), 19 bytes + + 0x80, 0x09, // string (request name), 9 bytes + // "1.3.6.1.1" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, 0x31, + + 0x81, 0x06, // string (request value), 6 bytes + // "foobar" + 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72 +] + +/** + * Represents a simple EXTENSION request with a string name + * and no value. + */ +module.exports.extensionNameAndNoValueRequestBytes = [ + 0x30, 0x10, // start sequence, 16 bytes + 0x02, 0x01, 0x01, // message ID (integer value 1) + 0x77, 0x0b, // protocol op (0x77), 11 bytes + + 0x80, 0x09, // string (request name), 9 bytes + // "1.3.6.1.1" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, 0x31 +] + +/** + * Represents an EXTENSION request to modify a password. + * Does not include a new password. + * Taken from https://web.archive.org/web/20220518193613/https://nawilson.com/ldapv3-wire-protocol-reference-extended/ + */ +module.exports.extensionChangePasswordRequestBytes = [ + 0x30, 0x53, // start sequence, 83 bytes + 0x02, 0x01, 0x01, // message ID (integer value 1) + 0x77, 0x4e, // protocol op (0x77), 78 bytes + + 0x80, 0x17, // string (request name; "oid"), 23 bytes + // "1.3.6.1.4.1.4203.1.11.1" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, // The extended request OID + 0x34, 0x2e, 0x31, 0x2e, 0x34, 0x32, 0x30, 0x33, + 0x2e, 0x31, 0x2e, 0x31, 0x31, 0x2e, 0x31, + + 0x81, 0x33, // sequence (request value), 51 bytes + 0x30, 0x31, // sequence, 49 bytes + + 0x80, 0x24, // extension specific string (entry), 36 bytes + // "uid=jdoe,ou=People,dc=example,dc=com" + 0x75, 0x69, 0x64, 0x3d, 0x6a, 0x64, 0x6f, 0x65, + 0x2c, 0x6f, 0x75, 0x3d, 0x50, 0x65, 0x6f, 0x70, + 0x6c, 0x65, 0x2c, 0x64, 0x63, 0x3d, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, + 0x3d, 0x63, 0x6f, 0x6d, + + 0x81, 0x09, // extension specific string (value), 9 bytes + // "secret123" + 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x31, 0x32, + 0x33 +] + +/** + * Represents an EXTENSION request to modify a password. + * Only provides the new password. + */ +module.exports.extensionChangePasswordWithNewPasswordBytes = [ + 0x30, 0x2d, // start sequence, 45 bytes + 0x02, 0x01, 0x01, // message ID (integer value 1) + 0x77, 0x28, // protocol op (0x77), 40 bytes + + 0x80, 0x17, // string (request name; "oid"), 23 bytes + // "1.3.6.1.4.1.4203.1.11.1" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, // The extended request OID + 0x34, 0x2e, 0x31, 0x2e, 0x34, 0x32, 0x30, 0x33, + 0x2e, 0x31, 0x2e, 0x31, 0x31, 0x2e, 0x31, + + 0x81, 0x0d, // sequence (request value), 13 bytes + 0x30, 0x0b, // sequence, 11 bytes + + 0x82, 0x09, // extension specific string (value), 9 bytes + // "secret123" + 0x73, 0x65, 0x63, 0x72, + 0x65, 0x74, 0x31, 0x32, + 0x33 +] + +/** + * Represents an EXTENSION response that is an unsolicited response. + * Taken from https://web.archive.org/web/20220518193613/https://nawilson.com/ldapv3-wire-protocol-reference-extended/ + */ +module.exports.extensionDisconnectionNotificationResponseBytes = [ + 0x30, 0x49, // start sequence, 73 bytes + 0x02, 0x01, 0x00, // message ID (integer value 0) + 0x78, 0x44, // protocol op (0x78), 68 bytes + 0x0a, 0x01, 0x34, // unavailable result code (enumerated value 52) + 0x04, 0x00, // no matched DN (0-byte octet string) + + 0x04, 0x25, // string (diagnostic message), 37 bytes + // "The Directory Server is shutting down" + 0x54, 0x68, 0x65, 0x20, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, + 0x73, 0x68, 0x75, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x64, 0x6f, 0x77, 0x6e, + + 0x8a, 0x16, // string (oid) + // "1.3.6.1.4.1.1466.20036" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, + 0x34, 0x2e, 0x31, 0x2e, 0x31, 0x34, 0x36, 0x36, + 0x2e, 0x32, 0x30, 0x30, 0x33, 0x36 +] + +/** + * Represents an EXTENSION request for a Who Am I? request. + * Taken from https://www.rfc-editor.org/rfc/rfc4532#section-2.1 + */ +module.exports.extensionWhoAmIRequestBytes = [ + 0x30, 0x1e, // start sequence, 30 bytes + 0x02, 0x01, 0x02, // message id, 2 + 0x77, 0x19, // protocol op (0x77), 25 bytes + 0x80, 0x17, // string (oid), 23 bytes + // "1.3.6.1.4.1.4203.1.11.3" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, + 0x2e, 0x34, 0x2e, 0x31, 0x2e, 0x34, 0x32, + 0x30, 0x33, 0x2e, 0x31, 0x2e, 0x31, 0x31, + 0x2e, 0x33 +] + +/** + * Represents a CANCEL request as described in + * https://www.rfc-editor.org/rfc/rfc3909#section-2.1. + */ +module.exports.extensionCancelRequestBytes = [ + 0x30, 0x19, // start sequence, 25 bytes + 0x02, 0x01, 0x02, // message id, 2 + 0x77, 0x14, // protocol op (0x77), 20 bytes + + 0x80, 0x0b, // string (oid), 11 bytes + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, + 0x31, 0x2e, 0x31, 0x2e, 0x38, + + 0x81, 0x05, // value sequence, 5 bytes + 0x30, 0x03, // sequence, 3 bytes + 0x02, 0x01, 0x01 // message id 1 +] + +/** + * Represents a CANCEL response as described in + * https://www.rfc-editor.org/rfc/rfc3909#section-2.2. + */ +module.exports.extensionCancelResponseBytes = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer 2) + 0x78, 0x07, // protocol op (0x78), 7 bytes + 0x0a, 0x01, 0x76, // status code, 118 (canceled) + 0x04, 0x00, // no matched dn + 0x04, 0x00 // no diagnostic message +] + +/** + * Represents a Start TLS request as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.14.1. + * + * Taken from + * https://web.archive.org/web/20220518193613/https://nawilson.com/ldapv3-wire-protocol-reference-extended/ + */ +module.exports.extenstionStartTLSRequestBytes = [ + 0x30, 0x1d, // sequence, 29 bytes + 0x02, 0x01, 0x01, // message id (integer value 1) + 0x77, 0x18, // protocol op (0x77), 24 bytes + + 0x80, 0x16, // name sequence, 22 bytes + // "1.3.6.1.4.1.1466.20037" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, + 0x34, 0x2e, 0x31, 0x2e, 0x31, 0x34, 0x36, 0x36, + 0x2e, 0x32, 0x30, 0x30, 0x33, 0x37 +] + +/** + * Represents a Start TLS response as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.14.2. + * + * Taken from + * https://web.archive.org/web/20220518193613/https://nawilson.com/ldapv3-wire-protocol-reference-extended/ + */ +module.exports.extensionStartTLSResponseBytes = [ + 0x30, 0x24, // sequence, 36 bytes + 0x02, 0x01, 0x01, // message id (integer value 1) + 0x78, 0x1f, // protocol op (0x78), 31 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched dn (0-byte octet string) + 0x04, 0x00, // do diagnostic message (0-byte octet string) + + 0x8a, 0x16, // value string, 22 bytes + // "1.3.6.1.4.1.1466.20037" + 0x31, 0x2e, 0x33, 0x2e, 0x36, 0x2e, 0x31, 0x2e, + 0x34, 0x2e, 0x31, 0x2e, 0x31, 0x34, 0x36, 0x36, + 0x2e, 0x32, 0x30, 0x30, 0x33, 0x37 +] + +/** + * Represents a MODIFY request. + * Taken from https://web.archive.org/web/20220518184303/https://nawilson.com/ldapv3-wire-protocol-reference-modify/. + */ +module.exports.modifyRequestBytes = [ + 0x30, 0x81, 0x80, // sequence start, 128 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x66, 0x7b, // protocol op (0x66), 123 bytes + + 0x04, 0x24, // string, 36 bytes + // "uid=jdoe,ou=People,dc=example,dc=com" + 0x75, 0x69, 0x64, 0x3d, 0x6a, 0x64, 0x6f, 0x65, + 0x2c, 0x6f, 0x75, 0x3d, 0x50, 0x65, 0x6f, 0x70, + 0x6c, 0x65, 0x2c, 0x64, 0x63, 0x3d, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, + 0x3d, 0x63, 0x6f, 0x6d, + + 0x30, 0x53, // start sequence (modifications), 83 bytes + + 0x30, 0x18, // sequence, 24 bytes + 0x0a, 0x01, 0x01, // delete modification type (enumerated value 1) + 0x30, 0x13, // sequence, 19 bytes + 0x04, 0x09, // string, 9 bytes + // "givenName" + 0x67, 0x69, 0x76, 0x65, + 0x6e, 0x4e, 0x61, 0x6d, + 0x65, + 0x31, 0x06, // string, 6 bytes + // "John" + 0x04, 0x04, 0x4a, + 0x6f, 0x68, 0x6e, + + 0x30, 0x1c, // sequence, 28 bytes + 0x0a, 0x01, 0x00, // add modification type (enumerated value 0) + 0x30, 0x17, // sequence, 23 bytes + 0x04, 0x09, // string, 9 bytes + // "givenName" + 0x67, 0x69, 0x76, 0x65, + 0x6e, 0x4e, 0x61, 0x6d, + 0x65, + 0x31, 0x0a, // string, 10 bytes + // "Jonathan" + 0x04, 0x08, 0x4a, 0x6f, 0x6e, + 0x61, 0x74, 0x68, 0x61, 0x6e, + + 0x30, 0x19, // sequence, 25 bytes + 0x0a, 0x01, 0x02, // replace modification type (enumerated value 2) + 0x30, 0x14, // sequence, 20 bytes + 0x04, 0x02, // string, 2 bytes + // "cn" + 0x63, 0x6e, + 0x31, 0x0e, // string, 14 bytes + // "Jonathan Doe" + 0x04, 0x0c, 0x4a, 0x6f, + 0x6e, 0x61, 0x74, 0x68, + 0x61, 0x6e, 0x20, 0x44, + 0x6f, 0x65 +] + +/** + * Represents a MODIFY response. + * Taken from https://web.archive.org/web/20220518184303/https://nawilson.com/ldapv3-wire-protocol-reference-modify/. + */ +module.exports.modifyResponseBytes = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x67, 0x07, // protocol op (0x67), 7 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched dn + 0x04, 0x00 // no diagnostic message +] + +/** + * Represents a MODIFYDN request. + * Taken from https://web.archive.org/web/20220630073359/https://nawilson.com/ldapv3-wire-protocol-reference-modify-dn/. + */ +module.exports.modifyDnRequestBytes = [ + 0x30, 0x58, // sequence, 88 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x6c, 0x53, // protocol op (0x6c), 83 bytes + + 0x04, 0x24, // string, 36 bytes + // "uid=jdoe,ou=People,dc=example,dc=com" + 0x75, 0x69, 0x64, 0x3d, 0x6a, 0x64, 0x6f, 0x65, + 0x2c, 0x6f, 0x75, 0x3d, 0x50, 0x65, 0x6f, 0x70, + 0x6c, 0x65, 0x2c, 0x64, 0x63, 0x3d, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, + 0x3d, 0x63, 0x6f, 0x6d, + + 0x04, 0x0c, // string, 12 bytes + // "uid=john.doe" + 0x75, 0x69, 0x64, 0x3d, + 0x6a, 0x6f, 0x68, 0x6e, + 0x2e, 0x64, 0x6f, 0x65, + + 0x01, 0x01, 0xff, // Delete the old RDN value (boolean true) + + 0x80, 0x1a, // context specific string, 26 bytes + // "ou=Users,dc=example,dc=com" + 0x6f, 0x75, 0x3d, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x2c, 0x64, 0x63, 0x3d, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, 0x3d, 0x63, + 0x6f, 0x6d +] + +/** + * Represents a MODIFYDN response. + * Taken from https://web.archive.org/web/20220630073359/https://nawilson.com/ldapv3-wire-protocol-reference-modify-dn/. + */ +module.exports.modifyDnResponseBytes = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x6d, 0x07, // protocol op (0x6d), 7 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched dn + 0x04, 0x00 // no diagnostic message +] + +/** + * Represents an UNBIND request. + * Taken from https://web.archive.org/web/20220518231541/https://nawilson.com/ldapv3-wire-protocol-reference-unbind/. + */ +module.exports.unbindRequestBytes = [ + 0x30, 0x05, // sequence, 5 bytes + 0x02, 0x01, 0x03, // message id (integer value 3) + 0x42, 0x00 // protocol op (0x42), 0 bytes +] + +/** + * Represents a SEARCHREQUEST request. + * Taken from https://web.archive.org/web/20220518215838/https://nawilson.com/ldapv3-wire-protocol-reference-search/. + */ +module.exports.searchRequestBytes = [ + 0x30, 0x56, // sequence, 86 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x63, 0x51, // protocol op, 81 bytes + + 0x04, 0x11, // string sequence, 17 bytes + // "dc=example,dc=com" + 0x64, 0x63, 0x3d, 0x65, + 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2c, 0x64, + 0x63, 0x3d, 0x63, 0x6f, + 0x6d, + + 0x0a, 0x01, 0x02, // wholeSubtree scope (enumerated value 2) + + 0x0a, 0x01, 0x00, // neverDerefAliases (enumerated value 0) + + 0x02, 0x02, 0x03, 0xe8, // size limit (integer value 1000) + + 0x02, 0x01, 0x1e, // time limit (integer value 30) + + 0x01, 0x01, 0x00, // typesOnly (boolean false) + + 0xa0, 0x24, // begin AND filter, 36 bytes + 0xa3, 0x15, // begin an EQUALITY filter, 21 bytes + 0x04, 0x0b, // string, 11 bytes + // "objectClass" + 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6c, + 0x61, 0x73, 0x73, + 0x04, 0x06, // string, 6 bytes + // "person" + 0x70, 0x65, 0x72, 0x73, + 0x6f, 0x6e, // The assertion value (octet string "person") + 0xa3, 0x0b, // begin an EQUALITY filter, 11 bytes + 0x04, 0x03, // string, 3 bytes + // "uid" + 0x75, 0x69, 0x64, + 0x04, 0x04, // string, 4 bytes + // "jdoe" + 0x6a, 0x64, 0x6f, 0x65, + + 0x30, 0x06, // begin the set of requested attributes, 6 bytes + 0x04, 0x01, // string, 1 byte + // "*" + 0x2a, + 0x04, 0x01, // string, 1 byte + // "+" + 0x2b +] + +/** + * Represents a SEARCHRESULTENTRY response. + * Taken from https://web.archive.org/web/20220518215838/https://nawilson.com/ldapv3-wire-protocol-reference-search/. + */ +module.exports.searchResultEntryBytes = [ + 0x30, 0x49, // sequence, 73 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x64, 0x44, // protocol op (0x64), 68 bytes + + 0x04, 0x11, // string, 17 bytes + // "dc=example,dc=com" + 0x64, 0x63, 0x3d, 0x65, + 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2c, 0x64, + 0x63, 0x3d, 0x63, 0x6f, + 0x6d, + + 0x30, 0x2f, // sequence, 47 bytes (attributes list) + 0x30, 0x1c, // sequence, 28 bytes (first attribute) + 0x04, 0x0b, // string, 11 bytes + // "objectClass" + 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6c, + 0x61, 0x73, 0x73, + 0x31, 0x0d, // set sequence, 13 bytes + 0x04, 0x03, // string, 3 bytes + // "top" + 0x74, 0x6f, 0x70, + 0x04, 0x06, // string, 6 bytes + // "domain" + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + + 0x30, 0x0f, // sequence, 15 bytes (second attribute) + 0x04, 0x02, // string, 2 bytes + // "dc" + 0x64, 0x63, + 0x31, 0x09, // set sequence, 9 bytes + 0x04, 0x07, // string, 7 bytes + // "example" + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65 +] + +/** + * Represents a SEARCHRESULTENTRY response that only returns attribute names. + * Taken from https://web.archive.org/web/20220518215838/https://nawilson.com/ldapv3-wire-protocol-reference-search/. + */ +module.exports.searchResultEntryNoValuesBytes = [ + 0x30, 0x33, // sequence, 51 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x64, 0x2e, // protocol op (0x64), 46 bytes + + 0x04, 0x11, // string, 17 bytes + // "dc=example,dc=com" + 0x64, 0x63, 0x3d, 0x65, + 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2c, 0x64, + 0x63, 0x3d, 0x63, 0x6f, + 0x6d, + + 0x30, 0x19, // sequence, 25 bytes (attributes list) + 0x30, 0x0f, // sequence, 15 bytes (first attribute) + 0x04, 0x0b, // string, 11 bytes + // "objectClass" + 0x6f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x43, 0x6c, + 0x61, 0x73, 0x73, + 0x31, 0x00, // sequence, 0 bytes + + 0x30, 0x06, // sequence, 6 bytes (second attribute) + 0x04, 0x02, // string, 2 bytes + // "dc" + 0x64, 0x63, + 0x31, 0x00 // sequence, 0 bytes +] + +/** + * Represents a SEARCHRESULTREFERENCE response. + * Taken from https://web.archive.org/web/20220518215838/https://nawilson.com/ldapv3-wire-protocol-reference-search/. + */ +module.exports.searchResultReferenceBytes = [ + 0x30, 0x6d, // sequence, 109 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x73, 0x68, // protocol op (0x73), 104 bytes + + 0x04, 0x32, // string, 50 bytes + // "ldap://ds1.example.com:389/dc=example,dc=com??sub?" + 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x64, + 0x73, 0x31, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x33, + 0x38, 0x39, 0x2f, 0x64, 0x63, 0x3d, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, + 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x3f, 0x73, 0x75, + 0x62, 0x3f, + + 0x04, 0x32, // string, 50 bytes + // "ldap://ds2.example.com:389/dc=example,dc=com??sub?" + 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x64, + 0x73, 0x32, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x3a, 0x33, + 0x38, 0x39, 0x2f, 0x64, 0x63, 0x3d, 0x65, 0x78, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2c, 0x64, 0x63, + 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x3f, 0x73, 0x75, + 0x62, 0x3f +] + +/** + * Represents a SEARCHRESULTDONE response. + * Taken from https://web.archive.org/web/20220518215838/https://nawilson.com/ldapv3-wire-protocol-reference-search/. + */ +module.exports.searchResultDoneBytes = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x65, 0x07, // protocol op (0x65), 7 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00 // no diagnostic message (0-byte octet string) +] + +/** + * Represents an INTERMEDIATE response with a name and value. + */ +module.exports.intermediateResponseBytes = [ + 0x30, 0x11, // sequence, 17 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x79, 0x0c, // protocol op (0x79), 12 bytes + + 0x80, 0x5, // string, 5 bytes + // "1.2.3" + 0x31, 0x2e, 0x32, 0x2e, 0x33, + + 0x81, 0x03, // string, 3 bytes + // "foo" + 0x66, 0x6f, 0x6f +] + +/** + * Represents an INTERMEDIATE response with a name but no value. + */ +module.exports.intermediateResponseNoValueBytes = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x79, 0x07, // protocol op (0x79), 12 bytes + + 0x80, 0x5, // string, 5 bytes + // "1.2.3" + 0x31, 0x2e, 0x32, 0x2e, 0x33 +] + +/** + * Represents an INTERMEDIATE response with a value but no name. + */ +module.exports.intermediateResponseNoNameBytes = [ + 0x30, 0x0a, // sequence, 10 bytes + 0x02, 0x01, 0x02, // message id (integer value 2) + 0x79, 0x05, // protocol op (0x79), 5 bytes + + 0x81, 0x03, // string, 3 bytes + // "foo" + 0x66, 0x6f, 0x6f +] diff --git a/node_modules/@ldapjs/messages/lib/messages/abandon-request.js b/node_modules/@ldapjs/messages/lib/messages/abandon-request.js new file mode 100644 index 0000000..0e7215e --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/abandon-request.js @@ -0,0 +1,104 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const Protocol = require('@ldapjs/protocol') +const warning = require('../deprecations') + +/** + * Implements the abandon request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.11 + */ +class AbandonRequest extends LdapMessage { + #abandonId + + /** + * @typedef {LdapMessageOptions} AbandonRequestOptions + * @property {number} [abandonId=0] The message id of the request to abandon. + */ + + /** + * @param {AbandonRequestOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = Protocol.operations.LDAP_REQ_ABANDON + super(options) + + const abandonId = options.abandonId || options.abandonID || 0 + if (options.abandonID) { + warning.emit('LDAP_MESSAGE_DEP_003') + } + this.#abandonId = abandonId + } + + /** + * The identifier for the request that the instance will request be abandoned. + * + * @type {number} + */ + get abandonId () { + return this.#abandonId + } + + /** + * Use {@link abandonId} instead. + * + * @deprecated + */ + get abandonID () { + warning.emit('LDAP_MESSAGE_DEP_003') + return this.#abandonId + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'AbandonRequest' + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.writeInt(this.#abandonId, Protocol.operations.LDAP_REQ_ABANDON) + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.abandonId = this.#abandonId + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.peek() + if (protocolOp !== Protocol.operations.LDAP_REQ_ABANDON) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const abandonId = ber.readInt(Protocol.operations.LDAP_REQ_ABANDON) + return { protocolOp, abandonId } + } +} + +module.exports = AbandonRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/abandon-request.test.js b/node_modules/@ldapjs/messages/lib/messages/abandon-request.test.js new file mode 100644 index 0000000..d82157c --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/abandon-request.test.js @@ -0,0 +1,125 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const warning = require('../deprecations') +const AbandonRequest = require('./abandon-request') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +const { abandonRequestBytes } = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new AbandonRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: 0x50, + type: 'AbandonRequest', + abandonId: 0, + controls: [] + }) + }) + + t.test('emits warning for abandonID', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_003', false) + }) + + const req = new AbandonRequest({ + abandonID: 1 + }) + t.ok(req) + + function handler (error) { + t.equal( + error.message, + 'abandonID is deprecated. Use abandonId instead.' + ) + t.end() + } + }) + + t.test('properties return correct values', t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_MESSAGE_DEP_003', false) + }) + + const req = new AbandonRequest({ + abandonId: 1 + }) + + t.equal(req.abandonId, 1) + t.equal(req.abandonID, 1) + + function handler (error) { + t.equal( + error.message, + 'abandonID is deprecated. Use abandonId instead.' + ) + t.end() + } + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts AbandonRequest to BER', async t => { + const reqBuffer = Buffer.from(abandonRequestBytes) + const reader = new BerReader(reqBuffer) + const message = AbandonRequest.parse(reader) + + const ber = message.toBer() + t.equal('[object BerReader]', Object.prototype.toString.call(ber)) + t.equal(reqBuffer.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns implementation properties', async t => { + const message = new AbandonRequest() + const pojo = message._pojo() + t.strictSame(pojo, { abandonId: 0 }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(abandonRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => AbandonRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(abandonRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = AbandonRequest.parseToPojo(reader) + t.strictSame(pojo, { + protocolOp: 0x50, + abandonId: 5 + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/abandon-response.js b/node_modules/@ldapjs/messages/lib/messages/abandon-response.js new file mode 100644 index 0000000..4970ed4 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/abandon-response.js @@ -0,0 +1,43 @@ +'use strict' + +const LdapResult = require('../ldap-result') + +/** + * Implements the ldapjs specific ABANDON response object. + */ +class AbandonResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = 0x00 + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'AbandonResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: 0x00, + berReader: ber + }) + } +} + +module.exports = AbandonResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/abandon-response.test.js b/node_modules/@ldapjs/messages/lib/messages/abandon-response.test.js new file mode 100644 index 0000000..60449f6 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/abandon-response.test.js @@ -0,0 +1,53 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { + abandonResponseBytes +} = require('./_fixtures/message-byte-arrays') +const AbandonResponse = require('./abandon-response') + +tap.test('basic', async t => { + const res = new AbandonResponse() + t.equal(res.protocolOp, 0x00) + t.equal(res.type, 'AbandonResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new AbandonResponse({ messageId: 1 }) + const ber = res.toBer() + const expected = Buffer.from(abandonResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = abandonResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = AbandonResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = abandonResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => AbandonResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.comment('see the LdapResult test suite for further tests') + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/add-request.js b/node_modules/@ldapjs/messages/lib/messages/add-request.js new file mode 100644 index 0000000..bf24091 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/add-request.js @@ -0,0 +1,277 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const Attribute = require('@ldapjs/attribute') +const Protocol = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') + +/** + * Implements the add request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.7 + */ +class AddRequest extends LdapMessage { + /** + * Path to the LDAP object. + * + * @type {null | import('@ldapjs/dn').DN} + */ + #entry + + /** + * A set of attribute objects. + * + * @type {import('@ldapjs/attribute')[]} + */ + #attributes = [] + + /** + * @typedef {LdapMessageOptions} AddRequestOptions + * @property {string} [entry=null] The path to the LDAP object. + * @property {import('@ldapjs/attribute')[]} [attributes=[]] A set of + * attributes to store at the `entry` path. + */ + + /** + * @param {AddRequestOptions} [options] + * + * @throws When the provided attributes list is invalid. + */ + constructor (options = {}) { + options.protocolOp = Protocol.operations.LDAP_REQ_ADD + super(options) + + this.entry = options.entry || null + this.attributes = options.attributes || [] + } + + /** + * Get a copy of the attributes associated with the request. + * + * @returns {import('@ldapjs/attribute')[]} + */ + get attributes () { + return this.#attributes.slice(0) + } + + /** + * Set the attributes to be added to the entry. Replaces any existing + * attributes. + * + * @param {import('@ldapjs/attribute')[]} attrs + * + * @throws If the input is not an array, or any element is not an + * {@link Attribute} or attribute-like object. + */ + set attributes (attrs) { + if (Array.isArray(attrs) === false) { + throw Error('attrs must be an array') + } + const newAttrs = [] + for (const attr of attrs) { + if (Attribute.isAttribute(attr) === false) { + throw Error('attr must be an Attribute instance or Attribute-like object') + } + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + newAttrs.push(new Attribute(attr)) + continue + } + newAttrs.push(attr) + } + this.#attributes = newAttrs + } + + /** + * The directory path to the object to add. + * + * @type {string} + */ + get entry () { + return this.#entry ?? null + } + + /** + * Define the entry path to the LDAP object. + * + * @param {string | import('@ldapjs/dn').DN} path + */ + set entry (path) { + if (path === null) return + if (typeof path === 'string') { + this.#entry = DN.fromString(path) + } else if (Object.prototype.toString.call(path) === '[object LdapDn]') { + this.#entry = path + } else { + throw Error('entry must be a valid DN string or instance of LdapDn') + } + } + + /** + * Alias of {@link entry}. + * + * @type {string} + */ + get _dn () { + return this.entry + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'AddRequest' + } + + /** + * Add a new {@link Attribute} to the list of request attributes. + * + * @param {import('@ldapjs/attribute')} attr + * + * @throws When the input is not an {@link Attribute} instance. + */ + addAttribute (attr) { + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + throw Error('attr must be an instance of Attribute') + } + + this.#attributes.push(attr) + } + + /** + * Get the list of attribute names for the attributes in the + * request. + * + * @returns {string[]} + */ + attributeNames () { + return this.#attributes.map(attr => attr.type) + } + + /** + * Retrieve an attribute by name from the attributes associated with + * the request. + * + * @param {string} attributeName + * + * @returns {import('@ldapjs/attribute')|null} + * + * @throws When `attributeName` is not a string. + */ + getAttribute (attributeName) { + if (typeof attributeName !== 'string') { + throw Error('attributeName must be a string') + } + + for (const attr of this.#attributes) { + if (attr.type === attributeName) { + return attr + } + } + + return null + } + + /** + * Find the index of an {@link Attribute} in the request's + * attribute set. + * + * @param {string} attributeName + * + * @returns {number} The index of the attribute, or `-1` if not + * found. + * + * @throws When `attributeName` is not a string. + */ + indexOf (attributeName) { + if (typeof attributeName !== 'string') { + throw Error('attributeName must be a string') + } + + for (let i = 0; i < this.#attributes.length; i += 1) { + if (this.#attributes[i].type === attributeName) { + return i + } + } + + return -1 + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(Protocol.operations.LDAP_REQ_ADD) + ber.writeString(this.#entry.toString()) + ber.startSequence() + for (const attr of this.#attributes) { + const attrBer = attr.toBer() + ber.appendBuffer(attrBer.buffer) + } + ber.endSequence() + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.entry = this.#entry ? this.#entry.toString() : null + obj.attributes = [] + for (const attr of this.#attributes) { + obj.attributes.push(attr.pojo) + } + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== Protocol.operations.LDAP_REQ_ADD) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const entry = ber.readString() + const attributes = [] + + // Advance to the first attribute sequence in the set + // of attribute sequences. + ber.readSequence() + + const endOfAttributesPos = ber.offset + ber.length + while (ber.offset < endOfAttributesPos) { + const attribute = Attribute.fromBer(ber) + attribute.type = attribute.type.toLowerCase() + + if (attribute.type === 'objectclass') { + for (let i = 0; i < attribute.values.length; i++) { + attribute.values[i] = attribute.values[i].toLowerCase() + } + } + + attributes.push(attribute) + } + + return { protocolOp, entry, attributes } + } +} + +module.exports = AddRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/add-request.test.js b/node_modules/@ldapjs/messages/lib/messages/add-request.test.js new file mode 100644 index 0000000..d0b10c8 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/add-request.test.js @@ -0,0 +1,316 @@ +'use strict' + +const tap = require('tap') +const Attribute = require('@ldapjs/attribute') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const { DN } = require('@ldapjs/dn') +const AddRequest = require('./add-request') + +const { addRequestBytes } = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new AddRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: 0x68, + type: 'AddRequest', + entry: null, + attributes: [], + controls: [] + }) + }) + + t.test('constructor with args', async t => { + const req = new AddRequest({ + entry: 'dn=foo,dc=example,dc=com', + attributes: [{ + type: 'cn', + values: ['foo'] + }] + }) + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: 0x68, + type: 'AddRequest', + entry: 'dn=foo,dc=example,dc=com', + attributes: [{ + type: 'cn', + values: ['foo'] + }], + controls: [] + }) + }) + + t.end() +}) + +tap.test('.attributes', t => { + t.test('returns a copy of the attributes', async t => { + const inputAttrs = [{ type: 'cn', values: ['foo'] }] + const req = new AddRequest({ + entry: 'cn=foo', + attributes: inputAttrs + }) + const attrs = req.attributes + t.not(attrs, inputAttrs) + t.equal(attrs.length, inputAttrs.length) + }) + + t.test('replaces attributes list', async t => { + const req = new AddRequest({ + entry: 'cn=foo', + attributes: [new Attribute({ type: 'cn', values: ['foo'] })] + }) + t.strictSame(req.attributes[0].pojo, { type: 'cn', values: ['foo'] }) + + req.attributes = [new Attribute({ type: 'sn', values: ['bar'] })] + t.strictSame(req.attributes[0].pojo, { type: 'sn', values: ['bar'] }) + }) + + t.test('throws if not an array', async t => { + const input = { type: 'cn', values: ['foo'] } + t.throws( + () => new AddRequest({ entry: 'cn=foo', attributes: input }), + Error('attrs must be an array') + ) + }) + + t.test('throws if attribute is invalid', async t => { + const input = [{ type: 42, values: ['foo'] }] + t.throws( + () => new AddRequest({ entry: 'cn=foo', attributes: input }), + Error('attr must be an Attribute instance or Attribute-like object') + ) + }) + + t.end() +}) + +tap.test('.entry', t => { + t.test('gets and sets', async t => { + let req = new AddRequest({ entry: 'cn=foo' }) + t.equal(req.entry.toString(), 'cn=foo') + t.equal(req._dn.toString(), 'cn=foo') + + req.entry = 'sn=bar' + t.equal(req.entry.toString(), 'sn=bar') + t.equal(req._dn.toString(), 'sn=bar') + + req.entry = DN.fromString('cn=baz') + t.equal(req.entry.toString(), 'cn=baz') + + req = new AddRequest() + t.equal(req.entry, null) + }) + + t.test('throws for bad value', async t => { + const req = new AddRequest() + t.throws( + () => { + req.entry = { cn: 'foo' } + }, + 'entry must be a valid DN string or instance of LdapDn' + ) + }) + + t.end() +}) + +tap.test('addAttribute', t => { + t.test('throws for invalid input', async t => { + const req = new AddRequest({ entry: 'cn=foo' }) + t.throws( + () => req.addAttribute({ type: 'foo', values: ['foo'] }), + Error('attr must be an instance of Attribute') + ) + }) + + t.test('adds an attribute', async t => { + const req = new AddRequest({ entry: 'cn=foo' }) + req.addAttribute(new Attribute({ type: 'bar', values: ['baz'] })) + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: 0x68, + type: 'AddRequest', + entry: 'cn=foo', + attributes: [{ + type: 'bar', + values: ['baz'] + }], + controls: [] + }) + }) + + t.end() +}) + +tap.test('attributeNames', t => { + t.test('returns the names list', async t => { + const req = new AddRequest({ + entry: 'cn=foo', + attributes: [ + new Attribute({ type: 'bar' }), + new Attribute({ type: 'baz' }), + new Attribute({ type: 'foobar' }), + new Attribute({ type: 'barfoo' }) + ] + }) + t.strictSame(req.attributeNames(), [ + 'bar', + 'baz', + 'foobar', + 'barfoo' + ]) + }) + + t.end() +}) + +tap.test('getAttribute', t => { + t.test('throws for invalid parameter', async t => { + const req = new AddRequest({ entry: 'cn=foo' }) + t.throws( + () => req.getAttribute(42), + Error('attributeName must be a string') + ) + }) + + t.test('returns null for not found', async t => { + const req = new AddRequest({ entry: 'cn=foo' }) + t.equal(req.getAttribute('bar'), null) + }) + + t.test('returns the correct attribute', async t => { + const req = new AddRequest({ + entry: 'cn=foo', + attributes: [ + new Attribute({ type: 'bar' }), + new Attribute({ type: 'baz', values: ['baz', 'baz', 'baz'] }), + new Attribute({ type: 'foobar' }), + new Attribute({ type: 'barfoo' }) + ] + }) + const attr = req.getAttribute('baz') + t.strictSame(attr.pojo, { + type: 'baz', + values: ['baz', 'baz', 'baz'] + }) + }) + + t.end() +}) + +tap.test('indexOf', t => { + t.test('throws for invalid parameter', async t => { + const req = new AddRequest({ entry: 'cn=foo' }) + t.throws( + () => req.indexOf(42), + Error('attributeName must be a string') + ) + }) + + t.test('finds an attribute', async t => { + const req = new AddRequest({ + entry: 'cn=foo', + attributes: [ + new Attribute({ type: 'bar' }), + new Attribute({ type: 'baz' }), + new Attribute({ type: 'foobar' }), + new Attribute({ type: 'barfoo' }) + ] + }) + t.equal(req.indexOf('foobar'), 2) + }) + + t.test('returns for not found', async t => { + const req = new AddRequest({ + entry: 'cn=foo', + attributes: [ + new Attribute({ type: 'bar' }), + new Attribute({ type: 'baz' }), + new Attribute({ type: 'foobar' }), + new Attribute({ type: 'barfoo' }) + ] + }) + t.equal(req.indexOf('zifbang'), -1) + }) + + t.end() +}) + +tap.test('_toBer', t => { + tap.test('converts instance to BER', async t => { + const req = new AddRequest({ + entry: 'dc=example,dc=com', + attributes: [ + new Attribute({ type: 'objectclass', values: ['top', 'domain'] }), + new Attribute({ type: 'dc', values: ['example'] }) + ] + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(addRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new AddRequest({ + entry: 'cn=foo', + attributes: [{ type: 'bar', values: ['baz'] }] + }) + t.strictSame(req._pojo(), { + entry: 'cn=foo', + attributes: [{ + type: 'bar', + values: ['baz'] + }] + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(addRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => AddRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(addRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = AddRequest.parseToPojo(reader) + t.equal(pojo.protocolOp, 0x68) + t.equal(pojo.entry, 'dc=example,dc=com') + t.strictSame(pojo.attributes[0].pojo, { + type: 'objectclass', + values: ['top', 'domain'] + }) + t.strictSame(pojo.attributes[1].pojo, { + type: 'dc', + values: ['example'] + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/add-response.js b/node_modules/@ldapjs/messages/lib/messages/add-response.js new file mode 100644 index 0000000..8e0d15a --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/add-response.js @@ -0,0 +1,45 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the add response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.7 + */ +class AddResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_ADD + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'AddResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_ADD, + berReader: ber + }) + } +} + +module.exports = AddResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/add-response.test.js b/node_modules/@ldapjs/messages/lib/messages/add-response.test.js new file mode 100644 index 0000000..29df7b1 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/add-response.test.js @@ -0,0 +1,56 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations } = require('@ldapjs/protocol') +const { + addResponseBasicBytes +} = require('./_fixtures/message-byte-arrays') +const AddResponse = require('./add-response') + +tap.test('basic', async t => { + const res = new AddResponse() + t.equal(res.protocolOp, operations.LDAP_RES_ADD) + t.equal(res.type, 'AddResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new AddResponse({ messageId: 2 }) + const ber = res.toBer() + const expected = Buffer.from(addResponseBasicBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.comment('see the LdapResult test suite for further tests') + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = addResponseBasicBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = AddResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = addResponseBasicBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => AddResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.comment('see the LdapResult test suite for further tests') + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/bind-request.js b/node_modules/@ldapjs/messages/lib/messages/bind-request.js new file mode 100644 index 0000000..453c160 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/bind-request.js @@ -0,0 +1,167 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const Protocol = require('@ldapjs/protocol') +const { BerTypes } = require('@ldapjs/asn1') + +/** + * Implements the bind request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.2. + * + * The bind request is further defined by: + * https://www.rfc-editor.org/rfc/rfc4513#section-5. + */ +class BindRequest extends LdapMessage { + static SIMPLE_BIND = 'simple' + static SASL_BIND = 'sasl' + + #version = 0x03 + #name + #authentication = BindRequest.SIMPLE_BIND + #credentials = '' + + /** + * @typedef {LdapMessageOptions} BindRequestOptions + * @property {number} [version=3] Version of the protocol being used. + * @property {string} [name=null] The "username" (dn) to connect with. + * @property {string} [authentication='simple'] The authentication + * mechanism to use. Currently, only `simple` is supported. + * @property {string} [credentials=''] The password to use. + */ + + /** + * @param {BindRequestOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = Protocol.operations.LDAP_REQ_BIND + super(options) + + const { + version = 0x03, + name = null, + authentication = BindRequest.SIMPLE_BIND, + credentials = '' + } = options + this.#version = version + this.#name = name + this.#authentication = authentication + this.#credentials = credentials + } + + /** + * The authentication credentials for the request. + * + * @returns {string} + */ + get credentials () { + return this.#credentials + } + + /** + * The DN, or "username", that is to be used in the bind request. + * + * @type {string} + */ + get name () { + return this.#name + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'BindRequest' + } + + /** + * The version number that the bind request conforms to. + * + * @type {number} + */ + get version () { + return this.#version + } + + /** + * Use {@link name} instead. + * + * @type {string} + */ + get _dn () { + return this.#name + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(Protocol.operations.LDAP_REQ_BIND) + ber.writeInt(this.#version) + ber.writeString(this.#name || '') + // TODO add support for SASL et al + ber.writeString(this.#credentials || '', BerTypes.Context) + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.version = this.#version + obj.name = this.#name + obj.authenticationType = this.#authentication + obj.credentials = this.#credentials + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== Protocol.operations.LDAP_REQ_BIND) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const version = ber.readInt() + const name = ber.readString() + + const tag = ber.peek() + + // TODO: add support for SASL et al + if (tag !== BerTypes.Context) { + // Currently only support 0x80. To support SASL, must support 0x83. + const authType = tag.toString(16).padStart(2, '0') + throw Error(`authentication 0x${authType} not supported`) + } + + const authentication = BindRequest.SIMPLE_BIND + const credentials = ber.readString(BerTypes.Context) + + return { + protocolOp, + version, + name, + authentication, + credentials + } + } +} + +module.exports = BindRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/bind-request.test.js b/node_modules/@ldapjs/messages/lib/messages/bind-request.test.js new file mode 100644 index 0000000..d120107 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/bind-request.test.js @@ -0,0 +1,128 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const BindRequest = require('./bind-request') + +const { + bindRequestBytes, + bindRequestAnonymousBytes +} = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new BindRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: 0x60, + type: 'BindRequest', + version: 3, + name: null, + authenticationType: 'simple', + credentials: '', + controls: [] + }) + }) + + t.test('properties return correct values', async t => { + const req = new BindRequest({ + messageId: 1, + version: 999, + name: 'foobar', + authentication: 'nonsense', + credentials: 'secret' + }) + + t.equal(req.credentials, 'secret') + t.equal(req.name, 'foobar') + t.equal(req.type, 'BindRequest') + t.equal(req.version, 999) + t.equal(req._dn, 'foobar') + }) + + t.end() +}) + +tap.test('toBer', t => { + t.test('converts BindRequest to BER', async t => { + const reqBuffer = Buffer.from(bindRequestBytes) + const reader = new BerReader(reqBuffer) + const message = BindRequest.parse(reader) + + const ber = message.toBer() + t.equal('[object BerReader]', Object.prototype.toString.call(ber)) + t.equal(reqBuffer.compare(ber.buffer), 0) + }) + + t.test('converts an anonymous bind request', async t => { + const reqBuffer = Buffer.from(bindRequestAnonymousBytes) + const message = new BindRequest() + const ber = message.toBer() + t.equal(reqBuffer.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns implementation properties', async t => { + const message = new BindRequest() + const pojo = message._pojo() + t.strictSame(pojo, { + version: 3, + name: null, + authenticationType: 'simple', + credentials: '' + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(bindRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => BindRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('throws if simple auth credentials is tagged wrong', async t => { + const reqBuffer = Buffer.from(bindRequestBytes) + reqBuffer[31] = 0x83 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => BindRequest.parseToPojo(reader), + Error('authentication 0x83 not supported') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(bindRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = BindRequest.parseToPojo(reader) + t.strictSame(pojo, { + protocolOp: 0x60, + version: 3, + name: 'uid=admin,ou=system', + authentication: 'simple', + credentials: 'secret' + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/bind-response.js b/node_modules/@ldapjs/messages/lib/messages/bind-response.js new file mode 100644 index 0000000..5bea596 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/bind-response.js @@ -0,0 +1,45 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the bind response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.2.2 + */ +class BindResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_BIND + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'BindResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_BIND, + berReader: ber + }) + } +} + +module.exports = BindResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/bind-response.test.js b/node_modules/@ldapjs/messages/lib/messages/bind-response.test.js new file mode 100644 index 0000000..45179ae --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/bind-response.test.js @@ -0,0 +1,54 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations } = require('@ldapjs/protocol') +const { + bindResponseBytes +} = require('./_fixtures/message-byte-arrays') +const BindResponse = require('./bind-response') + +tap.test('basic', async t => { + const res = new BindResponse() + t.equal(res.protocolOp, operations.LDAP_RES_BIND) + t.equal(res.type, 'BindResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new BindResponse({ messageId: 1 }) + const ber = res.toBer() + const expected = Buffer.from(bindResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = bindResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = BindResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = bindResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => BindResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.comment('see the LdapResult test suite for further tests') + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/compare-request.js b/node_modules/@ldapjs/messages/lib/messages/compare-request.js new file mode 100644 index 0000000..2c9d9b6 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/compare-request.js @@ -0,0 +1,173 @@ +'use strict' + +const { operations } = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') +const LdapMessage = require('../ldap-message') + +/** + * Implements the compare request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.10. + */ +class CompareRequest extends LdapMessage { + #attribute + #entry + #value + + /** + * @typedef {LdapMessageOptions} CompareRequestOptions + * @property {string|null} [attribute] The attribute name to compare + * against. + * @property {string} [entry] The target LDAP entity whose attribute + * will be compared. + * @property {string} [value] The value of the attribute to compare. + */ + + /** + * @param {CompareRequestOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_REQ_COMPARE + super(options) + + this.attribute = options.attribute || '' + this.entry = options.entry || null + this.value = options.value || '' + } + + /** + * The property of an LDAP entry to compare against. + * + * @returns {string} + */ + get attribute () { + return this.#attribute + } + + /** + * Define the LDAP entry property to compare against. + * + * @param {string} value + */ + set attribute (value) { + this.#attribute = value + } + + /** + * The LDAP entry that will be inspected. + * + * @returns {string | null} + */ + get entry () { + return this.#entry ?? null + } + + /** + * Define the LDAP entity to inspect. + * + * @param {string | null} value + */ + set entry (value) { + if (value === null) return + if (typeof value === 'string') { + this.#entry = DN.fromString(value) + } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { + this.#entry = value + } else { + throw Error('entry must be a valid DN string or instance of LdapDn') + } + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'CompareRequest' + } + + /** + * The value the attribute should be set to. + * + * @returns {string} + */ + get value () { + return this.#value + } + + /** + * Define the value the attribute should match. + * + * @param {string} value + */ + set value (value) { + this.#value = value + } + + get _dn () { + return this.#entry + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_REQ_COMPARE) + + ber.writeString(this.#entry.toString()) + ber.startSequence() + ber.writeString(this.#attribute) + ber.writeString(this.#value) + ber.endSequence() + + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.attribute = this.#attribute + obj.entry = this.#entry ? this.#entry.toString() : null + obj.value = this.#value + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_REQ_COMPARE) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const entry = ber.readString() + ber.readSequence() + const attribute = ber.readString() + const value = ber.readString() + + return { + protocolOp, + entry, + attribute, + value + } + } +} + +module.exports = CompareRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/compare-request.test.js b/node_modules/@ldapjs/messages/lib/messages/compare-request.test.js new file mode 100644 index 0000000..335f521 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/compare-request.test.js @@ -0,0 +1,168 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const { DN } = require('@ldapjs/dn') +const CompareRequest = require('./compare-request') + +const { compareRequestBytes } = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new CompareRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_COMPARE, + type: 'CompareRequest', + entry: null, + attribute: '', + value: '', + controls: [] + }) + }) + + t.test('constructor with args', async t => { + const req = new CompareRequest({ + entry: 'dn=foo,dc=example,dc=com', + attribute: 'foo', + value: 'bar' + }) + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_COMPARE, + type: 'CompareRequest', + entry: 'dn=foo,dc=example,dc=com', + attribute: 'foo', + value: 'bar', + controls: [] + }) + }) + + t.test('.type', async t => { + const req = new CompareRequest() + t.equal(req.type, 'CompareRequest') + }) + + t.test('.dn', async t => { + const req = new CompareRequest({ entry: 'dn=foo,dc=example,dc=com' }) + t.equal(req.dn.toString(), 'dn=foo,dc=example,dc=com') + }) + + t.end() +}) + +tap.test('.attribute', t => { + t.test('gets and sets', async t => { + const req = new CompareRequest() + t.equal(req.attribute, '') + req.attribute = 'foo' + t.equal(req.attribute, 'foo') + }) + + t.end() +}) + +tap.test('.entry', t => { + t.test('gets and sets', async t => { + const req = new CompareRequest() + t.equal(req.entry, null) + + req.entry = 'cn=foo' + t.equal(req.entry.toString(), 'cn=foo') + + req.entry = DN.fromString('sn=bar') + t.equal(req.entry.toString(), 'sn=bar') + }) + + t.test('throws for bad value', async t => { + const req = new CompareRequest() + t.throws( + () => { + req.entry = { cn: 'foo' } + }, + 'entry must be a valid DN string or instance of LdapDn' + ) + }) + + t.end() +}) + +tap.test('.value', t => { + t.test('gets and sets', async t => { + const req = new CompareRequest() + t.equal(req.value, '') + req.value = 'foo' + t.equal(req.value, 'foo') + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('converts instance to BER', async t => { + const req = new CompareRequest({ + messageId: 2, + entry: 'uid=jdoe,ou=People,dc=example,dc=com', + attribute: 'employeeType', + value: 'salaried' + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(compareRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new CompareRequest({ + entry: 'cn=foo', + attribute: 'bar', + value: 'baz' + }) + t.strictSame(req._pojo(), { + entry: 'cn=foo', + attribute: 'bar', + value: 'baz' + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(compareRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => CompareRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(compareRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = CompareRequest.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_REQ_COMPARE) + t.equal(pojo.entry, 'uid=jdoe,ou=People,dc=example,dc=com') + t.equal(pojo.attribute, 'employeeType') + t.equal(pojo.value, 'salaried') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/compare-response.js b/node_modules/@ldapjs/messages/lib/messages/compare-response.js new file mode 100644 index 0000000..7e5f5cb --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/compare-response.js @@ -0,0 +1,45 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the compare response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.10. + */ +class CompareResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_COMPARE + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'CompareResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_COMPARE, + berReader: ber + }) + } +} + +module.exports = CompareResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/compare-response.test.js b/node_modules/@ldapjs/messages/lib/messages/compare-response.test.js new file mode 100644 index 0000000..67ea56f --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/compare-response.test.js @@ -0,0 +1,55 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations, resultCodes } = require('@ldapjs/protocol') +const { + compareResponseBytes +} = require('./_fixtures/message-byte-arrays') +const CompareResponse = require('./compare-response') + +tap.test('basic', async t => { + const res = new CompareResponse() + t.equal(res.protocolOp, operations.LDAP_RES_COMPARE) + t.equal(res.type, 'CompareResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new CompareResponse({ + messageId: 2, + status: resultCodes.COMPARE_TRUE + }) + const ber = res.toBer() + const expected = Buffer.from(compareResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = compareResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = CompareResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: resultCodes.COMPARE_TRUE, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = compareResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => CompareResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/delete-request.js b/node_modules/@ldapjs/messages/lib/messages/delete-request.js new file mode 100644 index 0000000..06ea012 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/delete-request.js @@ -0,0 +1,116 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const Protocol = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') + +/** + * Implements the delete request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.8 + */ +class DeleteRequest extends LdapMessage { + #entry + + /** + * @typedef {LdapMessageOptions} DeleteRequestOptions + * @property {string} [entry=null] The LDAP entry path to remove. + */ + + /** + * @param {DeleteRequestOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = Protocol.operations.LDAP_REQ_DELETE + super(options) + + this.entry = options.entry ?? null + } + + /** + * Alias of {@link name}. + * + * @type {string} + */ + get _dn () { + return this.entry + } + + /** + * The identifier for the request that the instance will request be abandoned. + * + * @type {number} + */ + get entry () { + return this.#entry ?? null + } + + /** + * Define the path to the LDAP object that will be deleted. + * + * @param {string | null | import('@ldapjs/dn').DN} value + */ + set entry (value) { + if (value === null) return + if (typeof value === 'string') { + this.#entry = DN.fromString(value) + } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { + this.#entry = value + } else { + throw Error('entry must be a valid DN string or instance of LdapDn') + } + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'DeleteRequest' + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.writeString(this.#entry.toString(), Protocol.operations.LDAP_REQ_DELETE) + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.protocolOp = Protocol.operations.LDAP_REQ_DELETE + obj.entry = this.#entry ? this.#entry.toString() : null + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.peek() + if (protocolOp !== Protocol.operations.LDAP_REQ_DELETE) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const entry = ber.readString(Protocol.operations.LDAP_REQ_DELETE) + return { protocolOp, entry } + } +} + +module.exports = DeleteRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/delete-request.test.js b/node_modules/@ldapjs/messages/lib/messages/delete-request.test.js new file mode 100644 index 0000000..800d315 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/delete-request.test.js @@ -0,0 +1,115 @@ +'use strict' + +const tap = require('tap') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const { DN } = require('@ldapjs/dn') +const DeleteRequest = require('./delete-request') + +tap.test('constructor', t => { + t.test('no args', async t => { + const req = new DeleteRequest() + t.strictSame(req.pojo, { + messageId: 1, + type: 'DeleteRequest', + protocolOp: 0x4a, + entry: null, + controls: [] + }) + }) + + t.test('with options', async t => { + const req = new DeleteRequest({ + messageId: 5, + entry: 'dc=example,dc=com' + }) + t.strictSame(req.pojo, { + messageId: 5, + type: 'DeleteRequest', + protocolOp: 0x4a, + entry: 'dc=example,dc=com', + controls: [] + }) + + t.equal(req._dn.toString(), 'dc=example,dc=com') + t.equal(req.entry.toString(), 'dc=example,dc=com') + t.equal(req.type, 'DeleteRequest') + }) + + t.end() +}) + +tap.test('.entry', t => { + t.test('sets/gets', async t => { + const req = new DeleteRequest() + t.equal(req.entry, null) + t.equal(req._dn, null) + + req.entry = 'cn=foo' + t.equal(req.entry.toString(), 'cn=foo') + t.equal(req._dn.toString(), 'cn=foo') + + req.entry = DN.fromString('sn=bar') + t.equal(req.entry.toString(), 'sn=bar') + }) + + t.test('throws for bad value', async t => { + const req = new DeleteRequest() + t.throws( + () => { + req.entry = { cn: 'foo' } + }, + 'entry must be a valid DN string or instance of LdapDn' + ) + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('writes a correct sequence', async t => { + const req = new DeleteRequest({ entry: 'cn=foo' }) + const ber = new BerWriter() + req._toBer(ber) + + const expected = Buffer.from([ + 0x4a, 0x06, 0x63, 0x6e, + 0x3d, 0x66, 0x6f, 0x6f + ]) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns implementation properties', async t => { + const req = new DeleteRequest({ entry: 'cn=foo' }) + t.strictSame(req._pojo(), { + protocolOp: 0x4a, + entry: 'cn=foo' + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if tag is wrong', async t => { + const input = Buffer.from([0x4b, 0x03, 0x66, 0x6f, 0x6f]) + t.throws( + () => DeleteRequest.parseToPojo(new BerReader(input)), + Error('found wrong protocol operation: 0x4b') + ) + }) + + t.test('returns a pojo', async t => { + const input = Buffer.from([0x4a, 0x03, 0x66, 0x6f, 0x6f]) + const pojo = DeleteRequest.parseToPojo(new BerReader(input)) + t.strictSame(pojo, { + protocolOp: 0x4a, + entry: 'foo' + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/delete-response.js b/node_modules/@ldapjs/messages/lib/messages/delete-response.js new file mode 100644 index 0000000..bdf6496 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/delete-response.js @@ -0,0 +1,45 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the delete response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.8. + */ +class DeleteResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_DELETE + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'DeleteResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_DELETE, + berReader: ber + }) + } +} + +module.exports = DeleteResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/delete-response.test.js b/node_modules/@ldapjs/messages/lib/messages/delete-response.test.js new file mode 100644 index 0000000..ff5ff19 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/delete-response.test.js @@ -0,0 +1,52 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations } = require('@ldapjs/protocol') +const { + deleteResponseBytes +} = require('./_fixtures/message-byte-arrays') +const DeleteResponse = require('./delete-response') + +tap.test('basic', async t => { + const res = new DeleteResponse() + t.equal(res.protocolOp, operations.LDAP_RES_DELETE) + t.equal(res.type, 'DeleteResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new DeleteResponse({ messageId: 2 }) + const ber = res.toBer() + const expected = Buffer.from(deleteResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = deleteResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = DeleteResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = deleteResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => DeleteResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-request.js b/node_modules/@ldapjs/messages/lib/messages/extension-request.js new file mode 100644 index 0000000..42182f7 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-request.js @@ -0,0 +1,284 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const { operations } = require('@ldapjs/protocol') +const RECOGNIZED_OIDS = require('./extension-utils/recognized-oids') + +/** + * Implements the extension request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.12. + * + * There is a set of supported extension request OIDs supported. Any + * unrecognized OID will be treated a simple string pair, i.e. both + * `requestName` and `requestValue` will be assumed to be simple strings. + */ +class ExtensionRequest extends LdapMessage { + #requestName + #requestValue + + /** + * @typedef {LdapMessageOptions} ExtensionRequestOptions + * @property {string} [requestName=''] The name of the extension, i.e. + * OID for the request. + * @property {string|object} [requestValue] The value for the request. + * If `undefined`, no value will be sent. If the request requires a simple + * string value, provide such a string. For complex valued requests, e.g. + * for a password modify request, it should be a plain object with the + * appropriate properties. See the implementation of {@link parseToPojo} + * for the set of supported objects. + */ + + /** + * @param {ExtensionRequestOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_REQ_EXTENSION + super(options) + + this.requestName = options.requestName || '' + this.requestValue = options.requestValue + } + + /** + * Alias of {@link requestName}. + * + * @type {string} + */ + get _dn () { + return this.#requestName + } + + /** + * The name (OID) of the request. + * + * @returns {string} + */ + get requestName () { + return this.#requestName + } + + /** + * Set the name for the request. Should be an OID that + * matches a specification. + * + * @param {string} value + */ + set requestName (value) { + this.#requestName = value + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'ExtensionRequest' + } + + /** + * The value, if any, for the request. + * + * @returns {undefined|string|object} value + */ + get requestValue () { + return this.#requestValue + } + + /** + * Set the value for the request. The value should conform + * to the specification identified by the {@link requestName}. + * See the implemenation of {@link parseToPojo} for valid + * value shapes. + * + * @param {undefined|string|object} value + */ + set requestValue (val) { + this.#requestValue = val + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_REQ_EXTENSION) + ber.writeString(this.requestName, 0x80) + + if (this.requestValue) { + switch (this.requestName) { + case RECOGNIZED_OIDS.get('CANCEL_REQUEST'): { + encodeCancelRequest({ ber, requestValue: this.requestValue }) + break + } + + case RECOGNIZED_OIDS.get('PASSWORD_MODIFY'): { + encodePasswordModify({ + ber, + requestValue: this.requestValue + }) + break + } + + default: { + // We assume the value is a plain string since + // we do not recognize the request OID, or we know + // that the OID uses a plain string value. + ber.writeString(this.requestValue, 0x81) + } + } + } + + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.requestName = this.requestName + obj.requestValue = this.requestValue + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_REQ_EXTENSION) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + // While the requestName is an OID, it is not an + // _encoded_ OID. It is a plain string. So we do + // not use `.readOID` here. + const requestName = ber.readString(0x80) + if (ber.peek() !== 0x81) { + // There is not a request value present, so we just + // return an empty value representation. + return { protocolOp, requestName } + } + + let requestValue + switch (requestName) { + case RECOGNIZED_OIDS.get('CANCEL_REQUEST'): { + requestValue = readCancelRequest(ber) + break + } + + case RECOGNIZED_OIDS.get('PASSWORD_MODIFY'): { + requestValue = readPasswordModify(ber) + break + } + + default: { + // We will assume it is a plain string value + // since we do not recognize the OID, or we know + // that the OID uses a plain string value. + requestValue = ber.readString(0x81) + break + } + } + + return { protocolOp, requestName, requestValue } + } + + /** + * A list of EXTENDED operation OIDs that this module + * recognizes. Key names are named according to the common name + * of the extension. Key values are the OID associated with that + * extension. For example, key `PASSWORD_MODIFY` corresponds to + * OID `1.3.6.1.4.1.4203.1.11.1`. + * + * @returns {Map} + */ + static recognizedOIDs () { + return RECOGNIZED_OIDS + } +} + +module.exports = ExtensionRequest + +/** + * @param {object} input + * @param {@import('@ldapjs/asn1').BerWriter} input.ber + * @param {object} requestValue + */ +function encodeCancelRequest ({ ber, requestValue }) { + ber.startSequence(0x81) + ber.startSequence() + ber.writeInt(requestValue) + ber.endSequence() + ber.endSequence() +} + +/** + * @param {@import('@ldapjs/asn1').BerReader} ber + * @returns {number} + */ +function readCancelRequest (ber) { + ber.readSequence(0x81) + ber.readSequence() + return ber.readInt() +} + +/** + * @param {object} input + * @param {@import('@ldapjs/asn1').BerWriter} input.ber + * @param {object} requestValue + */ +function encodePasswordModify ({ ber, requestValue }) { + // start the value sequence + ber.startSequence(0x81) + // start the generic packed sequence + ber.startSequence() + if (requestValue.userIdentity) { + ber.writeString(requestValue.userIdentity, 0x80) + } + if (requestValue.oldPassword) { + ber.writeString(requestValue.oldPassword, 0x81) + } + if (requestValue.newPassword) { + ber.writeString(requestValue.newPassword, 0x82) + } + ber.endSequence() + ber.endSequence() +} + +/** + * @param {@import('@ldapjs/asn1').BerReader} ber + * @returns {object} + */ +function readPasswordModify (ber) { + // advance to the embedded sequence + ber.readSequence(0x81) + // advance to the value of the embedded sequence + ber.readSequence() + let userIdentity + if (ber.peek() === 0x80) { + userIdentity = ber.readString(0x80) + } + let oldPassword + if (ber.peek() === 0x81) { + oldPassword = ber.readString(0x81) + } + let newPassword + if (ber.peek() === 0x82) { + newPassword = ber.readString(0x82) + } + return { userIdentity, oldPassword, newPassword } +} diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-request.test.js b/node_modules/@ldapjs/messages/lib/messages/extension-request.test.js new file mode 100644 index 0000000..735650f --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-request.test.js @@ -0,0 +1,254 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const ExtensionRequest = require('./extension-request') + +const { + extensionCancelRequestBytes, + extensionNameAndValueRequestBytes, + extensionNameAndNoValueRequestBytes, + extensionChangePasswordRequestBytes, + extensionChangePasswordWithNewPasswordBytes +} = require('./_fixtures/message-byte-arrays') +const { BerReader, BerWriter } = require('@ldapjs/asn1') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new ExtensionRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_EXTENSION, + type: 'ExtensionRequest', + requestName: '', + requestValue: undefined, + controls: [] + }) + }) + + t.test('constructor with args', async t => { + const req = new ExtensionRequest({ + requestName: 'foo', + requestValue: 'bar' + }) + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_EXTENSION, + type: 'ExtensionRequest', + requestName: 'foo', + requestValue: 'bar', + controls: [] + }) + }) + + t.test('.type', async t => { + const req = new ExtensionRequest() + t.equal(req.type, 'ExtensionRequest') + }) + + t.test('.dn', async t => { + const req = new ExtensionRequest({ requestName: 'foo' }) + t.equal(req.dn, 'foo') + }) + + t.test('#recognizedOIDs returns map', async t => { + const oids = ExtensionRequest.recognizedOIDs() + t.type(oids, 'Map') + }) + + t.end() +}) + +tap.test('.name', t => { + t.test('gets and sets', async t => { + const req = new ExtensionRequest() + t.equal(req.requestName, '') + req.requestName = 'foo' + t.equal(req.requestName, 'foo') + }) + + t.end() +}) + +tap.test('.value', t => { + t.test('gets and sets', async t => { + const req = new ExtensionRequest() + t.equal(req.requestValue, undefined) + req.requestValue = 'foo' + t.equal(req.requestValue, 'foo') + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('converts simple instance to BER', async t => { + const req = new ExtensionRequest({ + requestName: '1.3.6.1.1', + requestValue: 'foobar' + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(extensionNameAndValueRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.test('converts a simple instance with no value to BER', async t => { + const req = new ExtensionRequest({ requestName: '1.3.6.1.1' }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(extensionNameAndNoValueRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.test('converts a cancel request', async t => { + const req = new ExtensionRequest({ + requestName: '1.3.6.1.1.8', + requestValue: 1 + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(extensionCancelRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.test('converts a modify password request with userIdentity and oldPassword', async t => { + const req = new ExtensionRequest({ + requestName: '1.3.6.1.4.1.4203.1.11.1', + requestValue: { + userIdentity: 'uid=jdoe,ou=People,dc=example,dc=com', + oldPassword: 'secret123' + } + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(extensionChangePasswordRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.test('converts a modify password request with newPassword', async t => { + const req = new ExtensionRequest({ + requestName: '1.3.6.1.4.1.4203.1.11.1', + requestValue: { + newPassword: 'secret123' + } + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(extensionChangePasswordWithNewPasswordBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new ExtensionRequest({ + requestName: 'foo', + requestValue: 'bar' + }) + t.strictSame(req._pojo(), { + requestName: 'foo', + requestValue: 'bar' + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(extensionNameAndValueRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => ExtensionRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo for a name only operation', async t => { + const reqBuffer = Buffer.from(extensionNameAndNoValueRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = ExtensionRequest.parseToPojo(reader) + t.equal(pojo.requestName, '1.3.6.1.1') + t.equal(pojo.requestValue, undefined) + }) + + t.test('returns a pojo for simple string name and value operation', async t => { + const reqBuffer = Buffer.from(extensionNameAndValueRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = ExtensionRequest.parseToPojo(reader) + t.equal(pojo.requestName, '1.3.6.1.1') + t.equal(pojo.requestValue, 'foobar') + }) + + t.test('returns pojo for a cancel request', async t => { + const reqBuffer = Buffer.from(extensionCancelRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = ExtensionRequest.parseToPojo(reader) + t.equal(pojo.requestName, '1.3.6.1.1.8') + t.equal(pojo.requestValue, 1) + }) + + t.test('returns a pojo for a modify password with user and old pass', async t => { + const reqBuffer = Buffer.from(extensionChangePasswordRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = ExtensionRequest.parseToPojo(reader) + t.equal(pojo.requestName, '1.3.6.1.4.1.4203.1.11.1') + t.strictSame(pojo.requestValue, { + userIdentity: 'uid=jdoe,ou=People,dc=example,dc=com', + oldPassword: 'secret123', + newPassword: undefined + }) + }) + + t.test('returns a pojo for a modify password new pass', async t => { + const reqBuffer = Buffer.from(extensionChangePasswordWithNewPasswordBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = ExtensionRequest.parseToPojo(reader) + t.equal(pojo.requestName, '1.3.6.1.4.1.4203.1.11.1') + t.strictSame(pojo.requestValue, { + userIdentity: undefined, + oldPassword: undefined, + newPassword: 'secret123' + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-response.js b/node_modules/@ldapjs/messages/lib/messages/extension-response.js new file mode 100644 index 0000000..e13117b --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-response.js @@ -0,0 +1,156 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the extension response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.12. + * + * The type of response is impossible to determine in isolation. + * Most EXTENSION responses do not include the request OID. And they + * all encode their values in unique ways. Therefore, this object's + * {@link parseToPojo} never attempts to parse the response value. + * Instead, if it is present, it reads the value as a buffer and + * encodes it into a hexadecimal string prefixed with a `` + * token. This string is then used by the `#fromExtension` method + * on specific implementations to build a new object. It is left up to + * the implementor to know when certain responses are expected and + * to act accordingly. + */ +class ExtensionResponse extends LdapResult { + #responseName + #responseValue + + /** + * @typedef {LdapResultOptions} ExtensionResponseOptions + * @property {string|undefined} [responseName] The name of the extension, i.e. + * OID for the response. + * @property {string|undefined} [responseValue] The value for the + * response. It may be a buffer string; such a string is a series of + * hexadecimal pairs preceded by the token ``. Buffer strings + * are used by specific response object types to get that type's specific + * encoded value. + */ + + /** + * @param {ExtensionResponseOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_EXTENSION + super(options) + + this.responseName = options.responseName + this.responseValue = options.responseValue + } + + /** + * The OID, if any, of the response. + * + * @returns {string|undefined} + */ + get responseName () { + return this.#responseName + } + + /** + * Define the name (OID) of the response. + * + * @param {string} value + */ + set responseName (value) { + this.#responseName = value + } + + /** + * The response value, if any. For specific extensions that + * are not simple string values, the initial value is a buffer string. + * That is, it is a hexadecimal string of bytes prefixed with ``. + * To parse this value, use a specific extension's `#fromResponse` method. + * + * @returns {string|undefined} + */ + get responseValue () { + return this.#responseValue + } + + /** + * Set the response value. Should be a buffer string if the value is + * an encoded value. + * + * @param {string} value + */ + set responseValue (value) { + this.#responseValue = value + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'ExtensionResponse' + } + + /** + * Internal use only. Used to write the response name and + * response value into the BER object. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _writeResponse (ber) { + if (this.responseName) { + ber.writeString(this.responseName, 0x8a) + } + + if (this.responseValue === undefined) { + return ber + } + + switch (this.responseName) { + default: { + // We assume the value is a plain string since + // we do not recognize the response OID, or we + // know it would be a plain string. + ber.writeString(this.responseValue, 0x8b) + } + } + + return ber + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const pojo = LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_EXTENSION, + berReader: ber + }) + + let responseName + if (ber.peek() === 0x8a) { + responseName = ber.readString(0x8a) + } + + if (ber.peek() !== 0x8b) { + return { ...pojo, responseName } + } + + const valueBuffer = ber.readTag(0x8b) + const responseValue = `${valueBuffer.toString('hex')}` + + return { ...pojo, responseName, responseValue } + } +} + +module.exports = ExtensionResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-response.test.js b/node_modules/@ldapjs/messages/lib/messages/extension-response.test.js new file mode 100644 index 0000000..cb20962 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-response.test.js @@ -0,0 +1,117 @@ +'use strict' + +const tap = require('tap') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const { operations, resultCodes } = require('@ldapjs/protocol') +const { + extensionDisconnectionNotificationResponseBytes +} = require('./_fixtures/message-byte-arrays') +const ExtensionResponse = require('./extension-response') + +tap.test('basic', async t => { + const res = new ExtensionResponse() + t.equal(res.protocolOp, operations.LDAP_RES_EXTENSION) + t.equal(res.type, 'ExtensionResponse') +}) + +tap.test('.responseName', t => { + t.test('gets and sets', async t => { + const res = new ExtensionResponse() + t.equal(res.responseName, undefined) + res.responseName = 'foo' + t.equal(res.responseName, 'foo') + }) + + t.end() +}) + +tap.test('.responseValue', t => { + t.test('gets and sets', async t => { + const res = new ExtensionResponse() + t.equal(res.responseValue, undefined) + res.responseValue = 'foo' + t.equal(res.responseValue, 'foo') + }) + + t.end() +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new ExtensionResponse({ + messageId: 0, + status: resultCodes.UNAVAILABLE, + diagnosticMessage: 'The Directory Server is shutting down', + responseName: '1.3.6.1.4.1.1466.20036' + }) + const ber = res.toBer() + const expected = Buffer.from(extensionDisconnectionNotificationResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('_writeResponse', t => { + t.test('writes a response with a name', async t => { + const req = new ExtensionResponse({ responseName: 'foo' }) + const expected = Buffer.from([0x8a, 0x03, 0x66, 0x6f, 0x6f]) + const writer = new BerWriter() + req._writeResponse(writer) + t.equal(expected.compare(writer.buffer), 0) + }) + + t.test('writes response with value', async t => { + const req = new ExtensionResponse({ responseValue: 'foo' }) + const expected = Buffer.from([0x8b, 0x03, 0x66, 0x6f, 0x6f]) + const writer = new BerWriter() + req._writeResponse(writer) + t.equal(expected.compare(writer.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if protocol op is wrong', async t => { + const bytes = extensionDisconnectionNotificationResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => ExtensionResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.test('parses a basic object', async t => { + const bytes = extensionDisconnectionNotificationResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = ExtensionResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: resultCodes.UNAVAILABLE, + matchedDN: '', + diagnosticMessage: 'The Directory Server is shutting down', + referrals: [], + responseName: '1.3.6.1.4.1.1466.20036' + }) + }) + + t.test('values are buffer strings', async t => { + const { + withGeneratedPasswordBytes + } = require('./extension-responses/_fixtures/password-modify') + const bytes = withGeneratedPasswordBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = ExtensionResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [], + responseName: undefined, + responseValue: '301f801d4164617074657253746576656e736f6e477261696e506c61796d617465' + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-responses/_fixtures/password-modify.js b/node_modules/@ldapjs/messages/lib/messages/extension-responses/_fixtures/password-modify.js new file mode 100644 index 0000000..cb4b7af --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-responses/_fixtures/password-modify.js @@ -0,0 +1,34 @@ +'use strict' + +/** + * Represents an EXTENSION response that is for a password change + * without providing a new one (server generates password). + * Taken from https://web.archive.org/web/20220518193613/https://nawilson.com/ldapv3-wire-protocol-reference-extended/ + */ +module.exports.withGeneratedPasswordBytes = [ + 0x30, 0x2f, // start sequence, 47 bytes + 0x02, 0x01, 0x01, // message ID (integer value 1) + 0x78, 0x2a, // protocol op (0x78), 42 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00, // no diagnostic message (0-byte octet string) + + 0x8b, 0x21, // sequence (response value), 33 bytes + 0x30, 0x1f, // sequence, 31 bytes + + 0x80, 0x1d, // extension specific string, 29 bytes + // "AdapterStevensonGrainPlaymate" + 0x41, 0x64, 0x61, 0x70, 0x74, 0x65, 0x72, 0x53, + 0x74, 0x65, 0x76, 0x65, 0x6e, 0x73, 0x6f, 0x6e, + 0x47, 0x72, 0x61, 0x69, 0x6e, 0x50, 0x6c, 0x61, + 0x79, 0x6d, 0x61, 0x74, 0x65 +] + +module.exports.basicResponse = [ + 0x30, 0x0c, // start sequence, 47 bytes + 0x02, 0x01, 0x01, // message ID (integer value 1) + 0x78, 0x2a, // protocol op (0x78), 42 bytes + 0x0a, 0x01, 0x00, // success result code (enumerated value 0) + 0x04, 0x00, // no matched DN (0-byte octet string) + 0x04, 0x00 // no diagnostic message (0-byte octet string) +] diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-responses/_fixtures/who-am-i.js b/node_modules/@ldapjs/messages/lib/messages/extension-responses/_fixtures/who-am-i.js new file mode 100644 index 0000000..64f88f2 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-responses/_fixtures/who-am-i.js @@ -0,0 +1,24 @@ +'use strict' + +module.exports.withId = [ + 0x30, 0x21, // sequence, 33 bytes + 0x02, 0x01, 0x02, // message id (integer 2) + 0x78, 0x1c, // protocol op (0x78), 28 bytes + 0x0a, 0x01, 0x00, // status code, 0 + 0x04, 0x00, // no matched dn + 0x04, 0x00, // no diagnostic message + 0x8b, 0x13, // string response value + // "u:xxyyz@EXAMPLE.NET" + 0x75, 0x3a, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x40, + 0x45, 0x58, 0x41, 0x4d, 0x50, 0x4c, 0x45, 0x2e, + 0x4e, 0x45, 0x54 +] + +module.exports.withoutId = [ + 0x30, 0x0c, // sequence, 12 bytes + 0x02, 0x01, 0x02, // message id (integer 2) + 0x78, 0x07, // protocol op (0x78), 7 bytes + 0x0a, 0x01, 0x00, // status code, 0 + 0x04, 0x00, // no matched dn + 0x04, 0x00 // no diagnostic message +] diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-responses/password-modify.js b/node_modules/@ldapjs/messages/lib/messages/extension-responses/password-modify.js new file mode 100644 index 0000000..76a9d43 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-responses/password-modify.js @@ -0,0 +1,33 @@ +'use strict' + +const { BerReader } = require('@ldapjs/asn1') +const ExtensionResponse = require('../extension-response') + +/** + * Implements the password modify extension defined by + * https://www.rfc-editor.org/rfc/rfc3062. + */ +class PasswordModifyResponse extends ExtensionResponse { + /** + * Given a basic {@link ExtensionResponse} with a buffer string in + * `responseValue`, parse into a specific {@link PasswordModifyResponse} + * instance. + * + * @param {ExtensionResponse} response + * + * @returns {PasswordModifyResponse} + */ + static fromResponse (response) { + if (response.responseValue === undefined) { + return new PasswordModifyResponse() + } + + const valueBuffer = Buffer.from(response.responseValue.substring(8), 'hex') + const reader = new BerReader(valueBuffer) + reader.readSequence() + const responseValue = reader.readString(0x80) + return new PasswordModifyResponse({ responseValue }) + } +} + +module.exports = PasswordModifyResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-responses/password-modify.test.js b/node_modules/@ldapjs/messages/lib/messages/extension-responses/password-modify.test.js new file mode 100644 index 0000000..3906751 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-responses/password-modify.test.js @@ -0,0 +1,28 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const LdapMessage = require('../../ldap-message') +const { + basicResponse, + withGeneratedPasswordBytes +} = require('./_fixtures/password-modify') +const PasswordModifyResponse = require('./password-modify') + +tap.test('parses a response with a generated password', async t => { + const reader = new BerReader(Buffer.from(withGeneratedPasswordBytes)) + let res = LdapMessage.parse(reader) + res = PasswordModifyResponse.fromResponse(res) + t.type(res, PasswordModifyResponse) + t.equal(res.responseName, undefined) + t.equal(res.responseValue, 'AdapterStevensonGrainPlaymate') +}) + +tap.test('parses a response with an empty value', async t => { + const reader = new BerReader(Buffer.from(basicResponse)) + let res = LdapMessage.parse(reader) + res = PasswordModifyResponse.fromResponse(res) + t.type(res, PasswordModifyResponse) + t.equal(res.responseName, undefined) + t.equal(res.responseValue, undefined) +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-responses/who-am-i.js b/node_modules/@ldapjs/messages/lib/messages/extension-responses/who-am-i.js new file mode 100644 index 0000000..f2d29be --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-responses/who-am-i.js @@ -0,0 +1,30 @@ +'use strict' + +const ExtensionResponse = require('../extension-response') + +/** + * Implements the "Who Am I" extension defined by + * https://www.rfc-editor.org/rfc/rfc4532. + */ +class WhoAmIResponse extends ExtensionResponse { + /** + * Given a basic {@link ExtensionResponse} with a buffer string in + * `responseValue`, parse into a specific {@link WhoAmIResponse} + * instance. + * + * @param {ExtensionResponse} response + * + * @returns {WhoAmIResponse} + */ + static fromResponse (response) { + if (response.responseValue === undefined) { + return new WhoAmIResponse() + } + + const valueBuffer = Buffer.from(response.responseValue.substring(8), 'hex') + const responseValue = valueBuffer.toString('utf8') + return new WhoAmIResponse({ responseValue }) + } +} + +module.exports = WhoAmIResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-responses/who-am-i.test.js b/node_modules/@ldapjs/messages/lib/messages/extension-responses/who-am-i.test.js new file mode 100644 index 0000000..0b5bc2f --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-responses/who-am-i.test.js @@ -0,0 +1,25 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const LdapMessage = require('../../ldap-message') +const { withId, withoutId } = require('./_fixtures/who-am-i') +const WhoAmIResponse = require('./who-am-i') + +tap.test('parses a response with a returned id', async t => { + const reader = new BerReader(Buffer.from(withId)) + let res = LdapMessage.parse(reader) + res = WhoAmIResponse.fromResponse(res) + t.type(res, WhoAmIResponse) + t.equal(res.responseName, undefined) + t.equal(res.responseValue, 'u:xxyyz@EXAMPLE.NET') +}) + +tap.test('parses a response with a returned id', async t => { + const reader = new BerReader(Buffer.from(withoutId)) + let res = LdapMessage.parse(reader) + res = WhoAmIResponse.fromResponse(res) + t.type(res, WhoAmIResponse) + t.equal(res.responseName, undefined) + t.equal(res.responseValue, undefined) +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-utils/recognized-oids.js b/node_modules/@ldapjs/messages/lib/messages/extension-utils/recognized-oids.js new file mode 100644 index 0000000..c4136af --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-utils/recognized-oids.js @@ -0,0 +1,29 @@ +'use strict' + +const OIDS = new Map([ + ['CANCEL_REQUEST', '1.3.6.1.1.8'], // RFC 3909 + ['DISCONNECTION_NOTIFICATION', '1.3.6.1.4.1.1466.20036'], // RFC 4511 + ['PASSWORD_MODIFY', '1.3.6.1.4.1.4203.1.11.1'], // RFC 3062 + ['START_TLS', '1.3.6.1.4.1.1466.20037'], // RFC 4511 + ['WHO_AM_I', '1.3.6.1.4.1.4203.1.11.3'] // RFC 4532 +]) + +Object.defineProperty(OIDS, 'lookupName', { + value: function (oid) { + for (const [key, value] of this.entries()) { + /* istanbul ignore else */ + if (value === oid) return key + } + } +}) + +Object.defineProperty(OIDS, 'lookupOID', { + value: function (name) { + for (const [key, value] of this.entries()) { + /* istanbul ignore else */ + if (key === name) return value + } + } +}) + +module.exports = OIDS diff --git a/node_modules/@ldapjs/messages/lib/messages/extension-utils/recognized-oids.test.js b/node_modules/@ldapjs/messages/lib/messages/extension-utils/recognized-oids.test.js new file mode 100644 index 0000000..4a2797d --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/extension-utils/recognized-oids.test.js @@ -0,0 +1,14 @@ +'use strict' + +const tap = require('tap') +const RECOGNIZED_OIDS = require('./recognized-oids') + +tap.test('lookupName returns correct name', async t => { + const name = RECOGNIZED_OIDS.lookupName('1.3.6.1.4.1.4203.1.11.1') + t.equal(name, 'PASSWORD_MODIFY') +}) + +tap.test('lookupOID returns correct OID', async t => { + const name = RECOGNIZED_OIDS.lookupOID('PASSWORD_MODIFY') + t.equal(name, '1.3.6.1.4.1.4203.1.11.1') +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/intermediate-response.js b/node_modules/@ldapjs/messages/lib/messages/intermediate-response.js new file mode 100644 index 0000000..ab737d6 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/intermediate-response.js @@ -0,0 +1,189 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const { operations } = require('@ldapjs/protocol') + +const partIsNotNumeric = part => /^\d+$/.test(part) === false + +/** + * Determines if a passed in string is a dotted decimal string. + * + * Copied from `@ldapjs/dn`. + * + * @param {string} value + * + * @returns {boolean} + */ +function isDottedDecimal (value) { + if (typeof value !== 'string') return false + + const parts = value.split('.') + const nonNumericParts = parts.filter(partIsNotNumeric) + + return nonNumericParts.length === 0 +} + +/** + * Implements the intermediate response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.13. + * + * TODO: actual implementations of this, e.g. RFC 4533 §2.5, seem to encode + * sequences in the responseValue. That means this needs a more robust + * implementation like is found in the ExtensionResponse implementation (i.e. + * detection of recognized OIDs and specific sub-implementations). As of now, + * this implementation follows the baseline spec without any sub-implementations. + */ +class IntermediateResponse extends LdapMessage { + #responseName + #responseValue + + /** + * @typedef {LdapMessageOptions} IntermediateResponseOptions + * @property {string} responseName + * @property {string} responseValue + */ + + /** + * @param {IntermediateResponseOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_INTERMEDIATE + super(options) + + this.responseName = options.responseName ?? null + this.responseValue = options.responseValue ?? null + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'IntermediateResponse' + } + + /** + * The numeric OID that identifies the type of intermediate response. + * + * @returns {string | undefined} + */ + get responseName () { + return this.#responseName + } + + /** + * Define the numeric OID that identifies the type of intermediate response. + * + * @param {string | null} value + * + * @throws For an invalid value. + */ + set responseName (value) { + if (value === null) return + if (isDottedDecimal(value) === false) { + throw Error('responseName must be a numeric OID') + } + this.#responseName = value + } + + /** + * The value for the intermidate response if any. + * + * @returns {string | undefined} + */ + get responseValue () { + return this.#responseValue + } + + /** + * Define the value for the intermediate response. + * + * @param {string | null} value + * + * @throws For an invalid value. + */ + set responseValue (value) { + if (value === null) return + if (typeof value !== 'string') { + throw Error('responseValue must be a string') + } + this.#responseValue = value + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_RES_INTERMEDIATE) + + if (this.#responseName) { + ber.writeString(this.#responseName, 0x80) + } + if (this.#responseValue) { + ber.writeString(this.#responseValue, 0x81) + } + + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.responseName = this.#responseName + obj.responseValue = this.#responseValue + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_RES_INTERMEDIATE) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + let responseName + let responseValue + + let tag = ber.peek() + switch (tag) { + case 0x80: { + responseName = ber.readString(tag) + + tag = ber.peek() + /* istanbul ignore else */ + if (tag === 0x81) { + responseValue = ber.readString(tag) + } + break + } + + case 0x81: { + responseValue = ber.readString(tag) + } + } + + return { protocolOp, responseName, responseValue } + } +} + +module.exports = IntermediateResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/intermediate-response.test.js b/node_modules/@ldapjs/messages/lib/messages/intermediate-response.test.js new file mode 100644 index 0000000..29679ba --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/intermediate-response.test.js @@ -0,0 +1,191 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const { BerWriter, BerReader } = require('@ldapjs/asn1') +const IntermediateResponse = require('./intermediate-response') + +const { + intermediateResponseBytes, + intermediateResponseNoValueBytes, + intermediateResponseNoNameBytes +} = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const res = new IntermediateResponse() + t.strictSame(res.pojo, { + messageId: 1, + protocolOp: operations.LDAP_RES_INTERMEDIATE, + type: 'IntermediateResponse', + responseName: undefined, + responseValue: undefined, + controls: [] + }) + + t.equal(res.type, 'IntermediateResponse') + }) + + t.test('constructor with args', async t => { + const res = new IntermediateResponse({ + responseName: '1.2.3', + responseValue: 'foo' + }) + t.strictSame(res.pojo, { + messageId: 1, + protocolOp: operations.LDAP_RES_INTERMEDIATE, + type: 'IntermediateResponse', + responseName: '1.2.3', + responseValue: 'foo', + controls: [] + }) + }) + + t.end() +}) + +tap.test('.responseName', t => { + t.test('sets/gets', async t => { + const res = new IntermediateResponse() + t.equal(res.responseName, undefined) + + res.responseName = '1.2.3' + t.equal(res.responseName, '1.2.3') + }) + + t.test('rejects bad value', async t => { + const res = new IntermediateResponse() + t.throws( + () => { + res.responseName = 'foo bar' + }, + 'responseName must be a numeric OID' + ) + t.throws( + () => { + res.responseName = 1.2 + }, + 'responseName must be a numeric OID' + ) + }) + + t.end() +}) + +tap.test('.responseValue', t => { + t.test('sets/gets', async t => { + const res = new IntermediateResponse() + t.equal(res.responseValue, undefined) + + res.responseValue = '1.2.3' + t.equal(res.responseValue, '1.2.3') + }) + + t.test('rejects bad value', async t => { + const res = new IntermediateResponse() + t.throws( + () => { + res.responseValue = { foo: 'foo' } + }, + 'responseValue must be a string' + ) + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('converts instance to BER', async t => { + let res = new IntermediateResponse({ + messageId: 2, + responseName: '1.2.3', + responseValue: 'foo' + }) + let writer = new BerWriter() + res._toBer(writer) + + t.equal( + Buffer.from(intermediateResponseBytes.slice(5)).compare(writer.buffer), + 0 + ) + + res = new IntermediateResponse({ + messageId: 2, + responseName: '1.2.3' + }) + writer = new BerWriter() + res._toBer(writer) + + t.equal( + Buffer.from(intermediateResponseNoValueBytes.slice(5)).compare(writer.buffer), + 0 + ) + + res = new IntermediateResponse({ + messageId: 2, + responseValue: 'foo' + }) + writer = new BerWriter() + res._toBer(writer) + + t.equal( + Buffer.from(intermediateResponseNoNameBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new IntermediateResponse({ + responseName: '1.2.3', + responseValue: 'foo' + }) + t.strictSame(req._pojo(), { + responseName: '1.2.3', + responseValue: 'foo' + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(intermediateResponseBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => IntermediateResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + let reqBuffer = Buffer.from(intermediateResponseBytes) + let reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + let pojo = IntermediateResponse.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_RES_INTERMEDIATE) + t.equal(pojo.responseName, '1.2.3') + t.equal(pojo.responseValue, 'foo') + + reqBuffer = Buffer.from(intermediateResponseNoNameBytes) + reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + pojo = IntermediateResponse.parseToPojo(reader) + t.equal(pojo.responseName, undefined) + t.equal(pojo.responseValue, 'foo') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/modify-request.js b/node_modules/@ldapjs/messages/lib/messages/modify-request.js new file mode 100644 index 0000000..4989a63 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modify-request.js @@ -0,0 +1,172 @@ +'use strict' + +const { operations } = require('@ldapjs/protocol') +const Change = require('@ldapjs/change') +const LdapMessage = require('../ldap-message') + +/** + * Implements the MODIFY request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.6. + * + * Changes should be in the order of operation as described in + * the spec. If sorting is desired, sort the array prior to + * adding it to the request. + * + * @example Sorting Changes + * const {ModifyRequest} = require('@ldapjs/messages') + * const Change = require('@ldapjs/change') + * const changes = someArrayOfChanges.sort(Change.sort) + * const req = new ModifyRequest({ + * object: 'dn=foo,dc=example,dc=com', + * changes + * }) + */ +class ModifyRequest extends LdapMessage { + #object + #changes + + /** + * @typedef {LdapMessageOptions} ModifyRequestOptions + * @property {string|null} [object] The LDAP object (DN) to modify. + * @property {import('@ldapjs/change')[]} [changes] The set of changes to + * apply. + */ + + /** + * @param {ModifyRequestOptions} [options] + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_REQ_MODIFY + super(options) + + this.#object = options.object || null + this.changes = options.changes || [] + } + + /** + * A copy of the set of changes to be applied to the LDAP object. + * + * @returns {import('@ldapjs/change')[]} + */ + get changes () { + return this.#changes.slice(0) + } + + /** + * Define the set of changes to apply to the LDAP object. + * + * @param {import('@ldapjs/change')[]} values + * + * @throws When `values` is not an array or contains any elements that + * are not changes. + */ + set changes (values) { + this.#changes = [] + if (Array.isArray(values) === false) { + throw Error('changes must be an array') + } + for (let change of values) { + if (Change.isChange(change) === false) { + throw Error('change must be an instance of Change or a Change-like object') + } + if (Object.prototype.toString.call(change) !== '[object LdapChange]') { + change = new Change(change) + } + this.#changes.push(change) + } + } + + /** + * The object (DN) to be modified. + * + * @returns {string} + */ + get object () { + return this.#object + } + + /** + * Define the object (DN) to be modified. + * + * @param {string} value + */ + set object (value) { + this.#object = value + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'ModifyRequest' + } + + get _dn () { + return this.#object + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_REQ_MODIFY) + + ber.writeString(this.#object.toString()) + ber.startSequence() + for (const change of this.#changes) { + ber.appendBuffer(change.toBer().buffer) + } + ber.endSequence() + + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.object = this.#object + obj.changes = this.#changes.map(c => c.pojo) + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_REQ_MODIFY) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const object = ber.readString() + const changes = [] + + ber.readSequence() + const end = ber.offset + ber.length + while (ber.offset < end) { + const change = Change.fromBer(ber) + changes.push(change.pojo) + } + + return { protocolOp, object, changes } + } +} + +module.exports = ModifyRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/modify-request.test.js b/node_modules/@ldapjs/messages/lib/messages/modify-request.test.js new file mode 100644 index 0000000..63026d6 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modify-request.test.js @@ -0,0 +1,207 @@ +'use strict' + +const tap = require('tap') +const { + modifyRequestBytes +} = require('./_fixtures/message-byte-arrays') +const { operations } = require('@ldapjs/protocol') +const { BerReader } = require('@ldapjs/asn1') +const Attribute = require('@ldapjs/attribute') +const Change = require('@ldapjs/change') +const ModifyRequest = require('./modify-request') + +tap.test('constructor', t => { + t.test('with empty params', async t => { + const req = new ModifyRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_MODIFY, + type: 'ModifyRequest', + object: null, + changes: [], + controls: [] + }) + }) + + t.test('with invalid changes options', async t => { + t.throws( + () => new ModifyRequest({ changes: 'foo' }), + Error('changes must be an array') + ) + }) + + t.end() +}) + +tap.test('.changes', t => { + t.test('gets a copy of the set of changes', async t => { + const changes = [new Change({ + modification: new Attribute() + })] + const req = new ModifyRequest({ changes }) + const found = req.changes + t.not(changes, found) + t.equal(changes.length, 1) + t.equal(Change.isChange(changes[0]), true) + }) + + t.test('set throws for non-array', async t => { + const req = new ModifyRequest() + t.throws( + () => { + req.changes = 42 + }, + Error('changes must be an array') + ) + }) + + t.test('throws for non-change in array', async t => { + const req = new ModifyRequest() + t.throws( + () => { + req.changes = [42] + }, + Error('change must be an instance of Change or a Change-like object') + ) + }) + + t.test('converts change-likes to changes', async t => { + const req = new ModifyRequest() + req.changes = [{ + operation: 'add', + modification: { + type: 'cn', + values: ['foo'] + } + }] + t.equal(req.changes.length, 1) + t.equal(Object.prototype.toString.call(req.changes[0]), '[object LdapChange]') + }) + + t.end() +}) + +tap.test('.object', t => { + t.test('gets and sets', async t => { + const req = new ModifyRequest() + t.equal(req.object, null) + req.object = 'foo' + t.equal(req.object, 'foo') + t.equal(req.dn, 'foo') + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('serializes to ber', async t => { + const req = new ModifyRequest({ + messageId: 2, + object: 'uid=jdoe,ou=People,dc=example,dc=com', + changes: [ + new Change({ + operation: 'delete', + modification: new Attribute({ + type: 'givenName', + values: ['John'] + }) + }), + new Change({ + operation: 'add', + modification: new Attribute({ + type: 'givenName', + values: ['Jonathan'] + }) + }), + new Change({ + operation: 'replace', + modification: new Attribute({ + type: 'cn', + values: ['Jonathan Doe'] + }) + }) + ] + }) + const expected = Buffer.from(modifyRequestBytes) + const ber = req.toBer() + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('serializes to plain object', async t => { + const req = new ModifyRequest({ + object: 'foo', + changes: [ + new Change({ + modification: new Attribute({ + type: 'cn', + values: ['bar'] + }) + }) + ] + }) + t.strictSame(req._pojo(), { + object: 'foo', + changes: [{ + operation: 'add', + modification: { + type: 'cn', + values: ['bar'] + } + }] + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws for wrong op', async t => { + const bytes = Buffer.from(modifyRequestBytes.slice(6)) + bytes[0] = 0x61 + const reader = new BerReader(bytes) + t.throws( + () => ModifyRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('parses bytes to an object', async t => { + const bytes = Buffer.from(modifyRequestBytes.slice(6)) + const reader = new BerReader(bytes) + const pojo = ModifyRequest.parseToPojo(reader) + t.type(pojo, 'Object') + t.strictSame(pojo, { + protocolOp: operations.LDAP_REQ_MODIFY, + object: 'uid=jdoe,ou=People,dc=example,dc=com', + changes: [ + { + operation: 'delete', + modification: { + type: 'givenName', + values: ['John'] + } + }, + { + operation: 'add', + modification: { + type: 'givenName', + values: ['Jonathan'] + } + }, + { + operation: 'replace', + modification: { + type: 'cn', + values: ['Jonathan Doe'] + } + } + ] + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/modify-response.js b/node_modules/@ldapjs/messages/lib/messages/modify-response.js new file mode 100644 index 0000000..3fd7adb --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modify-response.js @@ -0,0 +1,45 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the MODIFY response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.6. + */ +class ModifyResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_MODIFY + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'ModifyResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_MODIFY, + berReader: ber + }) + } +} + +module.exports = ModifyResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/modify-response.test.js b/node_modules/@ldapjs/messages/lib/messages/modify-response.test.js new file mode 100644 index 0000000..7118c17 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modify-response.test.js @@ -0,0 +1,55 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations, resultCodes } = require('@ldapjs/protocol') +const { + modifyResponseBytes +} = require('./_fixtures/message-byte-arrays') +const ModifyResponse = require('./modify-response') + +tap.test('basic', async t => { + const res = new ModifyResponse() + t.equal(res.protocolOp, operations.LDAP_RES_MODIFY) + t.equal(res.type, 'ModifyResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new ModifyResponse({ + messageId: 2, + status: resultCodes.SUCCESS + }) + const ber = res.toBer() + const expected = Buffer.from(modifyResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = modifyResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = ModifyResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: resultCodes.SUCCESS, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = modifyResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => ModifyResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/modifydn-request.js b/node_modules/@ldapjs/messages/lib/messages/modifydn-request.js new file mode 100644 index 0000000..23964f6 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modifydn-request.js @@ -0,0 +1,222 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const { operations } = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') + +/** + * Implements the modifydn request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.9. + */ +class ModifyDnRequest extends LdapMessage { + #entry + #newRdn + #deleteOldRdn + #newSuperior + + /** + * @typedef {LdapMessageOptions} ModifyDnRequestOptions + * @property {string|null} [entry=null] The path to the LDAP object. + * @property {string|null} [newRdn=null] Path to the new object for the + * entry. + * @property {boolean} [deleteOldRdn=false] Indicates if attributes + * should be removed in the new RDN that were in the old RDN but not the + * new one. + * @property {string} [newSuperior] Path for the new parent for + * the RDN. + */ + + /** + * @param {ModifyDnRequestOptions} [options] + * + * @throws When an option is invalid (e.g. `deleteOldRdn` is not a boolean + * value). + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_REQ_MODRDN + super(options) + + this.entry = options.entry || '' + this.newRdn = options.newRdn || '' + this.deleteOldRdn = options.deleteOldRdn ?? false + this.newSuperior = options.newSuperior + } + + /** + * The directory path to the object to modify. + * + * @type {import('@ldapjs/dn').DN} + */ + get entry () { + return this.#entry + } + + /** + * Define the entry path to the LDAP object. + * + * @param {string | import('@ldapjs/dn').dn} value + */ + set entry (value) { + if (typeof value === 'string') { + this.#entry = DN.fromString(value) + } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { + this.#entry = value + } else { + throw Error('entry must be a valid DN string or instance of LdapDn') + } + } + + /** + * Alias of {@link entry}. + * + * @type {import('@ldapjs/dn').DN} + */ + get _dn () { + return this.#entry + } + + /** + * The new directory path for the object. + * + * @returns {import('@ldapjs/dn').DN} + */ + get newRdn () { + return this.#newRdn + } + + /** + * Define the new entry path to the LDAP object. + * + * @param {string | import('@ldapjs/dn').DN} value + */ + set newRdn (value) { + if (typeof value === 'string') { + this.#newRdn = DN.fromString(value) + } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { + this.#newRdn = value + } else { + throw Error('newRdn must be a valid DN string or instance of LdapDn') + } + } + + /** + * Indicates if the old RDN should be removed or not. + * + * @returns {boolean} + */ + get deleteOldRdn () { + return this.#deleteOldRdn + } + + set deleteOldRdn (value) { + if (typeof value !== 'boolean') { + throw Error('deleteOldRdn must be a boolean value') + } + this.#deleteOldRdn = value + } + + /** + * The new superior for the entry, if any is defined. + * + * @returns {undefined | import('@ldapjs/dn').DN} + */ + get newSuperior () { + return this.#newSuperior + } + + /** + * Define the new superior path. + * + * @param {undefined | string | import('@ldapjs/dn').DN} value + */ + set newSuperior (value) { + if (value) { + if (typeof value === 'string') { + this.#newSuperior = DN.fromString(value) + } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { + this.#newSuperior = value + } else { + throw Error('newSuperior must be a valid DN string or instance of LdapDn') + } + } else { + this.#newSuperior = undefined + } + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'ModifyDnRequest' + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_REQ_MODRDN) + + ber.writeString(this.#entry.toString()) + ber.writeString(this.#newRdn.toString()) + ber.writeBoolean(this.#deleteOldRdn) + /* istanbul ignore else */ + if (this.#newSuperior !== undefined) { + ber.writeString(this.#newSuperior.toString(), 0x80) + } + + ber.endSequence() + + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.entry = this.#entry.toString() + obj.newRdn = this.#newRdn.toString() + obj.deleteOldRdn = this.#deleteOldRdn + obj.newSuperior = this.#newSuperior ? this.#newSuperior.toString() : undefined + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_REQ_MODRDN) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const entry = ber.readString() + const newRdn = ber.readString() + const deleteOldRdn = ber.readBoolean() + let newSuperior + /* istanbul ignore else */ + if (ber.peek() === 0x80) { + newSuperior = ber.readString(0x80) + } + + return { protocolOp, entry, newRdn, deleteOldRdn, newSuperior } + } +} + +module.exports = ModifyDnRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/modifydn-request.test.js b/node_modules/@ldapjs/messages/lib/messages/modifydn-request.test.js new file mode 100644 index 0000000..4ae85d3 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modifydn-request.test.js @@ -0,0 +1,233 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const { DN } = require('@ldapjs/dn') +const ModifyDnRequest = require('./modifydn-request') + +const { + modifyDnRequestBytes +} = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new ModifyDnRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_MODRDN, + type: 'ModifyDnRequest', + entry: '', + newRdn: '', + deleteOldRdn: false, + newSuperior: undefined, + controls: [] + }) + }) + + t.test('constructor with args', async t => { + const req = new ModifyDnRequest({ + entry: 'dc=to-move,dc=example,dc=com', + newRdn: 'dc=moved,dc=example,dc=com', + deleteOldRdn: true, + newSuperior: 'dc=example,dc=net' + }) + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_MODRDN, + type: 'ModifyDnRequest', + entry: 'dc=to-move,dc=example,dc=com', + newRdn: 'dc=moved,dc=example,dc=com', + deleteOldRdn: true, + newSuperior: 'dc=example,dc=net', + controls: [] + }) + }) + + t.test('.type', async t => { + const req = new ModifyDnRequest() + t.equal(req.type, 'ModifyDnRequest') + }) + + t.end() +}) + +tap.test('.entry', t => { + t.test('sets and gets', async t => { + const req = new ModifyDnRequest() + + req.entry = 'foo=bar' + t.equal(Object.prototype.toString.call(req.entry), '[object LdapDn]') + t.equal(req.entry.toString(), 'foo=bar') + t.equal(req._dn.toString(), 'foo=bar') + + req.entry = DN.fromString('cn=foo') + t.equal(req.entry.toString(), 'cn=foo') + }) + + t.test('throws for bad value', async t => { + const req = new ModifyDnRequest() + t.throws( + () => { + req.entry = { cn: 'foo' } + }, + 'entry must be a valid DN string or instance of LdapDN' + ) + }) + + t.end() +}) + +tap.test('.newRdn', t => { + t.test('sets and gets', async t => { + const req = new ModifyDnRequest() + + req.newRdn = 'foo=bar' + t.equal(Object.prototype.toString.call(req.newRdn), '[object LdapDn]') + t.equal(req.newRdn.toString(), 'foo=bar') + + req.newRdn = DN.fromString('cn=foo') + t.equal(req.newRdn.toString(), 'cn=foo') + }) + + t.test('throws for bad value', async t => { + const req = new ModifyDnRequest() + t.throws( + () => { + req.newRdn = { cn: 'foo' } + }, + 'newRdn must be a valid DN string or instance of LdapDN' + ) + }) + + t.end() +}) + +tap.test('.deleteOldRdn', t => { + t.test('throws for wrong type', async t => { + t.throws( + () => new ModifyDnRequest({ deleteOldRdn: 'false' }), + 'deleteOldRdn must be a boolean value' + ) + }) + + t.test('sets and gets', async t => { + const req = new ModifyDnRequest() + t.equal(req.deleteOldRdn, false) + + req.deleteOldRdn = true + t.type(req.deleteOldRdn, 'boolean') + t.equal(req.deleteOldRdn, true) + }) + + t.end() +}) + +tap.test('.newSuperior', t => { + t.test('sets and gets', async t => { + const req = new ModifyDnRequest() + + req.newSuperior = 'foo=bar' + t.equal(Object.prototype.toString.call(req.newSuperior), '[object LdapDn]') + t.equal(req.newSuperior.toString(), 'foo=bar') + + req.newSuperior = null + t.equal(req.newSuperior, undefined) + + req.newSuperior = DN.fromString('cn=foo') + t.equal(req.newSuperior.toString(), 'cn=foo') + }) + + t.test('throws for bad value', async t => { + const req = new ModifyDnRequest() + t.throws( + () => { + req.newSuperior = { cn: 'foo' } + }, + 'newSuperior must be a valid DN string or instance of LdapDN' + ) + }) + + t.end() +}) + +tap.test('_toBer', async t => { + t.test('converts instance to BER', async t => { + const req = new ModifyDnRequest({ + entry: 'uid=jdoe,ou=People,dc=example,dc=com', + newRdn: 'uid=john.doe', + deleteOldRdn: true, + newSuperior: 'ou=Users,dc=example,dc=com' + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(modifyDnRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + let req = new ModifyDnRequest({ + entry: 'cn=bar,dc=example,dc=com', + newRdn: 'cn=foo' + }) + t.strictSame(req._pojo(), { + entry: 'cn=bar,dc=example,dc=com', + newRdn: 'cn=foo', + deleteOldRdn: false, + newSuperior: undefined + }) + + req = new ModifyDnRequest({ + entry: 'cn=bar,dc=example,dc=com', + newRdn: 'cn=foo', + newSuperior: 'ou=people,dc=example,dc=com' + }) + t.strictSame(req._pojo(), { + entry: 'cn=bar,dc=example,dc=com', + newRdn: 'cn=foo', + deleteOldRdn: false, + newSuperior: 'ou=people,dc=example,dc=com' + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(modifyDnRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => ModifyDnRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(modifyDnRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = ModifyDnRequest.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_REQ_MODRDN) + t.equal(pojo.entry, 'uid=jdoe,ou=People,dc=example,dc=com') + t.equal(pojo.newRdn, 'uid=john.doe') + t.equal(pojo.deleteOldRdn, true) + t.equal(pojo.newSuperior, 'ou=Users,dc=example,dc=com') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/modifydn-response.js b/node_modules/@ldapjs/messages/lib/messages/modifydn-response.js new file mode 100644 index 0000000..e58090a --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modifydn-response.js @@ -0,0 +1,45 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the modifydn response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.9. + */ +class ModifyDnResponse extends LdapResult { + /** + * @param {LdapResultOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_MODRDN + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'ModifyDnResponse' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_MODRDN, + berReader: ber + }) + } +} + +module.exports = ModifyDnResponse diff --git a/node_modules/@ldapjs/messages/lib/messages/modifydn-response.test.js b/node_modules/@ldapjs/messages/lib/messages/modifydn-response.test.js new file mode 100644 index 0000000..548a1be --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/modifydn-response.test.js @@ -0,0 +1,56 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations } = require('@ldapjs/protocol') +const { + modifyDnResponseBytes +} = require('./_fixtures/message-byte-arrays') +const ModifyDnResponse = require('./modifydn-response') + +tap.test('basic', async t => { + const res = new ModifyDnResponse() + t.equal(res.protocolOp, operations.LDAP_RES_MODRDN) + t.equal(res.type, 'ModifyDnResponse') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new ModifyDnResponse({ messageId: 2 }) + const ber = res.toBer() + const expected = Buffer.from(modifyDnResponseBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.comment('see the LdapResult test suite for further tests') + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = modifyDnResponseBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = ModifyDnResponse.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = modifyDnResponseBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => ModifyDnResponse.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.comment('see the LdapResult test suite for further tests') + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/search-request.js b/node_modules/@ldapjs/messages/lib/messages/search-request.js new file mode 100644 index 0000000..151a5be --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-request.js @@ -0,0 +1,515 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const { operations, search } = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') +const filter = require('@ldapjs/filter') +const { BerReader, BerTypes } = require('@ldapjs/asn1') +const warning = require('../deprecations') + +const recognizedScopes = new Map([ + ['base', [search.SCOPE_BASE_OBJECT, 'base']], + ['single', [search.SCOPE_ONE_LEVEL, 'single', 'one']], + ['subtree', [search.SCOPE_SUBTREE, 'subtree', 'sub']] +]) +const scopeAliasToScope = alias => { + alias = typeof alias === 'string' ? alias.toLowerCase() : alias + if (recognizedScopes.has(alias)) { + return recognizedScopes.get(alias)[0] + } + for (const value of recognizedScopes.values()) { + if (value.includes(alias)) { + return value[0] + } + } + return undefined +} + +const isValidAttributeString = str => { + // special filter strings + if (['*', '1.1', '+'].includes(str) === true) { + return true + } + // "@" + if (/^@[a-zA-Z][\w\d.-]*$/.test(str) === true) { + return true + } + // ascii attribute names per RFC 4512 §2.5 + if (/^[a-zA-Z][\w\d.;-]*$/.test(str) === true) { + return true + } + // Matches the non-standard `range=-` ActiveDirectory + // extension as described in §3.1.1.3.1.3.3 (revision 57.0) of + // https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/d2435927-0999-4c62-8c6d-13ba31a52e1a. + if (/^[a-zA-Z][\w\d.-]*(;[\w\d.-]+)*;range=\d+-(\d+|\*)(;[\w\d.-]+)*$/.test(str) === true) { + return true + } + return false +} + +/** + * Implements the add request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.5.1. + * + * Various constants for searching and options can be used from the `search` + * object in the `@ldapjs/protocol` package. The same constants are exported + * here as static properties for convenience. + */ +class SearchRequest extends LdapMessage { + /** + * Limit searches to the specified {@link baseObject}. + * + * @type {number} + */ + static SCOPE_BASE = search.SCOPE_BASE_OBJECT + + /** + * Limit searches to the immediate children of the specified + * {@link baseObject}. + * + * @type {number} + */ + static SCOPE_SINGLE = search.SCOPE_ONE_LEVEL + + /** + * Limit searches to the {@link baseObject} and all descendents of that + * object. + * + * @type {number} + */ + static SCOPE_SUBTREE = search.SCOPE_SUBTREE + + /** + * Do not perform any dereferencing of aliases at all. + * + * @type {number} + */ + static DEREF_ALIASES_NEVER = search.NEVER_DEREF_ALIASES + + /** + * Dereference aliases in subordinate searches of the {@link baseObject}. + * + * @type {number} + */ + static DEREF_IN_SEARCHING = search.DEREF_IN_SEARCHING + + /** + * Dereference aliases when finding the base object only. + * + * @type {number} + */ + static DEREF_BASE_OBJECT = search.DEREF_BASE_OBJECT + + /** + * Dereference aliases when finding the base object and when searching + * subordinates. + * + * @type {number} + */ + static DEREF_ALWAYS = search.DEREF_ALWAYS + + #baseObject + #scope + #derefAliases + #sizeLimit + #timeLimit + #typesOnly + #filter + #attributes = [] + + /** + * @typedef {LdapMessageOptions} SearchRequestOptions + * @property {string | import('@ldapjs/dn').DN} baseObject The path to the + * LDAP object that will serve as the basis of the search. + * @property {number | string} scope The type of search to be performed. + * May be one of {@link SCOPE_BASE}, {@link SCOPE_SINGLE}, + * {@link SCOPE_SUBTREE}, `'base'`, `'single'` (`'one'`), or `'subtree'` + * (`'sub'`). + * @property {number} derefAliases Indicates if aliases should be dereferenced + * during searches. May be one of {@link DEREF_ALIASES_NEVER}, + * {@link DEREF_BASE_OBJECT}, {@link DEREF_IN_SEARCHING}, or + * {@link DEREF_ALWAYS}. + * @property {number} sizeLimit The number of search results the server should + * limit the result set to. `0` indicates no desired limit. + * @property {number} timeLimit The number of seconds the server should work + * before aborting the search request. `0` indicates no desired limit. + * @property {boolean} typesOnly Indicates if only attribute names should + * be returned (`true`), or both names and values should be returned (`false`). + * @property {string | import('@ldapjs/filter').FilterString} filter The + * filter to apply when searching. + * @property {string[]} attributes A set of attribute filtering strings + * to apply. See the docs for the {@link attributes} setter. + */ + + /** + * @param {SearchRequestOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_REQ_SEARCH + super(options) + + this.baseObject = options.baseObject ?? '' + this.scope = options.scope ?? search.SCOPE_BASE_OBJECT + this.derefAliases = options.derefAliases ?? search.NEVER_DEREF_ALIASES + this.sizeLimit = options.sizeLimit ?? 0 + this.timeLimit = options.timeLimit ?? 0 + this.typesOnly = options.typesOnly ?? false + this.filter = options.filter ?? new filter.PresenceFilter({ attribute: 'objectclass' }) + this.attributes = options.attributes ?? [] + } + + /** + * Alias of {@link baseObject}. + * + * @type {import('@ldapjs/dn').DN} + */ + get _dn () { + return this.#baseObject + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'SearchRequest' + } + + /** + * The list of attributes to match against. + * + * @returns {string[]} + */ + get attributes () { + return this.#attributes + } + + /** + * Set the list of attributes to match against. Overwrites any existing + * attributes. The list is a set of spec defined strings. They are not + * instances of `@ldapjs/attribute`. + * + * See: + * + https://www.rfc-editor.org/rfc/rfc4511.html#section-4.5.1.8 + * + https://www.rfc-editor.org/rfc/rfc3673.html + * + https://www.rfc-editor.org/rfc/rfc4529.html + * + * @param {string)[]} attrs + */ + set attributes (attrs) { + if (Array.isArray(attrs) === false) { + throw Error('attributes must be an array of attribute strings') + } + const newAttrs = [] + for (const attr of attrs) { + if (typeof attr === 'string' && isValidAttributeString(attr) === true) { + newAttrs.push(attr) + } else if (typeof attr === 'string' && attr === '') { + // TODO: emit warning about spec violation via log and/or telemetry + warning.emit('LDAP_ATTRIBUTE_SPEC_ERR_001') + } else { + throw Error('attribute must be a valid string') + } + } + this.#attributes = newAttrs + } + + /** + * The base LDAP object that the search will start from. + * + * @returns {import('@ldapjs/dn').DN} + */ + get baseObject () { + return this.#baseObject + } + + /** + * Define the base LDAP object to start searches from. + * + * @param {string | import('@ldapjs/dn').DN} obj + */ + set baseObject (obj) { + if (typeof obj === 'string') { + this.#baseObject = DN.fromString(obj) + } else if (Object.prototype.toString.call(obj) === '[object LdapDn]') { + this.#baseObject = obj + } else { + throw Error('baseObject must be a DN string or DN instance') + } + } + + /** + * The alias dereferencing method that will be provided to the server. + * May be one of {@link DEREF_ALIASES_NEVER}, {@link DEREF_IN_SEARCHING}, + * {@link DEREF_BASE_OBJECT},or {@link DEREF_ALWAYS}. + * + * @returns {number} + */ + get derefAliases () { + return this.#derefAliases + } + + /** + * Define the dereferencing method that will be provided to the server. + * May be one of {@link DEREF_ALIASES_NEVER}, {@link DEREF_IN_SEARCHING}, + * {@link DEREF_BASE_OBJECT},or {@link DEREF_ALWAYS}. + * + * @param {number} value + */ + set derefAliases (value) { + if (Number.isInteger(value) === false) { + throw Error('derefAliases must be set to an integer') + } + this.#derefAliases = value + } + + /** + * The filter that will be used in the search. + * + * @returns {import('@ldapjs/filter').FilterString} + */ + get filter () { + return this.#filter + } + + /** + * Define the filter to use in the search. + * + * @param {string | import('@ldapjs/filter').FilterString} value + */ + set filter (value) { + if ( + typeof value !== 'string' && + Object.prototype.toString.call(value) !== '[object FilterString]' + ) { + throw Error('filter must be a string or a FilterString instance') + } + + if (typeof value === 'string') { + this.#filter = filter.parseString(value) + } else { + this.#filter = value + } + } + + /** + * The current search scope value. Can be matched against the exported + * scope statics. + * + * @returns {number} + * + * @throws When the scope is set to an unrecognized scope constant. + */ + get scope () { + return this.#scope + } + + /** + * Define the scope of the search. + * + * @param {number|string} value Accepts one of {@link SCOPE_BASE}, + * {@link SCOPE_SINGLE}, or {@link SCOPE_SUBTREE}. Or, as a string, one of + * "base", "single", "one", "subtree", or "sub". + * + * @throws When the provided scope does not resolve to a recognized scope. + */ + set scope (value) { + const resolvedScope = scopeAliasToScope(value) + if (resolvedScope === undefined) { + throw Error(value + ' is an invalid search scope') + } + this.#scope = resolvedScope + } + + /** + * The current search scope value as a string name. + * + * @returns {string} One of 'base', 'single', or 'subtree'. + * + * @throws When the scope is set to an unrecognized scope constant. + */ + get scopeName () { + switch (this.#scope) { + case search.SCOPE_BASE_OBJECT: + return 'base' + case search.SCOPE_ONE_LEVEL: + return 'single' + case search.SCOPE_SUBTREE: + return 'subtree' + } + } + + /** + * The number of entries to limit search results to. + * + * @returns {number} + */ + get sizeLimit () { + return this.#sizeLimit + } + + /** + * Define the number of entries to limit search results to. + * + * @param {number} value `0` indicates no restriction. + */ + set sizeLimit (value) { + if (Number.isInteger(value) === false) { + throw Error('sizeLimit must be an integer') + } + this.#sizeLimit = value + } + + /** + * The number of seconds that the search should be limited to for execution. + * A value of `0` indicates a willingness to wait as long as the server is + * willing to work. + * + * @returns {number} + */ + get timeLimit () { + return this.#timeLimit + } + + /** + * Define the number of seconds to wait for a search result before the server + * should abort the search. + * + * @param {number} value `0` indicates no time limit restriction. + */ + set timeLimit (value) { + if (Number.isInteger(value) === false) { + throw Error('timeLimit must be an integer') + } + this.#timeLimit = value + } + + /** + * Indicates if only attribute names (`true`) should be returned, or if both + * attribute names and attribute values (`false`) should be returned. + * + * @returns {boolean} + */ + get typesOnly () { + return this.#typesOnly + } + + /** + * Define if the search results should include only the attributes names + * or attribute names and attribute values. + * + * @param {boolean} value `false` for both names and values, `true` for + * names only. + */ + set typesOnly (value) { + if (typeof value !== 'boolean') { + throw Error('typesOnly must be set to a boolean value') + } + this.#typesOnly = value + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_REQ_SEARCH) + + ber.writeString(this.#baseObject.toString()) + ber.writeEnumeration(this.#scope) + ber.writeEnumeration(this.#derefAliases) + ber.writeInt(this.#sizeLimit) + ber.writeInt(this.#timeLimit) + ber.writeBoolean(this.#typesOnly) + ber.appendBuffer(this.#filter.toBer().buffer) + + ber.startSequence(BerTypes.Sequence | BerTypes.Constructor) + for (const attr of this.#attributes) { + ber.writeString(attr) + } + ber.endSequence() + + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.baseObject = this.baseObject.toString() + obj.scope = this.scopeName + obj.derefAliases = this.derefAliases + obj.sizeLimit = this.sizeLimit + obj.timeLimit = this.timeLimit + obj.typesOnly = this.typesOnly + obj.filter = this.filter.toString() + + obj.attributes = [] + for (const attr of this.#attributes) { + obj.attributes.push(attr) + } + + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_REQ_SEARCH) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const baseObject = ber.readString() + const scope = ber.readEnumeration() + const derefAliases = ber.readEnumeration() + const sizeLimit = ber.readInt() + const timeLimit = ber.readInt() + const typesOnly = ber.readBoolean() + + const filterTag = ber.peek() + const filterBuffer = ber.readRawBuffer(filterTag) + const parsedFilter = filter.parseBer(new BerReader(filterBuffer)) + + const attributes = [] + // Advance to the first attribute sequence in the set + // of attribute sequences. + ber.readSequence() + const endOfAttributesPos = ber.offset + ber.length + while (ber.offset < endOfAttributesPos) { + const attribute = ber.readString() + attributes.push(attribute) + } + + return { + protocolOp, + baseObject, + scope, + derefAliases, + sizeLimit, + timeLimit, + typesOnly, + filter: parsedFilter.toString(), + attributes + } + } +} + +module.exports = SearchRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/search-request.test.js b/node_modules/@ldapjs/messages/lib/messages/search-request.test.js new file mode 100644 index 0000000..e948348 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-request.test.js @@ -0,0 +1,438 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const filter = require('@ldapjs/filter') +const SearchRequest = require('./search-request') +const { DN } = require('@ldapjs/dn') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const warning = require('../deprecations') + +// Silence the standard warning logs. We will test the messages explicitly. +process.removeAllListeners('warning') + +const { + searchRequestBytes +} = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new SearchRequest() + const pojo = req.pojo + t.strictSame(pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_SEARCH, + type: 'SearchRequest', + baseObject: '', + scope: 'base', + derefAliases: SearchRequest.DEREF_ALIASES_NEVER, + sizeLimit: 0, + timeLimit: 0, + typesOnly: false, + filter: '(objectclass=*)', + attributes: [], + controls: [] + }) + + t.equal(req.type, 'SearchRequest') + }) + + t.test('constructor with args', async t => { + const req = new SearchRequest({ + baseObject: 'cn=foo,dc=example,dc=com', + scope: SearchRequest.SCOPE_SUBTREE, + derefAliases: SearchRequest.DEREF_BASE_OBJECT, + sizeLimit: 1, + timeLimit: 1, + typesOnly: true, + filter: new filter.EqualityFilter({ attribute: 'cn', value: 'foo' }), + attributes: ['*'] + }) + const pojo = req.pojo + t.strictSame(pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_SEARCH, + type: 'SearchRequest', + baseObject: 'cn=foo,dc=example,dc=com', + scope: 'subtree', + derefAliases: SearchRequest.DEREF_BASE_OBJECT, + sizeLimit: 1, + timeLimit: 1, + typesOnly: true, + filter: '(cn=foo)', + attributes: ['*'], + controls: [] + }) + }) + + t.end() +}) + +tap.test('.attributes', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.strictSame(req.attributes, []) + + req.attributes = ['*'] + t.strictSame(req.attributes, ['*']) + }) + + t.test('set overwrites current list', async t => { + const req = new SearchRequest({ + attributes: ['1.1'] + }) + req.attributes = ['1.1', '*', '@foo3-bar.2', 'cn', 'sn;lang-en'] + + t.strictSame(req.attributes, ['1.1', '*', '@foo3-bar.2', 'cn', 'sn;lang-en']) + }) + + t.test('throws if not an array', async t => { + t.throws( + () => new SearchRequest({ attributes: '*' }), + 'attributes must be an array of attribute strings' + ) + }) + + t.test('throws if array contains non-attribute', async t => { + const input = [ + '*', + 'not allowed' + ] + t.throws( + () => new SearchRequest({ attributes: input }), + 'attribute must be a valid string' + ) + }) + + t.test('supports single character names (issue #2)', async t => { + const req = new SearchRequest({ + attributes: ['a'] + }) + t.strictSame(req.attributes, ['a']) + }) + + t.test('supports multiple attribute options', async t => { + const req = new SearchRequest({ + attributes: ['abc;lang-en;lang-es'] + }) + t.strictSame(req.attributes, ['abc;lang-en;lang-es']) + }) + + t.test('supports range options', async t => { + const req = new SearchRequest({ + attributes: [ + 'a;range=0-*', + 'abc;range=100-200', + 'def;range=0-5;lang-en', + 'ghi;lang-en;range=6-10', + 'jkl;lang-en;range=11-15;lang-es' + ] + }) + t.strictSame(req.attributes, [ + 'a;range=0-*', + 'abc;range=100-200', + 'def;range=0-5;lang-en', + 'ghi;lang-en;range=6-10', + 'jkl;lang-en;range=11-15;lang-es' + ]) + }) + + t.test('throws if array contains an invalid range', async t => { + const input = ['a;range=*-100'] + t.throws( + () => new SearchRequest({ attributes: input }), + 'attribute must be a valid string' + ) + }) + + t.test('skip empty attribute name', async t => { + process.on('warning', handler) + t.teardown(async () => { + process.removeListener('warning', handler) + warning.emitted.set('LDAP_ATTRIBUTE_SPEC_ERR_001', false) + }) + + const req = new SearchRequest({ + attributes: ['abc', ''] + }) + t.strictSame(req.attributes, ['abc']) + + function handler (error) { + t.equal(error.message, 'received attempt to define attribute with an empty name: attribute skipped.') + t.end() + } + }) + + t.end() +}) + +tap.test('.baseObject', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.baseObject.toString(), '') + + req.baseObject = 'dc=example,dc=com' + t.equal(req.baseObject.toString(), 'dc=example,dc=com') + + req.baseObject = DN.fromString('dc=example,dc=net') + t.equal(req.baseObject.toString(), 'dc=example,dc=net') + t.equal(req._dn.toString(), 'dc=example,dc=net') + }) + + t.test('throws for non-DN object', async t => { + const req = new SearchRequest() + t.throws( + () => { + req.baseObject = ['foo'] + }, + 'baseObject must be a DN string or DN instance' + ) + }) + + t.end() +}) + +tap.test('.derefAliases', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.derefAliases, SearchRequest.DEREF_ALIASES_NEVER) + + req.derefAliases = SearchRequest.DEREF_ALWAYS + t.equal(req.derefAliases, SearchRequest.DEREF_ALWAYS) + }) + + t.test('throws for bad value', async t => { + const req = new SearchRequest() + t.throws( + () => { + req.derefAliases = '0' + }, + 'derefAliases must be set to an integer' + ) + }) + + t.end() +}) + +tap.test('.filter', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.filter.toString(), '(objectclass=*)') + + req.filter = '(cn=foo)' + t.equal(req.filter.toString(), '(cn=foo)') + + req.filter = new filter.EqualityFilter({ attribute: 'sn', value: 'bar' }) + t.equal(req.filter.toString(), '(sn=bar)') + }) + + t.test('throws for bad value', async t => { + const expected = 'filter must be a string or a FilterString instance' + const req = new SearchRequest() + t.throws( + () => { + req.filter = ['foo'] + }, + expected + ) + t.throws( + () => { + req.filter = { attribute: 'cn', value: 'foo' } + }, + expected + ) + }) + + t.end() +}) + +tap.test('.scope', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.scopeName, 'base') + t.equal(req.scope, 0) + + req.scope = SearchRequest.SCOPE_SINGLE + t.equal(req.scopeName, 'single') + t.equal(req.scope, 1) + + req.scope = SearchRequest.SCOPE_SUBTREE + t.equal(req.scopeName, 'subtree') + t.equal(req.scope, 2) + + req.scope = 'SUB' + t.equal(req.scopeName, 'subtree') + t.equal(req.scope, 2) + + req.scope = 'base' + t.equal(req.scopeName, 'base') + t.equal(req.scope, 0) + }) + + t.test('throws for invalid value', async t => { + const expected = ' is an invalid search scope' + const req = new SearchRequest() + + t.throws( + () => { + req.scope = 'nested' + }, + 'nested' + expected + ) + + t.throws( + () => { + req.scope = 42 + }, + 42 + expected + ) + }) + + t.end() +}) + +tap.test('.sizeLimit', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.sizeLimit, 0) + + req.sizeLimit = 15 + t.equal(req.sizeLimit, 15) + }) + + t.test('throws for bad value', async t => { + const req = new SearchRequest() + t.throws( + () => { + req.sizeLimit = 15.5 + }, + 'sizeLimit must be an integer' + ) + }) + + t.end() +}) + +tap.test('.timeLimit', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.timeLimit, 0) + + req.timeLimit = 15 + t.equal(req.timeLimit, 15) + }) + + t.test('throws for bad value', async t => { + const req = new SearchRequest() + t.throws( + () => { + req.timeLimit = 15.5 + }, + 'timeLimit must be an integer' + ) + }) + + t.end() +}) + +tap.test('.typesOnly', t => { + t.test('sets/gets', async t => { + const req = new SearchRequest() + t.equal(req.typesOnly, false) + + req.typesOnly = true + t.equal(req.typesOnly, true) + }) + + t.test('throws for bad value', async t => { + const req = new SearchRequest() + t.throws( + () => { + req.typesOnly = 'true' + }, + 'typesOnly must be set to a boolean value' + ) + }) + + t.end() +}) + +tap.test('_toBer', t => { + tap.test('converts instance to BER', async t => { + const req = new SearchRequest({ + messageId: 2, + baseObject: 'dc=example,dc=com', + scope: 'subtree', + derefAliases: SearchRequest.DEREF_ALIASES_NEVER, + sizeLimit: 1000, + timeLimit: 30, + typesOnly: false, + filter: '(&(objectClass=person)(uid=jdoe))', + + attributes: ['*', '+'] + }) + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(searchRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new SearchRequest() + t.strictSame(req._pojo(), { + baseObject: '', + scope: 'base', + derefAliases: 0, + sizeLimit: 0, + timeLimit: 0, + typesOnly: false, + filter: '(objectclass=*)', + attributes: [] + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(searchRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => SearchRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(searchRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = SearchRequest.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_REQ_SEARCH) + t.equal(pojo.baseObject, 'dc=example,dc=com') + t.equal(pojo.scope, SearchRequest.SCOPE_SUBTREE) + t.equal(pojo.derefAliases, SearchRequest.DEREF_ALIASES_NEVER) + t.equal(pojo.sizeLimit, 1000) + t.equal(pojo.timeLimit, 30) + t.equal(pojo.typesOnly, false) + t.equal(pojo.filter, '(&(objectClass=person)(uid=jdoe))') + t.strictSame(pojo.attributes, ['*', '+']) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/search-result-done.js b/node_modules/@ldapjs/messages/lib/messages/search-result-done.js new file mode 100644 index 0000000..44e7a99 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-result-done.js @@ -0,0 +1,54 @@ +'use strict' + +const LdapResult = require('../ldap-result') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the search result done response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.5.2. + */ +class SearchResultDone extends LdapResult { + #uri + + /** + * @typedef {LdapResultOptions} SearchResultDoneOptions + * @property {string[]} [uri=[]] The set of reference URIs the message is + * providing. + * @property {string[]} [uris] An alias for uri. + */ + + /** + * @param {SearchResultDoneOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_SEARCH_DONE + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'SearchResultDone' + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + return LdapResult._parseToPojo({ + opCode: operations.LDAP_RES_SEARCH_DONE, + berReader: ber + }) + } +} + +module.exports = SearchResultDone diff --git a/node_modules/@ldapjs/messages/lib/messages/search-result-done.test.js b/node_modules/@ldapjs/messages/lib/messages/search-result-done.test.js new file mode 100644 index 0000000..eb7d063 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-result-done.test.js @@ -0,0 +1,52 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const { operations } = require('@ldapjs/protocol') +const { + searchResultDoneBytes +} = require('./_fixtures/message-byte-arrays') +const SearchResultDone = require('./search-result-done') + +tap.test('basic', async t => { + const res = new SearchResultDone() + t.equal(res.protocolOp, operations.LDAP_RES_SEARCH_DONE) + t.equal(res.type, 'SearchResultDone') +}) + +tap.test('toBer', t => { + tap.test('returns basic bytes', async t => { + const res = new SearchResultDone({ messageId: 2 }) + const ber = res.toBer() + const expected = Buffer.from(searchResultDoneBytes) + t.equal(expected.compare(ber.buffer), 0) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('parses a basic object', async t => { + const bytes = searchResultDoneBytes.slice(5) + const reader = new BerReader(Buffer.from(bytes)) + const pojo = SearchResultDone.parseToPojo(reader) + t.strictSame(pojo, { + status: 0, + matchedDN: '', + diagnosticMessage: '', + referrals: [] + }) + }) + + t.test('throws if protocol op is wrong', async t => { + const bytes = searchResultDoneBytes.slice(5) + bytes[0] = 0x68 + const reader = new BerReader(Buffer.from(bytes)) + t.throws( + () => SearchResultDone.parseToPojo(reader), + Error('found wrong protocol operation: 0x68') + ) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/search-result-entry.js b/node_modules/@ldapjs/messages/lib/messages/search-result-entry.js new file mode 100644 index 0000000..1e22c05 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-result-entry.js @@ -0,0 +1,198 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const Attribute = require('@ldapjs/attribute') +const { operations } = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') + +/** + * Implements the search result entry message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.5.2. + */ +class SearchResultEntry extends LdapMessage { + /** + * Path to the LDAP object. + * + * @type {import('@ldapjs/dn').DN} + */ + #objectName + + /** + * A set of attribute objects. + * + * @type {import('@ldapjs/attribute')[]} + */ + #attributes = [] + + /** + * @typedef {LdapMessageOptions} SearchResultEntryOptions + * @property {string | import('@ldapjs/dn').DN} [objectName=''] The path to + * the LDAP object. + * @property {import('@ldapjs/attribute')[]} attributes A set of attributes + * to store at the `entry` path. + */ + + /** + * @param {SearchResultEntryOptions} [options] + * + * @throws When the provided attributes list is invalid or the object name + * is not a valid LdapDn object or DN string. + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_SEARCH_ENTRY + super(options) + + this.objectName = options.objectName ?? '' + this.attributes = options.attributes ?? [] + } + + /** + * Alias of {@link objectName}. + * + * @type {string} + */ + get _dn () { + return this.#objectName + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'SearchResultEntry' + } + + /** + * Get a copy of the attributes associated with the request. + * + * @returns {import('@ldapjs/attribute')[]} + */ + get attributes () { + return this.#attributes.slice(0) + } + + /** + * Set the attributes to be added to the entry. Replaces any existing + * attributes. + * + * @param {object[] | import('@ldapjs/attribute')[]} attrs + * + * @throws If the input is not an array, or any element is not an + * {@link Attribute} or attribute-like object. + */ + set attributes (attrs) { + if (Array.isArray(attrs) === false) { + throw Error('attrs must be an array') + } + const newAttrs = [] + for (const attr of attrs) { + if (Attribute.isAttribute(attr) === false) { + throw Error('attr must be an Attribute instance or Attribute-like object') + } + if (Object.prototype.toString.call(attr) !== '[object LdapAttribute]') { + newAttrs.push(new Attribute(attr)) + continue + } + newAttrs.push(attr) + } + this.#attributes = newAttrs + } + + /** + * The path to the LDAP entry that matched the search. + * + * @returns {import('@ldapjs/dn').DN} + */ + get objectName () { + return this.#objectName + } + + /** + * Set the path to the LDAP entry that matched the search. + * + * @param {string | import('@ldapjs/dn').DN} value + * + * @throws When the input is invalid. + */ + set objectName (value) { + if (typeof value === 'string') { + this.#objectName = DN.fromString(value) + } else if (Object.prototype.toString.call(value) === '[object LdapDn]') { + this.#objectName = value + } else { + throw Error('objectName must be a DN string or an instance of LdapDn') + } + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_RES_SEARCH_ENTRY) + ber.writeString(this.#objectName.toString()) + ber.startSequence() + for (const attr of this.#attributes) { + const attrBer = attr.toBer() + ber.appendBuffer(attrBer.buffer) + } + ber.endSequence() + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.objectName = this.#objectName.toString() + obj.attributes = [] + for (const attr of this.#attributes) { + obj.attributes.push(attr.pojo) + } + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_RES_SEARCH_ENTRY) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const objectName = ber.readString() + const attributes = [] + + // Advance to the first attribute sequence in the set + // of attribute sequences. + ber.readSequence() + + const endOfAttributesPos = ber.offset + ber.length + while (ber.offset < endOfAttributesPos) { + const attribute = Attribute.fromBer(ber) + attributes.push(attribute) + } + + return { protocolOp, objectName, attributes } + } +} + +module.exports = SearchResultEntry diff --git a/node_modules/@ldapjs/messages/lib/messages/search-result-entry.test.js b/node_modules/@ldapjs/messages/lib/messages/search-result-entry.test.js new file mode 100644 index 0000000..5d141ab --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-result-entry.test.js @@ -0,0 +1,195 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const Attribute = require('@ldapjs/attribute') +const { DN } = require('@ldapjs/dn') +const { BerWriter, BerReader } = require('@ldapjs/asn1') +const SearchResultEntry = require('./search-result-entry') + +const { + searchResultEntryBytes, + searchResultEntryNoValuesBytes +} = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const res = new SearchResultEntry() + t.strictSame(res.pojo, { + messageId: 1, + protocolOp: operations.LDAP_RES_SEARCH_ENTRY, + type: 'SearchResultEntry', + objectName: '', + attributes: [], + controls: [] + }) + + t.equal(res.type, 'SearchResultEntry') + }) + + t.test('constructor with args', async t => { + const res = new SearchResultEntry({ + objectName: 'dc=example,dc=com', + attributes: [{ type: 'cn', values: ['foo'] }] + }) + t.strictSame(res.pojo, { + messageId: 1, + protocolOp: operations.LDAP_RES_SEARCH_ENTRY, + type: 'SearchResultEntry', + objectName: 'dc=example,dc=com', + attributes: [{ type: 'cn', values: ['foo'] }], + controls: [] + }) + }) + + t.end() +}) + +tap.test('.attributes', t => { + t.test('sets/gets', async t => { + const res = new SearchResultEntry() + t.strictSame(res.attributes, []) + + res.attributes = [new Attribute({ type: 'cn', values: 'foo' })] + t.strictSame(res.attributes, [new Attribute({ type: 'cn', values: 'foo' })]) + }) + + t.test('rejects non-array', async t => { + const res = new SearchResultEntry() + t.throws( + () => { + res.attributes = { type: 'cn', values: ['foo'] } + }, + 'attrs must be an array' + ) + }) + + t.test('rejects non-attribute objects', async t => { + const res = new SearchResultEntry() + t.throws( + () => { + res.attributes = [{ foo: 'bar' }] + }, + 'attr must be an Attribute instance or Attribute-like object' + ) + }) + + t.end() +}) + +tap.test('.objectName', t => { + t.test('sets/gets', async t => { + const res = new SearchResultEntry() + t.equal(res.objectName.toString(), '') + t.equal(res._dn.toString(), '') + + res.objectName = 'cn=foo' + t.equal(res.objectName.toString(), 'cn=foo') + + res.objectName = DN.fromString('sn=bar') + t.equal(res.objectName.toString(), 'sn=bar') + }) + + t.test('throws for invalid value', async t => { + const res = new SearchResultEntry() + t.throws( + () => { + res.objectName = ['invalid input'] + }, + 'objectName must be a DN string or instance of LdapDn' + ) + }) + + t.end() +}) + +tap.test('_toBer', t => { + t.test('converts instance to BER', async t => { + let res = new SearchResultEntry({ + objectName: 'dc=example,dc=com', + attributes: [ + { type: 'objectClass', values: ['top', 'domain'] }, + { type: 'dc', values: ['example'] } + ] + }) + let writer = new BerWriter() + res._toBer(writer) + + t.equal( + Buffer.from(searchResultEntryBytes.slice(5)).compare(writer.buffer), + 0 + ) + + res = new SearchResultEntry({ + objectName: 'dc=example,dc=com', + attributes: [ + { type: 'objectClass', values: [] }, + { type: 'dc', values: [] } + ] + }) + writer = new BerWriter() + res._toBer(writer) + + t.equal( + Buffer.from(searchResultEntryNoValuesBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new SearchResultEntry({ + objectName: 'cn=foo', + attributes: [{ type: 'bar', values: ['baz'] }] + }) + t.strictSame(req._pojo(), { + objectName: 'cn=foo', + attributes: [{ + type: 'bar', + values: ['baz'] + }] + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(searchResultEntryBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => SearchResultEntry.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(searchResultEntryBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = SearchResultEntry.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_RES_SEARCH_ENTRY) + t.equal(pojo.objectName, 'dc=example,dc=com') + t.strictSame(pojo.attributes[0].pojo, { + type: 'objectClass', + values: ['top', 'domain'] + }) + t.strictSame(pojo.attributes[1].pojo, { + type: 'dc', + values: ['example'] + }) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/search-result-reference.js b/node_modules/@ldapjs/messages/lib/messages/search-result-reference.js new file mode 100644 index 0000000..073c825 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-result-reference.js @@ -0,0 +1,144 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the search result reference response message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.5.2. + */ +class SearchResultReference extends LdapMessage { + #uri + + /** + * @typedef {LdapMessageOptions} SearchResultReferenceOptions + * @property {string[]} [uri=[]] The set of reference URIs the message is + * providing. + * @property {string[]} [uris] An alias for uri. + */ + + /** + * @param {SearchResultReferenceOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_RES_SEARCH_REF + super(options) + + this.uri = (options.uri || options.uris) ?? [] + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'SearchResultReference' + } + + /** + * The list of reference URIs associated with the message. + * + * @returns {string[]} + */ + get uri () { + return this.#uri.slice(0) + } + + /** + * Define the list of reference URIs associated with the message. + * + * @param {string[]} value + * + * @throws When the value is not an array or contains a non-string element. + */ + set uri (value) { + if ( + Array.isArray(value) === false || + value.some(v => typeof v !== 'string') + ) { + throw Error('uri must be an array of strings') + } + this.#uri = value.slice(0) + } + + /** + * Alias of {@link uri}. + * + * @returns {string[]} + */ + get uris () { + return this.uri + } + + /** + * Alias of {@link uri} setter. + * + * @param {string[]} value + */ + set uris (value) { + this.uri = value + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.startSequence(operations.LDAP_RES_SEARCH_REF) + + for (const uri of this.#uri) { + ber.writeString(uri) + } + + ber.endSequence() + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + obj.uri = [] + for (const uri of this.#uri) { + obj.uri.push(uri) + } + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + * + * @returns {object} + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_RES_SEARCH_REF) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + const uri = [] + + const endOfMessagePos = ber.offset + ber.length + while (ber.offset < endOfMessagePos) { + const u = ber.readString() + uri.push(u) + } + + return { protocolOp, uri } + } +} + +module.exports = SearchResultReference diff --git a/node_modules/@ldapjs/messages/lib/messages/search-result-reference.test.js b/node_modules/@ldapjs/messages/lib/messages/search-result-reference.test.js new file mode 100644 index 0000000..46f8fe7 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/search-result-reference.test.js @@ -0,0 +1,161 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const SearchResultReference = require('./search-result-reference') + +const { + searchResultReferenceBytes +} = require('./_fixtures/message-byte-arrays') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const expected = { + messageId: 1, + protocolOp: operations.LDAP_RES_SEARCH_REF, + type: 'SearchResultReference', + uri: [], + controls: [] + } + + const res = new SearchResultReference() + t.strictSame(res.pojo, expected) + + t.equal(res.type, 'SearchResultReference') + }) + + t.test('constructor with args', async t => { + const expected = { + messageId: 1, + protocolOp: operations.LDAP_RES_SEARCH_REF, + type: 'SearchResultReference', + uri: ['ldap://foo', 'ldap://bar'], + controls: [] + } + + let res = new SearchResultReference({ + uri: ['ldap://foo', 'ldap://bar'] + }) + t.strictSame(res.pojo, expected) + + res = new SearchResultReference({ + uris: ['ldap://foo', 'ldap://bar'] + }) + t.strictSame(res.pojo, expected) + }) + + t.end() +}) + +tap.test('.uri/.uris', t => { + t.test('sets/gets', async t => { + const res = new SearchResultReference() + t.strictSame(res.uri, []) + t.strictSame(res.uris, []) + + res.uri = ['ldap://foo'] + t.strictSame(res.uri, ['ldap://foo']) + + res.uris = ['ldap://bar'] + t.strictSame(res.uris, ['ldap://bar']) + t.strictSame(res.uri, ['ldap://bar']) + }) + + t.test('throws for bad input', async t => { + const res = new SearchResultReference() + const expected = Error('uri must be an array of strings') + + t.throws( + () => { + res.uri = 'ldap://foo' + }, + expected + ) + + t.throws( + () => { + res.uris = 'ldap://foo' + }, + expected + ) + + t.throws( + () => { + res.uri = ['ldap://foo', { foo: 'foo' }, 'ldap://bar'] + }, + expected + ) + }) + + t.end() +}) + +tap.test('_toBer', t => { + tap.test('converts instance to BER', async t => { + const res = new SearchResultReference({ + uri: [ + 'ldap://ds1.example.com:389/dc=example,dc=com??sub?', + 'ldap://ds2.example.com:389/dc=example,dc=com??sub?' + ] + }) + const writer = new BerWriter() + res._toBer(writer) + + t.equal( + Buffer.from(searchResultReferenceBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const res = new SearchResultReference({ + uri: [ + 'ldap://ds1.example.com:389/dc=example,dc=com??sub?', + 'ldap://ds2.example.com:389/dc=example,dc=com??sub?' + ] + }) + t.strictSame(res._pojo(), { + uri: [ + 'ldap://ds1.example.com:389/dc=example,dc=com??sub?', + 'ldap://ds2.example.com:389/dc=example,dc=com??sub?' + ] + }) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(searchResultReferenceBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => SearchResultReference.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(searchResultReferenceBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = SearchResultReference.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_RES_SEARCH_REF) + t.equal(pojo.uri[0], 'ldap://ds1.example.com:389/dc=example,dc=com??sub?') + t.equal(pojo.uri[1], 'ldap://ds2.example.com:389/dc=example,dc=com??sub?') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/messages/unbind-request.js b/node_modules/@ldapjs/messages/lib/messages/unbind-request.js new file mode 100644 index 0000000..bc616f6 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/unbind-request.js @@ -0,0 +1,69 @@ +'use strict' + +const LdapMessage = require('../ldap-message') +const { operations } = require('@ldapjs/protocol') + +/** + * Implements the unbind request message as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.3. + */ +class UnbindRequest extends LdapMessage { + /** + * @param {LdapMessageOptions} options + */ + constructor (options = {}) { + options.protocolOp = operations.LDAP_REQ_UNBIND + super(options) + } + + /** + * The name of the request type. + * + * @type {string} + */ + get type () { + return 'UnbindRequest' + } + + /** + * Internal use only. + * + * @param {import('@ldapjs/asn1').BerWriter} ber + * + * @returns {import('@ldapjs/asn1').BerWriter} + */ + _toBer (ber) { + ber.writeString('', operations.LDAP_REQ_UNBIND) + return ber + } + + /** + * Internal use only. + * + * @param {object} + * + * @returns {object} + */ + _pojo (obj = {}) { + return obj + } + + /** + * Implements the standardized `parseToPojo` method. + * + * @see LdapMessage.parseToPojo + * + * @param {import('@ldapjs/asn1').BerReader} ber + */ + static parseToPojo (ber) { + const protocolOp = ber.readSequence() + if (protocolOp !== operations.LDAP_REQ_UNBIND) { + const op = protocolOp.toString(16).padStart(2, '0') + throw Error(`found wrong protocol operation: 0x${op}`) + } + + return { protocolOp } + } +} + +module.exports = UnbindRequest diff --git a/node_modules/@ldapjs/messages/lib/messages/unbind-request.test.js b/node_modules/@ldapjs/messages/lib/messages/unbind-request.test.js new file mode 100644 index 0000000..f23c486 --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/messages/unbind-request.test.js @@ -0,0 +1,75 @@ +'use strict' + +const tap = require('tap') +const { operations } = require('@ldapjs/protocol') +const UnbindRequest = require('./unbind-request') + +const { unbindRequestBytes } = require('./_fixtures/message-byte-arrays') +const { BerReader, BerWriter } = require('@ldapjs/asn1') + +tap.test('basic', t => { + t.test('constructor no args', async t => { + const req = new UnbindRequest() + t.strictSame(req.pojo, { + messageId: 1, + protocolOp: operations.LDAP_REQ_UNBIND, + type: 'UnbindRequest', + controls: [] + }) + t.equal(req.type, 'UnbindRequest') + }) + + t.end() +}) + +tap.test('_toBer', t => { + tap.test('converts instance to BER', async t => { + const req = new UnbindRequest() + const writer = new BerWriter() + req._toBer(writer) + + t.equal( + Buffer.from(unbindRequestBytes.slice(5)).compare(writer.buffer), + 0 + ) + }) + + t.end() +}) + +tap.test('_pojo', t => { + t.test('returns a pojo representation', async t => { + const req = new UnbindRequest() + t.strictSame(req._pojo(), {}) + }) + + t.end() +}) + +tap.test('#parseToPojo', t => { + t.test('throws if operation incorrect', async t => { + const reqBuffer = Buffer.from(unbindRequestBytes) + reqBuffer[5] = 0x61 + + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + t.throws( + () => UnbindRequest.parseToPojo(reader), + Error('found wrong protocol operation: 0x61') + ) + }) + + t.test('returns a pojo representation', async t => { + const reqBuffer = Buffer.from(unbindRequestBytes) + const reader = new BerReader(reqBuffer) + reader.readSequence() + reader.readInt() + + const pojo = UnbindRequest.parseToPojo(reader) + t.equal(pojo.protocolOp, operations.LDAP_REQ_UNBIND) + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/messages/lib/parse-to-message.js b/node_modules/@ldapjs/messages/lib/parse-to-message.js new file mode 100644 index 0000000..0e52c8c --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/parse-to-message.js @@ -0,0 +1,205 @@ +'use strict' + +const { operations } = require('@ldapjs/protocol') +const { getControl } = require('@ldapjs/controls') + +const messageClasses = { + AbandonRequest: require('./messages/abandon-request'), + AddRequest: require('./messages/add-request'), + BindRequest: require('./messages/bind-request'), + CompareRequest: require('./messages/compare-request'), + DeleteRequest: require('./messages/delete-request'), + ExtensionRequest: require('./messages/extension-request'), + ModifyRequest: require('./messages/modify-request'), + ModifyDnRequest: require('./messages/modifydn-request'), + SearchRequest: require('./messages/search-request'), + UnbindRequest: require('./messages/unbind-request'), + + AbandonResponse: require('./messages/abandon-response'), + AddResponse: require('./messages/add-response'), + BindResponse: require('./messages/bind-response'), + CompareResponse: require('./messages/compare-response'), + DeleteResponse: require('./messages/delete-response'), + ExtensionResponse: require('./messages/extension-response'), + ModifyResponse: require('./messages/modify-response'), + ModifyDnResponse: require('./messages/modifydn-response'), + + // Search result messages. + SearchResultEntry: require('./messages/search-result-entry'), + SearchResultReference: require('./messages/search-result-reference'), + SearchResultDone: require('./messages/search-result-done'), + + // Miscellaneous messages. + IntermediateResponse: require('./messages/intermediate-response') +} + +/** + * Utility function that inspects a BER object and parses it into an instance + * of a specific LDAP message. + * + * @param {import('@ldapjs/asn1').BerReader} ber An object that represents a + * full LDAP Message sequence as described in + * https://www.rfc-editor.org/rfc/rfc4511.html#section-4.1.1. + * + * @returns {LdapMessage} Some specific instance of the base LDAP Message + * type. + * + * @throws When the input data is malformed. + */ +module.exports = function parseToMessage (ber) { + const inputType = Object.prototype.toString.apply(ber) + if (inputType !== '[object BerReader]') { + throw TypeError(`Expected BerReader but got ${inputType}.`) + } + + ber.readSequence() + + const messageId = ber.readInt() + const messageType = identifyType(ber) + const MessageClass = messageClasses[messageType] + const pojoMessage = MessageClass.parseToPojo(ber) + const message = new MessageClass({ + messageId, + ...pojoMessage + }) + + // Look for controls + if (ber.peek() === 0xa0) { + ber.readSequence() + const end = ber.offset + ber.length + while (ber.offset < end) { + const c = getControl(ber) + /* istanbul ignore else */ + if (c) { + message.addControl(c) + } + } + } + + return message +} + +/** + * Determines the type of LDAP message the BER represents, e.g. a "Bind Request" + * message. + * + * @param {BerReader} ber + * + * @returns {string} + */ +function identifyType (ber) { + let result + switch (ber.peek()) { + case operations.LDAP_REQ_ABANDON: { + result = 'AbandonRequest' + break + } + + case 0x00: { + result = 'AbandonResponse' + break + } + + case operations.LDAP_REQ_ADD: { + result = 'AddRequest' + break + } + + case operations.LDAP_RES_ADD: { + result = 'AddResponse' + break + } + + case operations.LDAP_REQ_BIND: { + result = 'BindRequest' + break + } + + case operations.LDAP_RES_BIND: { + result = 'BindResponse' + break + } + + case operations.LDAP_REQ_COMPARE: { + result = 'CompareRequest' + break + } + + case operations.LDAP_RES_COMPARE: { + result = 'CompareResponse' + break + } + + case operations.LDAP_REQ_DELETE: { + result = 'DeleteRequest' + break + } + + case operations.LDAP_RES_DELETE: { + result = 'DeleteResponse' + break + } + + case operations.LDAP_REQ_EXTENSION: { + result = 'ExtensionRequest' + break + } + + case operations.LDAP_RES_EXTENSION: { + result = 'ExtensionResponse' + break + } + + case operations.LDAP_REQ_MODIFY: { + result = 'ModifyRequest' + break + } + + case operations.LDAP_RES_MODIFY: { + result = 'ModifyResponse' + break + } + + case operations.LDAP_REQ_MODRDN: { + result = 'ModifyDnRequest' + break + } + + case operations.LDAP_RES_MODRDN: { + result = 'ModifyDnResponse' + break + } + + case operations.LDAP_REQ_SEARCH: { + result = 'SearchRequest' + break + } + + case operations.LDAP_RES_SEARCH_ENTRY: { + result = 'SearchResultEntry' + break + } + + case operations.LDAP_RES_SEARCH_REF: { + result = 'SearchResultReference' + break + } + + case operations.LDAP_RES_SEARCH_DONE: { + result = 'SearchResultDone' + break + } + + case operations.LDAP_REQ_UNBIND: { + result = 'UnbindRequest' + break + } + + case operations.LDAP_RES_INTERMEDIATE: { + result = 'IntermediateResponse' + break + } + } + + return result +} diff --git a/node_modules/@ldapjs/messages/lib/parse-to-message.test.js b/node_modules/@ldapjs/messages/lib/parse-to-message.test.js new file mode 100644 index 0000000..180762f --- /dev/null +++ b/node_modules/@ldapjs/messages/lib/parse-to-message.test.js @@ -0,0 +1,54 @@ +'use strict' + +const tap = require('tap') +const { BerReader } = require('@ldapjs/asn1') +const parseToMessage = require('./parse-to-message') + +const messageBytesArrays = require('./messages/_fixtures/message-byte-arrays') + +tap.test('throws if input not a BerReader', async t => { + const input = Buffer.from([0x30, 0x01, 0x64]) + t.throws( + () => parseToMessage(input), + Error('Expected BerReader but got [object Uint8Array]') + ) +}) + +tap.test('throws if sequence is invalid', async t => { + const input = new BerReader(Buffer.from([0x0a, 0x01, 0x64])) + t.throws( + () => parseToMessage(input), + Error('Expected 0x02: got 0x64') + ) +}) + +tap.test('parses messages correctly', async t => { + for (const [name, messageBytes] of Object.entries(messageBytesArrays)) { + t.comment(`verifying message bytes: ${name}`) + const expected = Buffer.from(messageBytes) + const reader = new BerReader(expected) + const message = parseToMessage(reader) + const found = message.toBer().buffer + const isEqual = t.equal(expected.compare(found), 0, `${name} comparison`) + + if (isEqual === false) { + const diff = {} + for (let i = 0; i < expected.length; i += 1) { + if (expected[i] !== found[i]) { + diff[i] = { + expected: Number(expected[i]).toString(16), + found: Number(found[i]).toString(16) + } + } + } + t.fail(`${name} differs`, diff) + } + } +}) + +tap.test('parses search req with evolution filter', async t => { + const messageBytes = require('./_fixtures/evolution-filter-req') + const messageBuffer = Buffer.from(messageBytes) + const message = parseToMessage(new BerReader(messageBuffer)) + t.equal(messageBuffer.compare(message.toBer().buffer), 0) +}) diff --git a/node_modules/@ldapjs/messages/package.json b/node_modules/@ldapjs/messages/package.json new file mode 100644 index 0000000..114b679 --- /dev/null +++ b/node_modules/@ldapjs/messages/package.json @@ -0,0 +1,44 @@ +{ + "name": "@ldapjs/messages", + "homepage": "https://github.com/ldapjs/messages", + "description": "API for creating and parsing LDAP messages", + "version": "1.3.0", + "license": "MIT", + "repository": { + "type": "git", + "url": "git@github.com:ldapjs/messages.git" + }, + "main": "index.js", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.2.0" + }, + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.47.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.28.0", + "eslint-plugin-n": "^16.0.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "tap": "^16.3.8" + }, + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-coverage-report", + "test:cov": "tap", + "test:cov:html": "tap --coverage-report=html", + "test:watch": "tap -w --no-coverage-report" + }, + "precommit": [ + "lint", + "test" + ] +} diff --git a/node_modules/@ldapjs/protocol/.eslintrc b/node_modules/@ldapjs/protocol/.eslintrc new file mode 100644 index 0000000..bfc2b2a --- /dev/null +++ b/node_modules/@ldapjs/protocol/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "ecmaVersion": "latest" + }, + + "extends": [ + "standard" + ] +} diff --git a/node_modules/@ldapjs/protocol/.github/workflows/main.yml b/node_modules/@ldapjs/protocol/.github/workflows/main.yml new file mode 100644 index 0000000..60030ee --- /dev/null +++ b/node_modules/@ldapjs/protocol/.github/workflows/main.yml @@ -0,0 +1,10 @@ +name: "CI" +on: + pull_request: + push: + branches: + - master + +jobs: + call-core-ci: + uses: ldapjs/.github/.github/workflows/node-ci.yml@main diff --git a/node_modules/@ldapjs/protocol/LICENSE b/node_modules/@ldapjs/protocol/LICENSE new file mode 100644 index 0000000..1913201 --- /dev/null +++ b/node_modules/@ldapjs/protocol/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2011 Mark Cavage, All rights reserved. +Copyright (c) 2022 The LDAPJS Collaborators. + +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 diff --git a/node_modules/@ldapjs/protocol/Readme.md b/node_modules/@ldapjs/protocol/Readme.md new file mode 100644 index 0000000..4998337 --- /dev/null +++ b/node_modules/@ldapjs/protocol/Readme.md @@ -0,0 +1,8 @@ +# `@ldapjs/protocol` + +This package provides a set of constant values and ASN.1 tags that are used +throughout the LDAP protocol. The constants are taken primarily from the +corresponding RFC: https://datatracker.ietf.org/doc/html/rfc4511. + +For reference on how tags are constructed, read: +https://web.archive.org/web/20220525004444/https://ldap.com/ldapv3-wire-protocol-reference-asn1-ber/ diff --git a/node_modules/@ldapjs/protocol/index.js b/node_modules/@ldapjs/protocol/index.js new file mode 100644 index 0000000..129be33 --- /dev/null +++ b/node_modules/@ldapjs/protocol/index.js @@ -0,0 +1,167 @@ +'use strict' + +const core = Object.freeze({ + LDAP_VERSION_3: 0x03, + LBER_SET: 0x31, + LDAP_CONTROLS: 0xa0 +}) + +const operations = Object.freeze({ + LDAP_REQ_BIND: 0x60, + LDAP_REQ_UNBIND: 0x42, + LDAP_REQ_SEARCH: 0x63, + LDAP_REQ_MODIFY: 0x66, + LDAP_REQ_ADD: 0x68, + LDAP_REQ_DELETE: 0x4a, + LDAP_REQ_MODRDN: 0x6c, + LDAP_REQ_COMPARE: 0x6e, + LDAP_REQ_ABANDON: 0x50, + LDAP_REQ_EXTENSION: 0x77, + + LDAP_RES_BIND: 0x61, + LDAP_RES_SEARCH_ENTRY: 0x64, + LDAP_RES_SEARCH_DONE: 0x65, + LDAP_RES_SEARCH_REF: 0x73, + LDAP_RES_SEARCH: 0x65, + LDAP_RES_MODIFY: 0x67, + LDAP_RES_ADD: 0x69, + LDAP_RES_DELETE: 0x6b, + LDAP_RES_MODRDN: 0x6d, + LDAP_RES_COMPARE: 0x6f, + LDAP_RES_EXTENSION: 0x78, + LDAP_RES_INTERMEDIATE: 0x79, + + // This is really an operation. It's a specific + // sequence tag. But the referral situation is + // so specific it makes more sense to put it here. + LDAP_RES_REFERRAL: 0xa3 +}) + +/** + * List of LDAP response result codes. See + * https://web.archive.org/web/20220812122129/https://nawilson.com/ldap-result-code-reference/ + */ +const resultCodes = Object.freeze({ + SUCCESS: 0, + OPERATIONS_ERROR: 1, + PROTOCOL_ERROR: 2, + TIME_LIMIT_EXCEEDED: 3, + SIZE_LIMIT_EXCEEDED: 4, + COMPARE_FALSE: 5, + COMPARE_TRUE: 6, + AUTH_METHOD_NOT_SUPPORTED: 7, + STRONGER_AUTH_REQUIRED: 8, + REFERRAL: 10, + ADMIN_LIMIT_EXCEEDED: 11, + UNAVAILABLE_CRITICAL_EXTENSION: 12, + CONFIDENTIALITY_REQUIRED: 13, + SASL_BIND_IN_PROGRESS: 14, + NO_SUCH_ATTRIBUTE: 16, + UNDEFINED_ATTRIBUTE_TYPE: 17, + INAPPROPRIATE_MATCHING: 18, + CONSTRAINT_VIOLATION: 19, + ATTRIBUTE_OR_VALUE_EXISTS: 20, + INVALID_ATTRIBUTE_SYNTAX: 21, + NO_SUCH_OBJECT: 32, + ALIAS_PROBLEM: 33, + INVALID_DN_SYNTAX: 34, + IS_LEAF: 35, + ALIAS_DEREFERENCING_PROBLEM: 36, + INAPPROPRIATE_AUTHENTICATION: 48, + INVALID_CREDENTIALS: 49, + INSUFFICIENT_ACCESS_RIGHTS: 50, + BUSY: 51, + UNAVAILABLE: 52, + UNWILLING_TO_PERFORM: 53, + LOOP_DETECT: 54, + SORT_CONTROL_MISSING: 60, + OFFSET_RANGE_ERROR: 61, + NAMING_VIOLATION: 64, + OBJECT_CLASS_VIOLATION: 65, + NOT_ALLOWED_ON_NON_LEAF: 66, + NOT_ALLOWED_ON_RDN: 67, + ENTRY_ALREADY_EXISTS: 68, + OBJECT_CLASS_MODS_PROHIBITED: 69, + RESULTS_TOO_LARGE: 70, + AFFECTS_MULTIPLE_DSAS: 71, + CONTROL_ERROR: 76, + OTHER: 80, + SERVER_DOWN: 81, + LOCAL_ERROR: 82, + ENCODING_ERROR: 83, + DECODING_ERROR: 84, + TIMEOUT: 85, + AUTH_UNKNOWN: 86, + FILTER_ERROR: 87, + USER_CANCELED: 88, + PARAM_ERROR: 89, + NO_MEMORY: 90, + CONNECT_ERROR: 91, + NOT_SUPPORTED: 92, + CONTROL_NOT_FOUND: 93, + NO_RESULTS_RETURNED: 94, + MORE_RESULTS_TO_RETURN: 95, + CLIENT_LOOP: 96, + REFERRAL_LIMIT_EXCEEDED: 97, + INVALID_RESPONSE: 100, + AMBIGUOUS_RESPONSE: 101, + TLS_NOT_SUPPORTED: 112, + INTERMEDIATE_RESPONSE: 113, + UNKNOWN_TYPE: 114, + CANCELED: 118, + NO_SUCH_OPERATION: 119, + TOO_LATE: 120, + CANNOT_CANCEL: 121, + ASSERTION_FAILED: 122, + AUTHORIZATION_DENIED: 123, + E_SYNC_REFRESH_REQUIRED: 4096, + NO_OPERATION: 16654 +}) + +/** + * Value constants and ASN.1 tags as defined in: + * https://datatracker.ietf.org/doc/html/rfc4511#section-4.5.1 + */ +const search = Object.freeze({ + SCOPE_BASE_OBJECT: 0, + SCOPE_ONE_LEVEL: 1, + SCOPE_SUBTREE: 2, + + NEVER_DEREF_ALIASES: 0, + DEREF_IN_SEARCHING: 1, + DEREF_BASE_OBJECT: 2, + DEREF_ALWAYS: 3, + + FILTER_AND: 0xa0, + FILTER_OR: 0xa1, + FILTER_NOT: 0xa2, + FILTER_EQUALITY: 0xa3, + FILTER_SUBSTRINGS: 0xa4, + FILTER_GE: 0xa5, + FILTER_LE: 0xa6, + FILTER_PRESENT: 0x87, + FILTER_APPROX: 0xa8, + FILTER_EXT: 0xa9 +}) + +module.exports = Object.freeze({ + core, + operations, + resultCodes, + search, + + resultCodeToName +}) + +/** + * Given an LDAP result code, return the constant name for that code. + * + * @param {number} code + * + * @returns {string|undefined} + */ +function resultCodeToName (code) { + for (const [key, value] of Object.entries(resultCodes)) { + if (value === code) return key + } +} diff --git a/node_modules/@ldapjs/protocol/index.test.js b/node_modules/@ldapjs/protocol/index.test.js new file mode 100644 index 0000000..5298e68 --- /dev/null +++ b/node_modules/@ldapjs/protocol/index.test.js @@ -0,0 +1,24 @@ +'use strict' + +const tap = require('tap') +const protocol = require('./') + +tap.test('exports expected object', async t => { + t.equal(Object.isFrozen(protocol), true); + ['core', 'operations', 'resultCodes', 'search'].forEach(component => { + t.ok(protocol[component]) + t.equal(Object.isFrozen(protocol[component]), true) + }) +}) + +tap.test('resultCodeToName', t => { + t.test('returns undefined for not found', async t => { + t.equal(protocol.resultCodeToName(-1), undefined) + }) + + t.test('returns correct name', async t => { + t.equal(protocol.resultCodeToName(32), 'NO_SUCH_OBJECT') + }) + + t.end() +}) diff --git a/node_modules/@ldapjs/protocol/package.json b/node_modules/@ldapjs/protocol/package.json new file mode 100644 index 0000000..08c5768 --- /dev/null +++ b/node_modules/@ldapjs/protocol/package.json @@ -0,0 +1,37 @@ +{ + "name": "@ldapjs/protocol", + "version": "1.2.1", + "description": "Provides constants for LDAP ASN.1 tags and values.", + "main": "index.js", + "scripts": { + "lint": "eslint .", + "lint:ci": "eslint .", + "test": "tap --no-cov -R terse", + "test:ci": "tap --coverage-report=lcovonly -R terse", + "test:cov": "tap -R terse", + "test:cov:html": "tap --coverage-report=html -R terse", + "test:watch": "tap -n -w --no-coverage-report -R terse" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/ldapjs/protocol.git" + }, + "keywords": [ + "ldapjs" + ], + "author": "James Sumners", + "license": "MIT", + "bugs": { + "url": "https://github.com/ldapjs/protocol/issues" + }, + "homepage": "https://github.com/ldapjs/protocol#readme", + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.17.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-n": "^15.2.1", + "eslint-plugin-promise": "^6.0.0", + "tap": "^16.2.0" + } +} diff --git a/node_modules/abstract-logging/Readme.md b/node_modules/abstract-logging/Readme.md new file mode 100644 index 0000000..3204c86 --- /dev/null +++ b/node_modules/abstract-logging/Readme.md @@ -0,0 +1,47 @@ +# abstract-logging + +This module provides an interface for modules to include so that they can +support logging via an external logger that conforms to the standard Log4j +interface. One such logger is [Pino](https://npm.im/pino). This module +is intended for modules that are meant to be used by other modules. + +Example: + +```js +'use strict' + +function AwesomeLibrary (options) { + this.log = (options.logger) ? options.logger : require('abstract-logging') +} + +AwesomeLibrary.prototype.coolMethod = function () { + this.log.trace('AwesomeLibrary.coolMethod was invoked') + return {} +} + +module.exports = AwesomeLibrary +``` + +## Interface + +Available methods: + ++ `fatal` ++ `error` ++ `warn` ++ `info` ++ `debug` ++ `trace` + +All methods are no operation functions. + +Some loggers, like [Pino](https://getpino.io/), implement a `child()` method. This method can be easily added to an `abstract-logging` instance when stubbing out such loggers: + +```js +const logger = require('abstract-logging') +logger.child = () => logger +``` + +## License + +[MIT License](http://jsumners.mit-license.org/) diff --git a/node_modules/abstract-logging/index.js b/node_modules/abstract-logging/index.js new file mode 100644 index 0000000..0fecbba --- /dev/null +++ b/node_modules/abstract-logging/index.js @@ -0,0 +1,18 @@ +'use strict' + +function noop () { } + +const proto = { + fatal: noop, + error: noop, + warn: noop, + info: noop, + debug: noop, + trace: noop +} + +Object.defineProperty(module, 'exports', { + get () { + return Object.create(proto) + } +}) diff --git a/node_modules/abstract-logging/package.json b/node_modules/abstract-logging/package.json new file mode 100644 index 0000000..94f931c --- /dev/null +++ b/node_modules/abstract-logging/package.json @@ -0,0 +1,25 @@ +{ + "name": "abstract-logging", + "version": "2.0.1", + "description": "A noop logger that conforms to the Log4j interface for modules to stub out internal logging", + "main": "index.js", + "scripts": { + "test": "node test.js" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jsumners/abstract-logging.git" + }, + "keywords": [ + "log", + "logging", + "logger", + "pino" + ], + "author": "James Sumners ", + "license": "MIT", + "bugs": { + "url": "https://github.com/jsumners/abstract-logging/issues" + }, + "homepage": "https://github.com/jsumners/abstract-logging#readme" +} diff --git a/node_modules/abstract-logging/test.js b/node_modules/abstract-logging/test.js new file mode 100644 index 0000000..c039ea2 --- /dev/null +++ b/node_modules/abstract-logging/test.js @@ -0,0 +1,17 @@ +'use strict' + +const assert = require('assert') + +const one = require('./') +const two = require('./') + +assert.notEqual(one, two) +assert.ok(one.info) +assert.equal(Function.prototype.isPrototypeOf(one.info), true) +two.info = () => 'info' + +const result1 = one.info() +assert.equal(result1, undefined) + +const result2 = two.info() +assert.equal(result2, 'info') diff --git a/node_modules/assert-plus/AUTHORS b/node_modules/assert-plus/AUTHORS new file mode 100644 index 0000000..1923524 --- /dev/null +++ b/node_modules/assert-plus/AUTHORS @@ -0,0 +1,6 @@ +Dave Eddy +Fred Kuo +Lars-Magnus Skog +Mark Cavage +Patrick Mooney +Rob Gulewich diff --git a/node_modules/assert-plus/CHANGES.md b/node_modules/assert-plus/CHANGES.md new file mode 100644 index 0000000..57d92bf --- /dev/null +++ b/node_modules/assert-plus/CHANGES.md @@ -0,0 +1,14 @@ +# assert-plus Changelog + +## 1.0.0 + +- *BREAKING* assert.number (and derivatives) now accept Infinity as valid input +- Add assert.finite check. Previous assert.number callers should use this if + they expect Infinity inputs to throw. + +## 0.2.0 + +- Fix `assert.object(null)` so it throws +- Fix optional/arrayOf exports for non-type-of asserts +- Add optiona/arrayOf exports for Stream/Date/Regex/uuid +- Add basic unit test coverage diff --git a/node_modules/assert-plus/README.md b/node_modules/assert-plus/README.md new file mode 100644 index 0000000..ec200d1 --- /dev/null +++ b/node_modules/assert-plus/README.md @@ -0,0 +1,162 @@ +# assert-plus + +This library is a super small wrapper over node's assert module that has two +things: (1) the ability to disable assertions with the environment variable +NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like +`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks +like this: + +```javascript + var assert = require('assert-plus'); + + function fooAccount(options, callback) { + assert.object(options, 'options'); + assert.number(options.id, 'options.id'); + assert.bool(options.isManager, 'options.isManager'); + assert.string(options.name, 'options.name'); + assert.arrayOfString(options.email, 'options.email'); + assert.func(callback, 'callback'); + + // Do stuff + callback(null, {}); + } +``` + +# API + +All methods that *aren't* part of node's core assert API are simply assumed to +take an argument, and then a string 'name' that's not a message; `AssertionError` +will be thrown if the assertion fails with a message like: + + AssertionError: foo (string) is required + at test (/home/mark/work/foo/foo.js:3:9) + at Object. (/home/mark/work/foo/foo.js:15:1) + at Module._compile (module.js:446:26) + at Object..js (module.js:464:10) + at Module.load (module.js:353:31) + at Function._load (module.js:311:12) + at Array.0 (module.js:484:10) + at EventEmitter._tickCallback (node.js:190:38) + +from: + +```javascript + function test(foo) { + assert.string(foo, 'foo'); + } +``` + +There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`: + +```javascript + function test(foo) { + assert.arrayOfString(foo, 'foo'); + } +``` + +You can assert IFF an argument is not `undefined` (i.e., an optional arg): + +```javascript + assert.optionalString(foo, 'foo'); +``` + +Lastly, you can opt-out of assertion checking altogether by setting the +environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have +lots of assertions, and don't want to pay `typeof ()` taxes to v8 in +production. Be advised: The standard functions re-exported from `assert` are +also disabled in assert-plus if NDEBUG is specified. Using them directly from +the `assert` module avoids this behavior. + +The complete list of APIs is: + +* assert.array +* assert.bool +* assert.buffer +* assert.func +* assert.number +* assert.finite +* assert.object +* assert.string +* assert.stream +* assert.date +* assert.regexp +* assert.uuid +* assert.arrayOfArray +* assert.arrayOfBool +* assert.arrayOfBuffer +* assert.arrayOfFunc +* assert.arrayOfNumber +* assert.arrayOfFinite +* assert.arrayOfObject +* assert.arrayOfString +* assert.arrayOfStream +* assert.arrayOfDate +* assert.arrayOfRegexp +* assert.arrayOfUuid +* assert.optionalArray +* assert.optionalBool +* assert.optionalBuffer +* assert.optionalFunc +* assert.optionalNumber +* assert.optionalFinite +* assert.optionalObject +* assert.optionalString +* assert.optionalStream +* assert.optionalDate +* assert.optionalRegexp +* assert.optionalUuid +* assert.optionalArrayOfArray +* assert.optionalArrayOfBool +* assert.optionalArrayOfBuffer +* assert.optionalArrayOfFunc +* assert.optionalArrayOfNumber +* assert.optionalArrayOfFinite +* assert.optionalArrayOfObject +* assert.optionalArrayOfString +* assert.optionalArrayOfStream +* assert.optionalArrayOfDate +* assert.optionalArrayOfRegexp +* assert.optionalArrayOfUuid +* assert.AssertionError +* assert.fail +* assert.ok +* assert.equal +* assert.notEqual +* assert.deepEqual +* assert.notDeepEqual +* assert.strictEqual +* assert.notStrictEqual +* assert.throws +* assert.doesNotThrow +* assert.ifError + +# Installation + + npm install assert-plus + +## License + +The MIT License (MIT) +Copyright (c) 2012 Mark Cavage + +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. + +## Bugs + +See . diff --git a/node_modules/assert-plus/assert.js b/node_modules/assert-plus/assert.js new file mode 100644 index 0000000..26f944e --- /dev/null +++ b/node_modules/assert-plus/assert.js @@ -0,0 +1,211 @@ +// Copyright (c) 2012, Mark Cavage. All rights reserved. +// Copyright 2015 Joyent, Inc. + +var assert = require('assert'); +var Stream = require('stream').Stream; +var util = require('util'); + + +///--- Globals + +/* JSSTYLED */ +var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/; + + +///--- Internal + +function _capitalize(str) { + return (str.charAt(0).toUpperCase() + str.slice(1)); +} + +function _toss(name, expected, oper, arg, actual) { + throw new assert.AssertionError({ + message: util.format('%s (%s) is required', name, expected), + actual: (actual === undefined) ? typeof (arg) : actual(arg), + expected: expected, + operator: oper || '===', + stackStartFunction: _toss.caller + }); +} + +function _getClass(arg) { + return (Object.prototype.toString.call(arg).slice(8, -1)); +} + +function noop() { + // Why even bother with asserts? +} + + +///--- Exports + +var types = { + bool: { + check: function (arg) { return typeof (arg) === 'boolean'; } + }, + func: { + check: function (arg) { return typeof (arg) === 'function'; } + }, + string: { + check: function (arg) { return typeof (arg) === 'string'; } + }, + object: { + check: function (arg) { + return typeof (arg) === 'object' && arg !== null; + } + }, + number: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg); + } + }, + finite: { + check: function (arg) { + return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg); + } + }, + buffer: { + check: function (arg) { return Buffer.isBuffer(arg); }, + operator: 'Buffer.isBuffer' + }, + array: { + check: function (arg) { return Array.isArray(arg); }, + operator: 'Array.isArray' + }, + stream: { + check: function (arg) { return arg instanceof Stream; }, + operator: 'instanceof', + actual: _getClass + }, + date: { + check: function (arg) { return arg instanceof Date; }, + operator: 'instanceof', + actual: _getClass + }, + regexp: { + check: function (arg) { return arg instanceof RegExp; }, + operator: 'instanceof', + actual: _getClass + }, + uuid: { + check: function (arg) { + return typeof (arg) === 'string' && UUID_REGEXP.test(arg); + }, + operator: 'isUUID' + } +}; + +function _setExports(ndebug) { + var keys = Object.keys(types); + var out; + + /* re-export standard assert */ + if (process.env.NODE_NDEBUG) { + out = noop; + } else { + out = function (arg, msg) { + if (!arg) { + _toss(msg, 'true', arg); + } + }; + } + + /* standard checks */ + keys.forEach(function (k) { + if (ndebug) { + out[k] = noop; + return; + } + var type = types[k]; + out[k] = function (arg, msg) { + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* optional checks */ + keys.forEach(function (k) { + var name = 'optional' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!type.check(arg)) { + _toss(msg, k, type.operator, arg, type.actual); + } + }; + }); + + /* arrayOf checks */ + keys.forEach(function (k) { + var name = 'arrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* optionalArrayOf checks */ + keys.forEach(function (k) { + var name = 'optionalArrayOf' + _capitalize(k); + if (ndebug) { + out[name] = noop; + return; + } + var type = types[k]; + var expected = '[' + k + ']'; + out[name] = function (arg, msg) { + if (arg === undefined || arg === null) { + return; + } + if (!Array.isArray(arg)) { + _toss(msg, expected, type.operator, arg, type.actual); + } + var i; + for (i = 0; i < arg.length; i++) { + if (!type.check(arg[i])) { + _toss(msg, expected, type.operator, arg, type.actual); + } + } + }; + }); + + /* re-export built-in assertions */ + Object.keys(assert).forEach(function (k) { + if (k === 'AssertionError') { + out[k] = assert[k]; + return; + } + if (ndebug) { + out[k] = noop; + return; + } + out[k] = assert[k]; + }); + + /* export ourselves (for unit tests _only_) */ + out._setExports = _setExports; + + return out; +} + +module.exports = _setExports(process.env.NODE_NDEBUG); diff --git a/node_modules/assert-plus/package.json b/node_modules/assert-plus/package.json new file mode 100644 index 0000000..40d6a5c --- /dev/null +++ b/node_modules/assert-plus/package.json @@ -0,0 +1,23 @@ +{ + "author": "Mark Cavage ", + "name": "assert-plus", + "description": "Extra assertions on top of node's assert module", + "version": "1.0.0", + "license": "MIT", + "main": "./assert.js", + "devDependencies": { + "tape": "4.2.2", + "faucet": "0.0.1" + }, + "optionalDependencies": {}, + "scripts": { + "test": "./node_modules/.bin/tape tests/*.js | ./node_modules/.bin/faucet" + }, + "repository": { + "type": "git", + "url": "https://github.com/mcavage/node-assert-plus.git" + }, + "engines": { + "node": ">=0.8" + } +} diff --git a/node_modules/asynckit/LICENSE b/node_modules/asynckit/LICENSE new file mode 100644 index 0000000..c9eca5d --- /dev/null +++ b/node_modules/asynckit/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Alex Indigo + +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. diff --git a/node_modules/asynckit/README.md b/node_modules/asynckit/README.md new file mode 100644 index 0000000..ddcc7e6 --- /dev/null +++ b/node_modules/asynckit/README.md @@ -0,0 +1,233 @@ +# asynckit [![NPM Module](https://img.shields.io/npm/v/asynckit.svg?style=flat)](https://www.npmjs.com/package/asynckit) + +Minimal async jobs utility library, with streams support. + +[![PhantomJS Build](https://img.shields.io/travis/alexindigo/asynckit/v0.4.0.svg?label=browser&style=flat)](https://travis-ci.org/alexindigo/asynckit) +[![Linux Build](https://img.shields.io/travis/alexindigo/asynckit/v0.4.0.svg?label=linux:0.12-6.x&style=flat)](https://travis-ci.org/alexindigo/asynckit) +[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/asynckit/v0.4.0.svg?label=windows:0.12-6.x&style=flat)](https://ci.appveyor.com/project/alexindigo/asynckit) + +[![Coverage Status](https://img.shields.io/coveralls/alexindigo/asynckit/v0.4.0.svg?label=code+coverage&style=flat)](https://coveralls.io/github/alexindigo/asynckit?branch=master) +[![Dependency Status](https://img.shields.io/david/alexindigo/asynckit/v0.4.0.svg?style=flat)](https://david-dm.org/alexindigo/asynckit) +[![bitHound Overall Score](https://www.bithound.io/github/alexindigo/asynckit/badges/score.svg)](https://www.bithound.io/github/alexindigo/asynckit) + + + +AsyncKit provides harness for `parallel` and `serial` iterators over list of items represented by arrays or objects. +Optionally it accepts abort function (should be synchronously return by iterator for each item), and terminates left over jobs upon an error event. For specific iteration order built-in (`ascending` and `descending`) and custom sort helpers also supported, via `asynckit.serialOrdered` method. + +It ensures async operations to keep behavior more stable and prevent `Maximum call stack size exceeded` errors, from sync iterators. + +| compression | size | +| :----------------- | -------: | +| asynckit.js | 12.34 kB | +| asynckit.min.js | 4.11 kB | +| asynckit.min.js.gz | 1.47 kB | + + +## Install + +```sh +$ npm install --save asynckit +``` + +## Examples + +### Parallel Jobs + +Runs iterator over provided array in parallel. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will terminate rest of the active jobs (if abort function is provided) +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var parallel = require('asynckit').parallel + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] + , target = [] + ; + +parallel(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// async job accepts one element from the array +// and a callback function +function asyncJob(item, cb) +{ + // different delays (in ms) per item + var delay = item * 25; + + // pretend different jobs take different time to finish + // and not in consequential order + var timeoutId = setTimeout(function() { + target.push(item); + cb(null, item * 2); + }, delay); + + // allow to cancel "leftover" jobs upon error + // return function, invoking of which will abort this job + return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-array.js](test/test-parallel-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var parallel = require('asynckit/parallel') + , assert = require('assert') + ; + +var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } + , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } + , expectedTarget = [ 1, 1, 2, 4, 8, 16, 32, 64 ] + , expectedKeys = [ 'first', 'one', 'two', 'four', 'eight', 'sixteen', 'thirtyTwo', 'sixtyFour' ] + , target = [] + , keys = [] + ; + +parallel(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); + assert.deepEqual(keys, expectedKeys); +}); + +// supports full value, key, callback (shortcut) interface +function asyncJob(item, key, cb) +{ + // different delays (in ms) per item + var delay = item * 25; + + // pretend different jobs take different time to finish + // and not in consequential order + var timeoutId = setTimeout(function() { + keys.push(key); + target.push(item); + cb(null, item * 2); + }, delay); + + // allow to cancel "leftover" jobs upon error + // return function, invoking of which will abort this job + return clearTimeout.bind(null, timeoutId); +} +``` + +More examples could be found in [test/test-parallel-object.js](test/test-parallel-object.js). + +### Serial Jobs + +Runs iterator over provided array sequentially. Stores output in the `result` array, +on the matching positions. In unlikely event of an error from one of the jobs, +will not proceed to the rest of the items in the list +and return error along with salvaged data to the main callback function. + +#### Input Array + +```javascript +var serial = require('asynckit/serial') + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] + , target = [] + ; + +serial(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// extended interface (item, key, callback) +// also supported for arrays +function asyncJob(item, key, cb) +{ + target.push(key); + + // it will be automatically made async + // even it iterator "returns" in the same event loop + cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-array.js](test/test-serial-array.js). + +#### Input Object + +Also it supports named jobs, listed via object. + +```javascript +var serial = require('asynckit').serial + , assert = require('assert') + ; + +var source = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , expectedResult = [ 2, 2, 8, 32, 128, 64, 16, 4 ] + , expectedTarget = [ 0, 1, 2, 3, 4, 5, 6, 7 ] + , target = [] + ; + +var source = { first: 1, one: 1, four: 4, sixteen: 16, sixtyFour: 64, thirtyTwo: 32, eight: 8, two: 2 } + , expectedResult = { first: 2, one: 2, four: 8, sixteen: 32, sixtyFour: 128, thirtyTwo: 64, eight: 16, two: 4 } + , expectedTarget = [ 1, 1, 4, 16, 64, 32, 8, 2 ] + , target = [] + ; + + +serial(source, asyncJob, function(err, result) +{ + assert.deepEqual(result, expectedResult); + assert.deepEqual(target, expectedTarget); +}); + +// shortcut interface (item, callback) +// works for object as well as for the arrays +function asyncJob(item, cb) +{ + target.push(item); + + // it will be automatically made async + // even it iterator "returns" in the same event loop + cb(null, item * 2); +} +``` + +More examples could be found in [test/test-serial-object.js](test/test-serial-object.js). + +_Note: Since _object_ is an _unordered_ collection of properties, +it may produce unexpected results with sequential iterations. +Whenever order of the jobs' execution is important please use `serialOrdered` method._ + +### Ordered Serial Iterations + +TBD + +For example [compare-property](compare-property) package. + +### Streaming interface + +TBD + +## Want to Know More? + +More examples can be found in [test folder](test/). + +Or open an [issue](https://github.com/alexindigo/asynckit/issues) with questions and/or suggestions. + +## License + +AsyncKit is licensed under the MIT license. diff --git a/node_modules/asynckit/bench.js b/node_modules/asynckit/bench.js new file mode 100644 index 0000000..c612f1a --- /dev/null +++ b/node_modules/asynckit/bench.js @@ -0,0 +1,76 @@ +/* eslint no-console: "off" */ + +var asynckit = require('./') + , async = require('async') + , assert = require('assert') + , expected = 0 + ; + +var Benchmark = require('benchmark'); +var suite = new Benchmark.Suite; + +var source = []; +for (var z = 1; z < 100; z++) +{ + source.push(z); + expected += z; +} + +suite +// add tests + +.add('async.map', function(deferred) +{ + var total = 0; + + async.map(source, + function(i, cb) + { + setImmediate(function() + { + total += i; + cb(null, total); + }); + }, + function(err, result) + { + assert.ifError(err); + assert.equal(result[result.length - 1], expected); + deferred.resolve(); + }); +}, {'defer': true}) + + +.add('asynckit.parallel', function(deferred) +{ + var total = 0; + + asynckit.parallel(source, + function(i, cb) + { + setImmediate(function() + { + total += i; + cb(null, total); + }); + }, + function(err, result) + { + assert.ifError(err); + assert.equal(result[result.length - 1], expected); + deferred.resolve(); + }); +}, {'defer': true}) + + +// add listeners +.on('cycle', function(ev) +{ + console.log(String(ev.target)); +}) +.on('complete', function() +{ + console.log('Fastest is ' + this.filter('fastest').map('name')); +}) +// run async +.run({ 'async': true }); diff --git a/node_modules/asynckit/index.js b/node_modules/asynckit/index.js new file mode 100644 index 0000000..455f945 --- /dev/null +++ b/node_modules/asynckit/index.js @@ -0,0 +1,6 @@ +module.exports = +{ + parallel : require('./parallel.js'), + serial : require('./serial.js'), + serialOrdered : require('./serialOrdered.js') +}; diff --git a/node_modules/asynckit/lib/abort.js b/node_modules/asynckit/lib/abort.js new file mode 100644 index 0000000..114367e --- /dev/null +++ b/node_modules/asynckit/lib/abort.js @@ -0,0 +1,29 @@ +// API +module.exports = abort; + +/** + * Aborts leftover active jobs + * + * @param {object} state - current state object + */ +function abort(state) +{ + Object.keys(state.jobs).forEach(clean.bind(state)); + + // reset leftover jobs + state.jobs = {}; +} + +/** + * Cleans up leftover job by invoking abort function for the provided job id + * + * @this state + * @param {string|number} key - job id to abort + */ +function clean(key) +{ + if (typeof this.jobs[key] == 'function') + { + this.jobs[key](); + } +} diff --git a/node_modules/asynckit/lib/async.js b/node_modules/asynckit/lib/async.js new file mode 100644 index 0000000..7f1288a --- /dev/null +++ b/node_modules/asynckit/lib/async.js @@ -0,0 +1,34 @@ +var defer = require('./defer.js'); + +// API +module.exports = async; + +/** + * Runs provided callback asynchronously + * even if callback itself is not + * + * @param {function} callback - callback to invoke + * @returns {function} - augmented callback + */ +function async(callback) +{ + var isAsync = false; + + // check if async happened + defer(function() { isAsync = true; }); + + return function async_callback(err, result) + { + if (isAsync) + { + callback(err, result); + } + else + { + defer(function nextTick_callback() + { + callback(err, result); + }); + } + }; +} diff --git a/node_modules/asynckit/lib/defer.js b/node_modules/asynckit/lib/defer.js new file mode 100644 index 0000000..b67110c --- /dev/null +++ b/node_modules/asynckit/lib/defer.js @@ -0,0 +1,26 @@ +module.exports = defer; + +/** + * Runs provided function on next iteration of the event loop + * + * @param {function} fn - function to run + */ +function defer(fn) +{ + var nextTick = typeof setImmediate == 'function' + ? setImmediate + : ( + typeof process == 'object' && typeof process.nextTick == 'function' + ? process.nextTick + : null + ); + + if (nextTick) + { + nextTick(fn); + } + else + { + setTimeout(fn, 0); + } +} diff --git a/node_modules/asynckit/lib/iterate.js b/node_modules/asynckit/lib/iterate.js new file mode 100644 index 0000000..5d2839a --- /dev/null +++ b/node_modules/asynckit/lib/iterate.js @@ -0,0 +1,75 @@ +var async = require('./async.js') + , abort = require('./abort.js') + ; + +// API +module.exports = iterate; + +/** + * Iterates over each job object + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {object} state - current job status + * @param {function} callback - invoked when all elements processed + */ +function iterate(list, iterator, state, callback) +{ + // store current index + var key = state['keyedList'] ? state['keyedList'][state.index] : state.index; + + state.jobs[key] = runJob(iterator, key, list[key], function(error, output) + { + // don't repeat yourself + // skip secondary callbacks + if (!(key in state.jobs)) + { + return; + } + + // clean up jobs + delete state.jobs[key]; + + if (error) + { + // don't process rest of the results + // stop still active jobs + // and reset the list + abort(state); + } + else + { + state.results[key] = output; + } + + // return salvaged results + callback(error, state.results); + }); +} + +/** + * Runs iterator over provided job element + * + * @param {function} iterator - iterator to invoke + * @param {string|number} key - key/index of the element in the list of jobs + * @param {mixed} item - job description + * @param {function} callback - invoked after iterator is done with the job + * @returns {function|mixed} - job abort function or something else + */ +function runJob(iterator, key, item, callback) +{ + var aborter; + + // allow shortcut if iterator expects only two arguments + if (iterator.length == 2) + { + aborter = iterator(item, async(callback)); + } + // otherwise go with full three arguments + else + { + aborter = iterator(item, key, async(callback)); + } + + return aborter; +} diff --git a/node_modules/asynckit/lib/readable_asynckit.js b/node_modules/asynckit/lib/readable_asynckit.js new file mode 100644 index 0000000..78ad240 --- /dev/null +++ b/node_modules/asynckit/lib/readable_asynckit.js @@ -0,0 +1,91 @@ +var streamify = require('./streamify.js') + , defer = require('./defer.js') + ; + +// API +module.exports = ReadableAsyncKit; + +/** + * Base constructor for all streams + * used to hold properties/methods + */ +function ReadableAsyncKit() +{ + ReadableAsyncKit.super_.apply(this, arguments); + + // list of active jobs + this.jobs = {}; + + // add stream methods + this.destroy = destroy; + this._start = _start; + this._read = _read; +} + +/** + * Destroys readable stream, + * by aborting outstanding jobs + * + * @returns {void} + */ +function destroy() +{ + if (this.destroyed) + { + return; + } + + this.destroyed = true; + + if (typeof this.terminator == 'function') + { + this.terminator(); + } +} + +/** + * Starts provided jobs in async manner + * + * @private + */ +function _start() +{ + // first argument – runner function + var runner = arguments[0] + // take away first argument + , args = Array.prototype.slice.call(arguments, 1) + // second argument - input data + , input = args[0] + // last argument - result callback + , endCb = streamify.callback.call(this, args[args.length - 1]) + ; + + args[args.length - 1] = endCb; + // third argument - iterator + args[1] = streamify.iterator.call(this, args[1]); + + // allow time for proper setup + defer(function() + { + if (!this.destroyed) + { + this.terminator = runner.apply(null, args); + } + else + { + endCb(null, Array.isArray(input) ? [] : {}); + } + }.bind(this)); +} + + +/** + * Implement _read to comply with Readable streams + * Doesn't really make sense for flowing object mode + * + * @private + */ +function _read() +{ + +} diff --git a/node_modules/asynckit/lib/readable_parallel.js b/node_modules/asynckit/lib/readable_parallel.js new file mode 100644 index 0000000..5d2929f --- /dev/null +++ b/node_modules/asynckit/lib/readable_parallel.js @@ -0,0 +1,25 @@ +var parallel = require('../parallel.js'); + +// API +module.exports = ReadableParallel; + +/** + * Streaming wrapper to `asynckit.parallel` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableParallel(list, iterator, callback) +{ + if (!(this instanceof ReadableParallel)) + { + return new ReadableParallel(list, iterator, callback); + } + + // turn on object mode + ReadableParallel.super_.call(this, {objectMode: true}); + + this._start(parallel, list, iterator, callback); +} diff --git a/node_modules/asynckit/lib/readable_serial.js b/node_modules/asynckit/lib/readable_serial.js new file mode 100644 index 0000000..7822698 --- /dev/null +++ b/node_modules/asynckit/lib/readable_serial.js @@ -0,0 +1,25 @@ +var serial = require('../serial.js'); + +// API +module.exports = ReadableSerial; + +/** + * Streaming wrapper to `asynckit.serial` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerial(list, iterator, callback) +{ + if (!(this instanceof ReadableSerial)) + { + return new ReadableSerial(list, iterator, callback); + } + + // turn on object mode + ReadableSerial.super_.call(this, {objectMode: true}); + + this._start(serial, list, iterator, callback); +} diff --git a/node_modules/asynckit/lib/readable_serial_ordered.js b/node_modules/asynckit/lib/readable_serial_ordered.js new file mode 100644 index 0000000..3de89c4 --- /dev/null +++ b/node_modules/asynckit/lib/readable_serial_ordered.js @@ -0,0 +1,29 @@ +var serialOrdered = require('../serialOrdered.js'); + +// API +module.exports = ReadableSerialOrdered; +// expose sort helpers +module.exports.ascending = serialOrdered.ascending; +module.exports.descending = serialOrdered.descending; + +/** + * Streaming wrapper to `asynckit.serialOrdered` + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {stream.Readable#} + */ +function ReadableSerialOrdered(list, iterator, sortMethod, callback) +{ + if (!(this instanceof ReadableSerialOrdered)) + { + return new ReadableSerialOrdered(list, iterator, sortMethod, callback); + } + + // turn on object mode + ReadableSerialOrdered.super_.call(this, {objectMode: true}); + + this._start(serialOrdered, list, iterator, sortMethod, callback); +} diff --git a/node_modules/asynckit/lib/state.js b/node_modules/asynckit/lib/state.js new file mode 100644 index 0000000..cbea7ad --- /dev/null +++ b/node_modules/asynckit/lib/state.js @@ -0,0 +1,37 @@ +// API +module.exports = state; + +/** + * Creates initial state object + * for iteration over list + * + * @param {array|object} list - list to iterate over + * @param {function|null} sortMethod - function to use for keys sort, + * or `null` to keep them as is + * @returns {object} - initial state object + */ +function state(list, sortMethod) +{ + var isNamedList = !Array.isArray(list) + , initState = + { + index : 0, + keyedList: isNamedList || sortMethod ? Object.keys(list) : null, + jobs : {}, + results : isNamedList ? {} : [], + size : isNamedList ? Object.keys(list).length : list.length + } + ; + + if (sortMethod) + { + // sort array keys based on it's values + // sort object's keys just on own merit + initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) + { + return sortMethod(list[a], list[b]); + }); + } + + return initState; +} diff --git a/node_modules/asynckit/lib/streamify.js b/node_modules/asynckit/lib/streamify.js new file mode 100644 index 0000000..f56a1c9 --- /dev/null +++ b/node_modules/asynckit/lib/streamify.js @@ -0,0 +1,141 @@ +var async = require('./async.js'); + +// API +module.exports = { + iterator: wrapIterator, + callback: wrapCallback +}; + +/** + * Wraps iterators with long signature + * + * @this ReadableAsyncKit# + * @param {function} iterator - function to wrap + * @returns {function} - wrapped function + */ +function wrapIterator(iterator) +{ + var stream = this; + + return function(item, key, cb) + { + var aborter + , wrappedCb = async(wrapIteratorCallback.call(stream, cb, key)) + ; + + stream.jobs[key] = wrappedCb; + + // it's either shortcut (item, cb) + if (iterator.length == 2) + { + aborter = iterator(item, wrappedCb); + } + // or long format (item, key, cb) + else + { + aborter = iterator(item, key, wrappedCb); + } + + return aborter; + }; +} + +/** + * Wraps provided callback function + * allowing to execute snitch function before + * real callback + * + * @this ReadableAsyncKit# + * @param {function} callback - function to wrap + * @returns {function} - wrapped function + */ +function wrapCallback(callback) +{ + var stream = this; + + var wrapped = function(error, result) + { + return finisher.call(stream, error, result, callback); + }; + + return wrapped; +} + +/** + * Wraps provided iterator callback function + * makes sure snitch only called once, + * but passes secondary calls to the original callback + * + * @this ReadableAsyncKit# + * @param {function} callback - callback to wrap + * @param {number|string} key - iteration key + * @returns {function} wrapped callback + */ +function wrapIteratorCallback(callback, key) +{ + var stream = this; + + return function(error, output) + { + // don't repeat yourself + if (!(key in stream.jobs)) + { + callback(error, output); + return; + } + + // clean up jobs + delete stream.jobs[key]; + + return streamer.call(stream, error, {key: key, value: output}, callback); + }; +} + +/** + * Stream wrapper for iterator callback + * + * @this ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects iterator results + */ +function streamer(error, output, callback) +{ + if (error && !this.error) + { + this.error = error; + this.pause(); + this.emit('error', error); + // send back value only, as expected + callback(error, output && output.value); + return; + } + + // stream stuff + this.push(output); + + // back to original track + // send back value only, as expected + callback(error, output && output.value); +} + +/** + * Stream wrapper for finishing callback + * + * @this ReadableAsyncKit# + * @param {mixed} error - error response + * @param {mixed} output - iterator output + * @param {function} callback - callback that expects final results + */ +function finisher(error, output, callback) +{ + // signal end of the stream + // only for successfully finished streams + if (!error) + { + this.push(null); + } + + // back to original track + callback(error, output); +} diff --git a/node_modules/asynckit/lib/terminator.js b/node_modules/asynckit/lib/terminator.js new file mode 100644 index 0000000..d6eb992 --- /dev/null +++ b/node_modules/asynckit/lib/terminator.js @@ -0,0 +1,29 @@ +var abort = require('./abort.js') + , async = require('./async.js') + ; + +// API +module.exports = terminator; + +/** + * Terminates jobs in the attached state context + * + * @this AsyncKitState# + * @param {function} callback - final callback to invoke after termination + */ +function terminator(callback) +{ + if (!Object.keys(this.jobs).length) + { + return; + } + + // fast forward iteration index + this.index = this.size; + + // abort jobs + abort(this); + + // send back results we have so far + async(callback)(null, this.results); +} diff --git a/node_modules/asynckit/package.json b/node_modules/asynckit/package.json new file mode 100644 index 0000000..51147d6 --- /dev/null +++ b/node_modules/asynckit/package.json @@ -0,0 +1,63 @@ +{ + "name": "asynckit", + "version": "0.4.0", + "description": "Minimal async jobs utility library, with streams support", + "main": "index.js", + "scripts": { + "clean": "rimraf coverage", + "lint": "eslint *.js lib/*.js test/*.js", + "test": "istanbul cover --reporter=json tape -- 'test/test-*.js' | tap-spec", + "win-test": "tape test/test-*.js", + "browser": "browserify -t browserify-istanbul test/lib/browserify_adjustment.js test/test-*.js | obake --coverage | tap-spec", + "report": "istanbul report", + "size": "browserify index.js | size-table asynckit", + "debug": "tape test/test-*.js" + }, + "pre-commit": [ + "clean", + "lint", + "test", + "browser", + "report", + "size" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/alexindigo/asynckit.git" + }, + "keywords": [ + "async", + "jobs", + "parallel", + "serial", + "iterator", + "array", + "object", + "stream", + "destroy", + "terminate", + "abort" + ], + "author": "Alex Indigo ", + "license": "MIT", + "bugs": { + "url": "https://github.com/alexindigo/asynckit/issues" + }, + "homepage": "https://github.com/alexindigo/asynckit#readme", + "devDependencies": { + "browserify": "^13.0.0", + "browserify-istanbul": "^2.0.0", + "coveralls": "^2.11.9", + "eslint": "^2.9.0", + "istanbul": "^0.4.3", + "obake": "^0.1.2", + "phantomjs-prebuilt": "^2.1.7", + "pre-commit": "^1.1.3", + "reamde": "^1.1.0", + "rimraf": "^2.5.2", + "size-table": "^0.2.0", + "tap-spec": "^4.1.1", + "tape": "^4.5.1" + }, + "dependencies": {} +} diff --git a/node_modules/asynckit/parallel.js b/node_modules/asynckit/parallel.js new file mode 100644 index 0000000..3c50344 --- /dev/null +++ b/node_modules/asynckit/parallel.js @@ -0,0 +1,43 @@ +var iterate = require('./lib/iterate.js') + , initState = require('./lib/state.js') + , terminator = require('./lib/terminator.js') + ; + +// Public API +module.exports = parallel; + +/** + * Runs iterator over provided array elements in parallel + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function parallel(list, iterator, callback) +{ + var state = initState(list); + + while (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, function(error, result) + { + if (error) + { + callback(error, result); + return; + } + + // looks like it's the last one + if (Object.keys(state.jobs).length === 0) + { + callback(null, state.results); + return; + } + }); + + state.index++; + } + + return terminator.bind(state, callback); +} diff --git a/node_modules/asynckit/serial.js b/node_modules/asynckit/serial.js new file mode 100644 index 0000000..6cd949a --- /dev/null +++ b/node_modules/asynckit/serial.js @@ -0,0 +1,17 @@ +var serialOrdered = require('./serialOrdered.js'); + +// Public API +module.exports = serial; + +/** + * Runs iterator over provided array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serial(list, iterator, callback) +{ + return serialOrdered(list, iterator, null, callback); +} diff --git a/node_modules/asynckit/serialOrdered.js b/node_modules/asynckit/serialOrdered.js new file mode 100644 index 0000000..607eafe --- /dev/null +++ b/node_modules/asynckit/serialOrdered.js @@ -0,0 +1,75 @@ +var iterate = require('./lib/iterate.js') + , initState = require('./lib/state.js') + , terminator = require('./lib/terminator.js') + ; + +// Public API +module.exports = serialOrdered; +// sorting helpers +module.exports.ascending = ascending; +module.exports.descending = descending; + +/** + * Runs iterator over provided sorted array elements in series + * + * @param {array|object} list - array or object (named list) to iterate over + * @param {function} iterator - iterator to run + * @param {function} sortMethod - custom sort function + * @param {function} callback - invoked when all elements processed + * @returns {function} - jobs terminator + */ +function serialOrdered(list, iterator, sortMethod, callback) +{ + var state = initState(list, sortMethod); + + iterate(list, iterator, state, function iteratorHandler(error, result) + { + if (error) + { + callback(error, result); + return; + } + + state.index++; + + // are we there yet? + if (state.index < (state['keyedList'] || list).length) + { + iterate(list, iterator, state, iteratorHandler); + return; + } + + // done here + callback(null, state.results); + }); + + return terminator.bind(state, callback); +} + +/* + * -- Sort methods + */ + +/** + * sort helper to sort array elements in ascending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function ascending(a, b) +{ + return a < b ? -1 : a > b ? 1 : 0; +} + +/** + * sort helper to sort array elements in descending order + * + * @param {mixed} a - an item to compare + * @param {mixed} b - an item to compare + * @returns {number} - comparison result + */ +function descending(a, b) +{ + return -1 * ascending(a, b); +} diff --git a/node_modules/asynckit/stream.js b/node_modules/asynckit/stream.js new file mode 100644 index 0000000..d43465f --- /dev/null +++ b/node_modules/asynckit/stream.js @@ -0,0 +1,21 @@ +var inherits = require('util').inherits + , Readable = require('stream').Readable + , ReadableAsyncKit = require('./lib/readable_asynckit.js') + , ReadableParallel = require('./lib/readable_parallel.js') + , ReadableSerial = require('./lib/readable_serial.js') + , ReadableSerialOrdered = require('./lib/readable_serial_ordered.js') + ; + +// API +module.exports = +{ + parallel : ReadableParallel, + serial : ReadableSerial, + serialOrdered : ReadableSerialOrdered, +}; + +inherits(ReadableAsyncKit, Readable); + +inherits(ReadableParallel, ReadableAsyncKit); +inherits(ReadableSerial, ReadableAsyncKit); +inherits(ReadableSerialOrdered, ReadableAsyncKit); diff --git a/node_modules/axios/CHANGELOG.md b/node_modules/axios/CHANGELOG.md new file mode 100644 index 0000000..d06400b --- /dev/null +++ b/node_modules/axios/CHANGELOG.md @@ -0,0 +1,1295 @@ +# Changelog + +## [1.12.2](https://github.com/axios/axios/compare/v1.12.1...v1.12.2) (2025-09-14) + + +### Bug Fixes + +* **fetch:** use current global fetch instead of cached one when env fetch is not specified to keep MSW support; ([#7030](https://github.com/axios/axios/issues/7030)) ([cf78825](https://github.com/axios/axios/commit/cf78825e1229b60d1629ad0bbc8a752ff43c3f53)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+247/-16 (#7030 #7022 #7024 )") +- avatar [Noritaka Kobayashi](https://github.com/noritaka1166 "+2/-6 (#7028 #7029 )") + +## [1.12.1](https://github.com/axios/axios/compare/v1.12.0...v1.12.1) (2025-09-12) + + +### Bug Fixes + +* **types:** fixed env config types; ([#7020](https://github.com/axios/axios/issues/7020)) ([b5f26b7](https://github.com/axios/axios/commit/b5f26b75bdd9afa95016fb67d0cab15fc74cbf05)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+10/-4 (#7020 )") + +# [1.12.0](https://github.com/axios/axios/compare/v1.11.0...v1.12.0) (2025-09-11) + + +### Bug Fixes + +* adding build artifacts ([9ec86de](https://github.com/axios/axios/commit/9ec86de257bfa33856571036279169f385ed92bd)) +* dont add dist on release ([a2edc36](https://github.com/axios/axios/commit/a2edc3606a4f775d868a67bb3461ff18ce7ecd11)) +* **fetch-adapter:** set correct Content-Type for Node FormData ([#6998](https://github.com/axios/axios/issues/6998)) ([a9f47af](https://github.com/axios/axios/commit/a9f47afbf3224d2ca987dbd8188789c7ea853c5d)) +* **node:** enforce maxContentLength for data: URLs ([#7011](https://github.com/axios/axios/issues/7011)) ([945435f](https://github.com/axios/axios/commit/945435fc51467303768202250debb8d4ae892593)) +* package exports ([#5627](https://github.com/axios/axios/issues/5627)) ([aa78ac2](https://github.com/axios/axios/commit/aa78ac23fc9036163308c0f6bd2bb885e7af3f36)) +* **params:** removing '[' and ']' from URL encode exclude characters ([#3316](https://github.com/axios/axios/issues/3316)) ([#5715](https://github.com/axios/axios/issues/5715)) ([6d84189](https://github.com/axios/axios/commit/6d84189349c43b1dcdd977b522610660cc4c7042)) +* release pr run ([fd7f404](https://github.com/axios/axios/commit/fd7f404488b2c4f238c2fbe635b58026a634bfd2)) +* **types:** change the type guard on isCancel ([#5595](https://github.com/axios/axios/issues/5595)) ([0dbb7fd](https://github.com/axios/axios/commit/0dbb7fd4f61dc568498cd13a681fa7f907d6ec7e)) + + +### Features + +* **adapter:** surface low‑level network error details; attach original error via cause ([#6982](https://github.com/axios/axios/issues/6982)) ([78b290c](https://github.com/axios/axios/commit/78b290c57c978ed2ab420b90d97350231c9e5d74)) +* **fetch:** add fetch, Request, Response env config variables for the adapter; ([#7003](https://github.com/axios/axios/issues/7003)) ([c959ff2](https://github.com/axios/axios/commit/c959ff29013a3bc90cde3ac7ea2d9a3f9c08974b)) +* support reviver on JSON.parse ([#5926](https://github.com/axios/axios/issues/5926)) ([2a97634](https://github.com/axios/axios/commit/2a9763426e43d996fd60d01afe63fa6e1f5b4fca)), closes [#5924](https://github.com/axios/axios/issues/5924) +* **types:** extend AxiosResponse interface to include custom headers type ([#6782](https://github.com/axios/axios/issues/6782)) ([7960d34](https://github.com/axios/axios/commit/7960d34eded2de66ffd30b4687f8da0e46c4903e)) + +### Contributors to this release + +- avatar [Willian Agostini](https://github.com/WillianAgostini "+132/-16760 (#7002 #5926 #6782 )") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+4263/-293 (#7006 #7003 )") +- avatar [khani](https://github.com/mkhani01 "+111/-15 (#6982 )") +- avatar [Ameer Assadi](https://github.com/AmeerAssadi "+123/-0 (#7011 )") +- avatar [Emiedonmokumo Dick-Boro](https://github.com/emiedonmokumo "+55/-35 (#6998 )") +- avatar [Zeroday BYTE](https://github.com/opsysdebug "+8/-8 (#6980 )") +- avatar [Jason Saayman](https://github.com/jasonsaayman "+7/-7 (#6985 #6985 )") +- avatar [최예찬](https://github.com/HealGaren "+5/-7 (#5715 )") +- avatar [Gligor Kotushevski](https://github.com/gligorkot "+3/-1 (#5627 )") +- avatar [Aleksandar Dimitrov](https://github.com/adimit "+2/-1 (#5595 )") + +# [1.11.0](https://github.com/axios/axios/compare/v1.10.0...v1.11.0) (2025-07-22) + + +### Bug Fixes + +* form-data npm pakcage ([#6970](https://github.com/axios/axios/issues/6970)) ([e72c193](https://github.com/axios/axios/commit/e72c193722530db538b19e5ddaaa4544d226b253)) +* prevent RangeError when using large Buffers ([#6961](https://github.com/axios/axios/issues/6961)) ([a2214ca](https://github.com/axios/axios/commit/a2214ca1bc60540baf2c80573cea3a0ff91ba9d1)) +* **types:** resolve type discrepancies between ESM and CJS TypeScript declaration files ([#6956](https://github.com/axios/axios/issues/6956)) ([8517aa1](https://github.com/axios/axios/commit/8517aa16f8d082fc1d5309c642220fa736159110)) + +### Contributors to this release + +- avatar [izzy goldman](https://github.com/izzygld "+186/-93 (#6970 )") +- avatar [Manish Sahani](https://github.com/manishsahanidev "+70/-0 (#6961 )") +- avatar [Noritaka Kobayashi](https://github.com/noritaka1166 "+12/-10 (#6938 #6939 )") +- avatar [James Nail](https://github.com/jrnail23 "+13/-2 (#6956 )") +- avatar [Tejaswi1305](https://github.com/Tejaswi1305 "+1/-1 (#6894 )") + +# [1.10.0](https://github.com/axios/axios/compare/v1.9.0...v1.10.0) (2025-06-14) + + +### Bug Fixes + +* **adapter:** pass fetchOptions to fetch function ([#6883](https://github.com/axios/axios/issues/6883)) ([0f50af8](https://github.com/axios/axios/commit/0f50af8e076b7fb403844789bd5e812dedcaf4ed)) +* **form-data:** convert boolean values to strings in FormData serialization ([#6917](https://github.com/axios/axios/issues/6917)) ([5064b10](https://github.com/axios/axios/commit/5064b108de336ff34862650709761b8a96d26be0)) +* **package:** add module entry point for React Native; ([#6933](https://github.com/axios/axios/issues/6933)) ([3d343b8](https://github.com/axios/axios/commit/3d343b86dc4fd0eea0987059c5af04327c7ae304)) + + +### Features + +* **types:** improved fetchOptions interface ([#6867](https://github.com/axios/axios/issues/6867)) ([63f1fce](https://github.com/axios/axios/commit/63f1fce233009f5db1abf2586c145825ac98c3d7)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+30/-19 (#6933 #6920 #6893 #6892 )") +- avatar [Noritaka Kobayashi](https://github.com/noritaka1166 "+2/-6 (#6922 #6923 )") +- avatar [Dimitrios Lazanas](https://github.com/dimitry-lzs "+4/-0 (#6917 )") +- avatar [Adrian Knapp](https://github.com/AdrianKnapp "+2/-2 (#6867 )") +- avatar [Howie Zhao](https://github.com/howiezhao "+3/-1 (#6872 )") +- avatar [Uhyeon Park](https://github.com/warpdev "+1/-1 (#6883 )") +- avatar [Sampo Silvennoinen](https://github.com/stscoundrel "+1/-1 (#6913 )") + +# [1.9.0](https://github.com/axios/axios/compare/v1.8.4...v1.9.0) (2025-04-24) + + +### Bug Fixes + +* **core:** fix the Axios constructor implementation to treat the config argument as optional; ([#6881](https://github.com/axios/axios/issues/6881)) ([6c5d4cd](https://github.com/axios/axios/commit/6c5d4cd69286868059c5e52d45085cb9a894a983)) +* **fetch:** fixed ERR_NETWORK mapping for Safari browsers; ([#6767](https://github.com/axios/axios/issues/6767)) ([dfe8411](https://github.com/axios/axios/commit/dfe8411c9a082c3d068bdd1f8d6e73054f387f45)) +* **headers:** allow iterable objects to be a data source for the set method; ([#6873](https://github.com/axios/axios/issues/6873)) ([1b1f9cc](https://github.com/axios/axios/commit/1b1f9ccdc15f1ea745160ec9a5223de9db4673bc)) +* **headers:** fix `getSetCookie` by using 'get' method for caseless access; ([#6874](https://github.com/axios/axios/issues/6874)) ([d4f7df4](https://github.com/axios/axios/commit/d4f7df4b304af8b373488fdf8e830793ff843eb9)) +* **headers:** fixed support for setting multiple header values from an iterated source; ([#6885](https://github.com/axios/axios/issues/6885)) ([f7a3b5e](https://github.com/axios/axios/commit/f7a3b5e0f7e5e127b97defa92a132fbf1b55cf15)) +* **http:** send minimal end multipart boundary ([#6661](https://github.com/axios/axios/issues/6661)) ([987d2e2](https://github.com/axios/axios/commit/987d2e2dd3b362757550f36eab875e60640b6ddc)) +* **types:** fix autocomplete for adapter config ([#6855](https://github.com/axios/axios/issues/6855)) ([e61a893](https://github.com/axios/axios/commit/e61a8934d8f94dd429a2f309b48c67307c700df0)) + + +### Features + +* **AxiosHeaders:** add getSetCookie method to retrieve set-cookie headers values ([#5707](https://github.com/axios/axios/issues/5707)) ([80ea756](https://github.com/axios/axios/commit/80ea756e72bcf53110fa792f5d7ab76e8b11c996)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+200/-34 (#6890 #6889 #6888 #6885 #6881 #6767 #6874 #6873 )") +- avatar [Jay](https://github.com/jasonsaayman "+26/-1 ()") +- avatar [Willian Agostini](https://github.com/WillianAgostini "+21/-0 (#5707 )") +- avatar [George Cheng](https://github.com/Gerhut "+3/-3 (#5096 )") +- avatar [FatahChan](https://github.com/FatahChan "+2/-2 (#6855 )") +- avatar [Ionuț G. Stan](https://github.com/igstan "+1/-1 (#6661 )") + +## [1.8.4](https://github.com/axios/axios/compare/v1.8.3...v1.8.4) (2025-03-19) + + +### Bug Fixes + +* **buildFullPath:** handle `allowAbsoluteUrls: false` without `baseURL` ([#6833](https://github.com/axios/axios/issues/6833)) ([f10c2e0](https://github.com/axios/axios/commit/f10c2e0de7fde0051f848609a29c2906d0caa1d9)) + +### Contributors to this release + +- avatar [Marc Hassan](https://github.com/mhassan1 "+5/-1 (#6833 )") + +## [1.8.3](https://github.com/axios/axios/compare/v1.8.2...v1.8.3) (2025-03-10) + + +### Bug Fixes + +* add missing type for allowAbsoluteUrls ([#6818](https://github.com/axios/axios/issues/6818)) ([10fa70e](https://github.com/axios/axios/commit/10fa70ef14fe39558b15a179f0e82f5f5e5d11b2)) +* **xhr/fetch:** pass `allowAbsoluteUrls` to `buildFullPath` in `xhr` and `fetch` adapters ([#6814](https://github.com/axios/axios/issues/6814)) ([ec159e5](https://github.com/axios/axios/commit/ec159e507bdf08c04ba1a10fe7710094e9e50ec9)) + +### Contributors to this release + +- avatar [Ashcon Partovi](https://github.com/Electroid "+6/-0 (#6811 )") +- avatar [StefanBRas](https://github.com/StefanBRas "+4/-0 (#6818 )") +- avatar [Marc Hassan](https://github.com/mhassan1 "+2/-2 (#6814 )") + +## [1.8.2](https://github.com/axios/axios/compare/v1.8.1...v1.8.2) (2025-03-07) + + +### Bug Fixes + +* **http-adapter:** add allowAbsoluteUrls to path building ([#6810](https://github.com/axios/axios/issues/6810)) ([fb8eec2](https://github.com/axios/axios/commit/fb8eec214ce7744b5ca787f2c3b8339b2f54b00f)) + +### Contributors to this release + +- avatar [Fasoro-Joseph Alexander](https://github.com/lexcorp16 "+1/-1 (#6810 )") + +## [1.8.1](https://github.com/axios/axios/compare/v1.8.0...v1.8.1) (2025-02-26) + + +### Bug Fixes + +* **utils:** move `generateString` to platform utils to avoid importing crypto module into client builds; ([#6789](https://github.com/axios/axios/issues/6789)) ([36a5a62](https://github.com/axios/axios/commit/36a5a620bec0b181451927f13ac85b9888b86cec)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+51/-47 (#6789 )") + +# [1.8.0](https://github.com/axios/axios/compare/v1.7.9...v1.8.0) (2025-02-25) + + +### Bug Fixes + +* **examples:** application crashed when navigating examples in browser ([#5938](https://github.com/axios/axios/issues/5938)) ([1260ded](https://github.com/axios/axios/commit/1260ded634ec101dd5ed05d3b70f8e8f899dba6c)) +* missing word in SUPPORT_QUESTION.yml ([#6757](https://github.com/axios/axios/issues/6757)) ([1f890b1](https://github.com/axios/axios/commit/1f890b13f2c25a016f3c84ae78efb769f244133e)) +* **utils:** replace getRandomValues with crypto module ([#6788](https://github.com/axios/axios/issues/6788)) ([23a25af](https://github.com/axios/axios/commit/23a25af0688d1db2c396deb09229d2271cc24f6c)) + + +### Features + +* Add config for ignoring absolute URLs ([#5902](https://github.com/axios/axios/issues/5902)) ([#6192](https://github.com/axios/axios/issues/6192)) ([32c7bcc](https://github.com/axios/axios/commit/32c7bcc0f233285ba27dec73a4b1e81fb7a219b3)) + + +### Reverts + +* Revert "chore: expose fromDataToStream to be consumable (#6731)" (#6732) ([1317261](https://github.com/axios/axios/commit/1317261125e9c419fe9f126867f64d28f9c1efda)), closes [#6731](https://github.com/axios/axios/issues/6731) [#6732](https://github.com/axios/axios/issues/6732) + + +### BREAKING CHANGES + +* code relying on the above will now combine the URLs instead of prefer request URL + +* feat: add config option for allowing absolute URLs + +* fix: add default value for allowAbsoluteUrls in buildFullPath + +* fix: typo in flow control when setting allowAbsoluteUrls + +### Contributors to this release + +- avatar [Michael Toscano](https://github.com/GethosTheWalrus "+42/-8 (#6192 )") +- avatar [Willian Agostini](https://github.com/WillianAgostini "+26/-3 (#6788 #6777 )") +- avatar [Naron](https://github.com/naronchen "+27/-0 (#5901 )") +- avatar [shravan || श्रvan](https://github.com/shravan20 "+7/-3 (#6116 )") +- avatar [Justin Dhillon](https://github.com/justindhillon "+0/-7 (#6312 )") +- avatar [yionr](https://github.com/yionr "+5/-1 (#6129 )") +- avatar [Shin'ya Ueoka](https://github.com/ueokande "+3/-3 (#5935 )") +- avatar [Dan Dascalescu](https://github.com/dandv "+3/-3 (#5908 #6757 )") +- avatar [Nitin Ramnani](https://github.com/NitinRamnani "+2/-2 (#5938 )") +- avatar [Shay Molcho](https://github.com/shaymolcho "+2/-2 (#6770 )") +- avatar [Jay](https://github.com/jasonsaayman "+0/-3 (#6732 )") +- fancy45daddy +- avatar [Habip Akyol](https://github.com/habipakyol "+1/-1 (#6030 )") +- avatar [Bailey Lissington](https://github.com/llamington "+1/-1 (#6771 )") +- avatar [Bernardo da Eira Duarte](https://github.com/bernardoduarte "+1/-1 (#6480 )") +- avatar [Shivam Batham](https://github.com/Shivam-Batham "+1/-1 (#5949 )") +- avatar [Lipin Kariappa](https://github.com/lipinnnnn "+1/-1 (#5936 )") + +## [1.7.9](https://github.com/axios/axios/compare/v1.7.8...v1.7.9) (2024-12-04) + + +### Reverts + +* Revert "fix(types): export CJS types from ESM (#6218)" (#6729) ([c44d2f2](https://github.com/axios/axios/commit/c44d2f2316ad289b38997657248ba10de11deb6c)), closes [#6218](https://github.com/axios/axios/issues/6218) [#6729](https://github.com/axios/axios/issues/6729) + +### Contributors to this release + +- avatar [Jay](https://github.com/jasonsaayman "+596/-108 (#6729 )") + +## [1.7.8](https://github.com/axios/axios/compare/v1.7.7...v1.7.8) (2024-11-25) + + +### Bug Fixes + +* allow passing a callback as paramsSerializer to buildURL ([#6680](https://github.com/axios/axios/issues/6680)) ([eac4619](https://github.com/axios/axios/commit/eac4619fe2e0926e876cd260ee21e3690381dbb5)) +* **core:** fixed config merging bug ([#6668](https://github.com/axios/axios/issues/6668)) ([5d99fe4](https://github.com/axios/axios/commit/5d99fe4491202a6268c71e5dcc09192359d73cea)) +* fixed width form to not shrink after 'Send Request' button is clicked ([#6644](https://github.com/axios/axios/issues/6644)) ([7ccd5fd](https://github.com/axios/axios/commit/7ccd5fd42402102d38712c32707bf055be72ab54)) +* **http:** add support for File objects as payload in http adapter ([#6588](https://github.com/axios/axios/issues/6588)) ([#6605](https://github.com/axios/axios/issues/6605)) ([6841d8d](https://github.com/axios/axios/commit/6841d8d18ddc71cc1bd202ffcfddb3f95622eef3)) +* **http:** fixed proxy-from-env module import ([#5222](https://github.com/axios/axios/issues/5222)) ([12b3295](https://github.com/axios/axios/commit/12b32957f1258aee94ef859809ed39f8f88f9dfa)) +* **http:** use `globalThis.TextEncoder` when available ([#6634](https://github.com/axios/axios/issues/6634)) ([df956d1](https://github.com/axios/axios/commit/df956d18febc9100a563298dfdf0f102c3d15410)) +* ios11 breaks when build ([#6608](https://github.com/axios/axios/issues/6608)) ([7638952](https://github.com/axios/axios/commit/763895270f7b50c7c780c3c9807ae8635de952cd)) +* **types:** add missing types for mergeConfig function ([#6590](https://github.com/axios/axios/issues/6590)) ([00de614](https://github.com/axios/axios/commit/00de614cd07b7149af335e202aef0e076c254f49)) +* **types:** export CJS types from ESM ([#6218](https://github.com/axios/axios/issues/6218)) ([c71811b](https://github.com/axios/axios/commit/c71811b00f2fcff558e4382ba913bdac4ad7200e)) +* updated stream aborted error message to be more clear ([#6615](https://github.com/axios/axios/issues/6615)) ([cc3217a](https://github.com/axios/axios/commit/cc3217a612024d83a663722a56d7a98d8759c6d5)) +* use URL API instead of DOM to fix a potential vulnerability warning; ([#6714](https://github.com/axios/axios/issues/6714)) ([0a8d6e1](https://github.com/axios/axios/commit/0a8d6e19da5b9899a2abafaaa06a75ee548597db)) + +### Contributors to this release + +- avatar [Remco Haszing](https://github.com/remcohaszing "+108/-596 (#6218 )") +- avatar [Jay](https://github.com/jasonsaayman "+281/-19 (#6640 #6619 )") +- avatar [Aayush Yadav](https://github.com/aayushyadav020 "+124/-111 (#6617 )") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+12/-65 (#6714 )") +- avatar [Ell Bradshaw](https://github.com/cincodenada "+29/-0 (#6489 )") +- avatar [Amit Saini](https://github.com/amitsainii "+13/-3 (#5237 )") +- avatar [Tommaso Paulon](https://github.com/guuido "+14/-1 (#6680 )") +- avatar [Akki](https://github.com/Aakash-Rana "+5/-5 (#6668 )") +- avatar [Sampo Silvennoinen](https://github.com/stscoundrel "+3/-3 (#6633 )") +- avatar [Kasper Isager Dalsgarð](https://github.com/kasperisager "+2/-2 (#6634 )") +- avatar [Christian Clauss](https://github.com/cclauss "+4/-0 (#6683 )") +- avatar [Pavan Welihinda](https://github.com/pavan168 "+2/-2 (#5222 )") +- avatar [Taylor Flatt](https://github.com/taylorflatt "+2/-2 (#6615 )") +- avatar [Kenzo Wada](https://github.com/Kenzo-Wada "+2/-2 (#6608 )") +- avatar [Ngole Lawson](https://github.com/echelonnought "+3/-0 (#6644 )") +- avatar [Haven](https://github.com/Baoyx007 "+3/-0 (#6590 )") +- avatar [Shrivali Dutt](https://github.com/shrivalidutt "+1/-1 (#6637 )") +- avatar [Henco Appel](https://github.com/hencoappel "+1/-1 (#6605 )") + +## [1.7.7](https://github.com/axios/axios/compare/v1.7.6...v1.7.7) (2024-08-31) + + +### Bug Fixes + +* **fetch:** fix stream handling in Safari by fallback to using a stream reader instead of an async iterator; ([#6584](https://github.com/axios/axios/issues/6584)) ([d198085](https://github.com/axios/axios/commit/d1980854fee1765cd02fa0787adf5d6e34dd9dcf)) +* **http:** fixed support for IPv6 literal strings in url ([#5731](https://github.com/axios/axios/issues/5731)) ([364993f](https://github.com/axios/axios/commit/364993f0d8bc6e0e06f76b8a35d2d0a35cab054c)) + +### Contributors to this release + +- avatar [Rishi556](https://github.com/Rishi556 "+39/-1 (#5731 )") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+27/-7 (#6584 )") + +## [1.7.6](https://github.com/axios/axios/compare/v1.7.5...v1.7.6) (2024-08-30) + + +### Bug Fixes + +* **fetch:** fix content length calculation for FormData payload; ([#6524](https://github.com/axios/axios/issues/6524)) ([085f568](https://github.com/axios/axios/commit/085f56861a83e9ac02c140ad9d68dac540dfeeaa)) +* **fetch:** optimize signals composing logic; ([#6582](https://github.com/axios/axios/issues/6582)) ([df9889b](https://github.com/axios/axios/commit/df9889b83c2cc37e9e6189675a73ab70c60f031f)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+98/-46 (#6582 )") +- avatar [Jacques Germishuys](https://github.com/jacquesg "+5/-1 (#6524 )") +- avatar [kuroino721](https://github.com/kuroino721 "+3/-1 (#6575 )") + +## [1.7.5](https://github.com/axios/axios/compare/v1.7.4...v1.7.5) (2024-08-23) + + +### Bug Fixes + +* **adapter:** fix undefined reference to hasBrowserEnv ([#6572](https://github.com/axios/axios/issues/6572)) ([7004707](https://github.com/axios/axios/commit/7004707c4180b416341863bd86913fe4fc2f1df1)) +* **core:** add the missed implementation of AxiosError#status property; ([#6573](https://github.com/axios/axios/issues/6573)) ([6700a8a](https://github.com/axios/axios/commit/6700a8adac06942205f6a7a21421ecb36c4e0852)) +* **core:** fix `ReferenceError: navigator is not defined` for custom environments; ([#6567](https://github.com/axios/axios/issues/6567)) ([fed1a4b](https://github.com/axios/axios/commit/fed1a4b2d78ed4a588c84e09d32749ed01dc2794)) +* **fetch:** fix credentials handling in Cloudflare workers ([#6533](https://github.com/axios/axios/issues/6533)) ([550d885](https://github.com/axios/axios/commit/550d885eb90fd156add7b93bbdc54d30d2f9a98d)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+187/-83 (#6573 #6567 #6566 #6564 #6563 #6557 #6556 #6555 #6554 #6552 )") +- avatar [Antonin Bas](https://github.com/antoninbas "+6/-6 (#6572 )") +- avatar [Hans Otto Wirtz](https://github.com/hansottowirtz "+4/-1 (#6533 )") + +## [1.7.4](https://github.com/axios/axios/compare/v1.7.3...v1.7.4) (2024-08-13) + + +### Bug Fixes + +* **sec:** CVE-2024-39338 ([#6539](https://github.com/axios/axios/issues/6539)) ([#6543](https://github.com/axios/axios/issues/6543)) ([6b6b605](https://github.com/axios/axios/commit/6b6b605eaf73852fb2dae033f1e786155959de3a)) +* **sec:** disregard protocol-relative URL to remediate SSRF ([#6539](https://github.com/axios/axios/issues/6539)) ([07a661a](https://github.com/axios/axios/commit/07a661a2a6b9092c4aa640dcc7f724ec5e65bdda)) + +### Contributors to this release + +- avatar [Lev Pachmanov](https://github.com/levpachmanov "+47/-11 (#6543 )") +- avatar [Đỗ Trọng Hải](https://github.com/hainenber "+49/-4 (#6539 )") + +## [1.7.3](https://github.com/axios/axios/compare/v1.7.2...v1.7.3) (2024-08-01) + + +### Bug Fixes + +* **adapter:** fix progress event emitting; ([#6518](https://github.com/axios/axios/issues/6518)) ([e3c76fc](https://github.com/axios/axios/commit/e3c76fc9bdd03aa4d98afaf211df943e2031453f)) +* **fetch:** fix withCredentials request config ([#6505](https://github.com/axios/axios/issues/6505)) ([85d4d0e](https://github.com/axios/axios/commit/85d4d0ea0aae91082f04e303dec46510d1b4e787)) +* **xhr:** return original config on errors from XHR adapter ([#6515](https://github.com/axios/axios/issues/6515)) ([8966ee7](https://github.com/axios/axios/commit/8966ee7ea62ecbd6cfb39a905939bcdab5cf6388)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+211/-159 (#6518 #6519 )") +- avatar [Valerii Sidorenko](https://github.com/ValeraS "+3/-3 (#6515 )") +- avatar [prianYu](https://github.com/prianyu "+2/-2 (#6505 )") + +## [1.7.2](https://github.com/axios/axios/compare/v1.7.1...v1.7.2) (2024-05-21) + + +### Bug Fixes + +* **fetch:** enhance fetch API detection; ([#6413](https://github.com/axios/axios/issues/6413)) ([4f79aef](https://github.com/axios/axios/commit/4f79aef81b7c4644328365bfc33acf0a9ef595bc)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+3/-3 (#6413 )") + +## [1.7.1](https://github.com/axios/axios/compare/v1.7.0...v1.7.1) (2024-05-20) + + +### Bug Fixes + +* **fetch:** fixed ReferenceError issue when TextEncoder is not available in the environment; ([#6410](https://github.com/axios/axios/issues/6410)) ([733f15f](https://github.com/axios/axios/commit/733f15fe5bd2d67e1fadaee82e7913b70d45dc5e)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+14/-9 (#6410 )") + +# [1.7.0](https://github.com/axios/axios/compare/v1.7.0-beta.2...v1.7.0) (2024-05-19) + + +### Features + +* **adapter:** add fetch adapter; ([#6371](https://github.com/axios/axios/issues/6371)) ([a3ff99b](https://github.com/axios/axios/commit/a3ff99b59d8ec2ab5dd049e68c043617a4072e42)) + +### Bug Fixes + +* **core/axios:** handle un-writable error stack ([#6362](https://github.com/axios/axios/issues/6362)) ([81e0455](https://github.com/axios/axios/commit/81e0455b7b57fbaf2be16a73ebe0e6591cc6d8f9)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+1015/-127 (#6371 )") +- avatar [Jay](https://github.com/jasonsaayman "+30/-14 ()") +- avatar [Alexandre ABRIOUX](https://github.com/alexandre-abrioux "+56/-6 (#6362 )") + +# [1.7.0-beta.2](https://github.com/axios/axios/compare/v1.7.0-beta.1...v1.7.0-beta.2) (2024-05-19) + + +### Bug Fixes + +* **fetch:** capitalize HTTP method names; ([#6395](https://github.com/axios/axios/issues/6395)) ([ad3174a](https://github.com/axios/axios/commit/ad3174a3515c3c2573f4bcb94818d582826f3914)) +* **fetch:** fix & optimize progress capturing for cases when the request data has a nullish value or zero data length ([#6400](https://github.com/axios/axios/issues/6400)) ([95a3e8e](https://github.com/axios/axios/commit/95a3e8e346cfd6a5548e171f2341df3235d0e26b)) +* **fetch:** fix headers getting from a stream response; ([#6401](https://github.com/axios/axios/issues/6401)) ([870e0a7](https://github.com/axios/axios/commit/870e0a76f60d0094774a6a63fa606eec52a381af)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+99/-46 (#6405 #6404 #6401 #6400 #6395 )") + +# [1.7.0-beta.1](https://github.com/axios/axios/compare/v1.7.0-beta.0...v1.7.0-beta.1) (2024-05-07) + + +### Bug Fixes + +* **core/axios:** handle un-writable error stack ([#6362](https://github.com/axios/axios/issues/6362)) ([81e0455](https://github.com/axios/axios/commit/81e0455b7b57fbaf2be16a73ebe0e6591cc6d8f9)) +* **fetch:** fix cases when ReadableStream or Response.body are not available; ([#6377](https://github.com/axios/axios/issues/6377)) ([d1d359d](https://github.com/axios/axios/commit/d1d359da347704e8b28d768e61515a3e96c5b072)) +* **fetch:** treat fetch-related TypeError as an AxiosError.ERR_NETWORK error; ([#6380](https://github.com/axios/axios/issues/6380)) ([bb5f9a5](https://github.com/axios/axios/commit/bb5f9a5ab768452de9e166dc28d0ffc234245ef1)) + +### Contributors to this release + +- avatar [Alexandre ABRIOUX](https://github.com/alexandre-abrioux "+56/-6 (#6362 )") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+42/-17 (#6380 #6377 )") + +# [1.7.0-beta.0](https://github.com/axios/axios/compare/v1.6.8...v1.7.0-beta.0) (2024-04-28) + + +### Features + +* **adapter:** add fetch adapter; ([#6371](https://github.com/axios/axios/issues/6371)) ([a3ff99b](https://github.com/axios/axios/commit/a3ff99b59d8ec2ab5dd049e68c043617a4072e42)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+1015/-127 (#6371 )") +- avatar [Jay](https://github.com/jasonsaayman "+30/-14 ()") + +## [1.6.8](https://github.com/axios/axios/compare/v1.6.7...v1.6.8) (2024-03-15) + + +### Bug Fixes + +* **AxiosHeaders:** fix AxiosHeaders conversion to an object during config merging ([#6243](https://github.com/axios/axios/issues/6243)) ([2656612](https://github.com/axios/axios/commit/2656612bc10fe2757e9832b708ed773ab340b5cb)) +* **import:** use named export for EventEmitter; ([7320430](https://github.com/axios/axios/commit/7320430aef2e1ba2b89488a0eaf42681165498b1)) +* **vulnerability:** update follow-redirects to 1.15.6 ([#6300](https://github.com/axios/axios/issues/6300)) ([8786e0f](https://github.com/axios/axios/commit/8786e0ff55a8c68d4ca989801ad26df924042e27)) + +### Contributors to this release + +- avatar [Jay](https://github.com/jasonsaayman "+4572/-3446 (#6238 )") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+30/-0 (#6231 )") +- avatar [Mitchell](https://github.com/Creaous "+9/-9 (#6300 )") +- avatar [Emmanuel](https://github.com/mannoeu "+2/-2 (#6196 )") +- avatar [Lucas Keller](https://github.com/ljkeller "+3/-0 (#6194 )") +- avatar [Aditya Mogili](https://github.com/ADITYA-176 "+1/-1 ()") +- avatar [Miroslav Petrov](https://github.com/petrovmiroslav "+1/-1 (#6243 )") + +## [1.6.7](https://github.com/axios/axios/compare/v1.6.6...v1.6.7) (2024-01-25) + + +### Bug Fixes + +* capture async stack only for rejections with native error objects; ([#6203](https://github.com/axios/axios/issues/6203)) ([1a08f90](https://github.com/axios/axios/commit/1a08f90f402336e4d00e9ee82f211c6adb1640b0)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+30/-26 (#6203 )") +- avatar [zhoulixiang](https://github.com/zh-lx "+0/-3 (#6186 )") + +## [1.6.6](https://github.com/axios/axios/compare/v1.6.5...v1.6.6) (2024-01-24) + + +### Bug Fixes + +* fixed missed dispatchBeforeRedirect argument ([#5778](https://github.com/axios/axios/issues/5778)) ([a1938ff](https://github.com/axios/axios/commit/a1938ff073fcb0f89011f001dfbc1fa1dc995e39)) +* wrap errors to improve async stack trace ([#5987](https://github.com/axios/axios/issues/5987)) ([123f354](https://github.com/axios/axios/commit/123f354b920f154a209ea99f76b7b2ef3d9ebbab)) + +### Contributors to this release + +- avatar [Ilya Priven](https://github.com/ikonst "+91/-8 (#5987 )") +- avatar [Zao Soula](https://github.com/zaosoula "+6/-6 (#5778 )") + +## [1.6.5](https://github.com/axios/axios/compare/v1.6.4...v1.6.5) (2024-01-05) + + +### Bug Fixes + +* **ci:** refactor notify action as a job of publish action; ([#6176](https://github.com/axios/axios/issues/6176)) ([0736f95](https://github.com/axios/axios/commit/0736f95ce8776366dc9ca569f49ba505feb6373c)) +* **dns:** fixed lookup error handling; ([#6175](https://github.com/axios/axios/issues/6175)) ([f4f2b03](https://github.com/axios/axios/commit/f4f2b039dd38eb4829e8583caede4ed6d2dd59be)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+41/-6 (#6176 #6175 )") +- avatar [Jay](https://github.com/jasonsaayman "+6/-1 ()") + +## [1.6.4](https://github.com/axios/axios/compare/v1.6.3...v1.6.4) (2024-01-03) + + +### Bug Fixes + +* **security:** fixed formToJSON prototype pollution vulnerability; ([#6167](https://github.com/axios/axios/issues/6167)) ([3c0c11c](https://github.com/axios/axios/commit/3c0c11cade045c4412c242b5727308cff9897a0e)) +* **security:** fixed security vulnerability in follow-redirects ([#6163](https://github.com/axios/axios/issues/6163)) ([75af1cd](https://github.com/axios/axios/commit/75af1cdff5b3a6ca3766d3d3afbc3115bb0811b8)) + +### Contributors to this release + +- avatar [Jay](https://github.com/jasonsaayman "+34/-6 ()") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+34/-3 (#6172 #6167 )") +- avatar [Guy Nesher](https://github.com/gnesher "+10/-10 (#6163 )") + +## [1.6.3](https://github.com/axios/axios/compare/v1.6.2...v1.6.3) (2023-12-26) + + +### Bug Fixes + +* Regular Expression Denial of Service (ReDoS) ([#6132](https://github.com/axios/axios/issues/6132)) ([5e7ad38](https://github.com/axios/axios/commit/5e7ad38fb0f819fceb19fb2ee5d5d38f56aa837d)) + +### Contributors to this release + +- avatar [Jay](https://github.com/jasonsaayman "+15/-6 (#6145 )") +- avatar [Willian Agostini](https://github.com/WillianAgostini "+17/-2 (#6132 )") +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+3/-0 (#6084 )") + +## [1.6.2](https://github.com/axios/axios/compare/v1.6.1...v1.6.2) (2023-11-14) + + +### Features + +* **withXSRFToken:** added withXSRFToken option as a workaround to achieve the old `withCredentials` behavior; ([#6046](https://github.com/axios/axios/issues/6046)) ([cff9967](https://github.com/axios/axios/commit/cff996779b272a5e94c2b52f5503ccf668bc42dc)) + +### PRs +- feat(withXSRFToken): added withXSRFToken option as a workaround to achieve the old `withCredentials` behavior; ( [#6046](https://api.github.com/repos/axios/axios/pulls/6046) ) +``` + +📢 This PR added 'withXSRFToken' option as a replacement for old withCredentials behaviour. +You should now use withXSRFToken along with withCredential to get the old behavior. +This functionality is considered as a fix. +``` + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+271/-146 (#6081 #6080 #6079 #6078 #6046 #6064 #6063 )") +- avatar [Ng Choon Khon (CK)](https://github.com/ckng0221 "+4/-4 (#6073 )") +- avatar [Muhammad Noman](https://github.com/mnomanmemon "+2/-2 (#6048 )") + +## [1.6.1](https://github.com/axios/axios/compare/v1.6.0...v1.6.1) (2023-11-08) + + +### Bug Fixes + +* **formdata:** fixed content-type header normalization for non-standard browser environments; ([#6056](https://github.com/axios/axios/issues/6056)) ([dd465ab](https://github.com/axios/axios/commit/dd465ab22bbfa262c6567be6574bf46a057d5288)) +* **platform:** fixed emulated browser detection in node.js environment; ([#6055](https://github.com/axios/axios/issues/6055)) ([3dc8369](https://github.com/axios/axios/commit/3dc8369e505e32a4e12c22f154c55fd63ac67fbb)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+432/-65 (#6059 #6056 #6055 )") +- avatar [Fabian Meyer](https://github.com/meyfa "+5/-2 (#5835 )") + +### PRs +- feat(withXSRFToken): added withXSRFToken option as a workaround to achieve the old `withCredentials` behavior; ( [#6046](https://api.github.com/repos/axios/axios/pulls/6046) ) +``` + +📢 This PR added 'withXSRFToken' option as a replacement for old withCredentials behaviour. +You should now use withXSRFToken along with withCredential to get the old behavior. +This functionality is considered as a fix. +``` + +# [1.6.0](https://github.com/axios/axios/compare/v1.5.1...v1.6.0) (2023-10-26) + + +### Bug Fixes + +* **CSRF:** fixed CSRF vulnerability CVE-2023-45857 ([#6028](https://github.com/axios/axios/issues/6028)) ([96ee232](https://github.com/axios/axios/commit/96ee232bd3ee4de2e657333d4d2191cd389e14d0)) +* **dns:** fixed lookup function decorator to work properly in node v20; ([#6011](https://github.com/axios/axios/issues/6011)) ([5aaff53](https://github.com/axios/axios/commit/5aaff532a6b820bb9ab6a8cd0f77131b47e2adb8)) +* **types:** fix AxiosHeaders types; ([#5931](https://github.com/axios/axios/issues/5931)) ([a1c8ad0](https://github.com/axios/axios/commit/a1c8ad008b3c13d53e135bbd0862587fb9d3fc09)) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+449/-114 (#6032 #6021 #6011 #5932 #5931 )") +- avatar [Valentin Panov](https://github.com/valentin-panov "+4/-4 (#6028 )") +- avatar [Rinku Chaudhari](https://github.com/therealrinku "+1/-1 (#5889 )") + +## [1.5.1](https://github.com/axios/axios/compare/v1.5.0...v1.5.1) (2023-09-26) + + +### Bug Fixes + +* **adapters:** improved adapters loading logic to have clear error messages; ([#5919](https://github.com/axios/axios/issues/5919)) ([e410779](https://github.com/axios/axios/commit/e4107797a7a1376f6209fbecfbbce73d3faa7859)) +* **formdata:** fixed automatic addition of the `Content-Type` header for FormData in non-browser environments; ([#5917](https://github.com/axios/axios/issues/5917)) ([bc9af51](https://github.com/axios/axios/commit/bc9af51b1886d1b3529617702f2a21a6c0ed5d92)) +* **headers:** allow `content-encoding` header to handle case-insensitive values ([#5890](https://github.com/axios/axios/issues/5890)) ([#5892](https://github.com/axios/axios/issues/5892)) ([4c89f25](https://github.com/axios/axios/commit/4c89f25196525e90a6e75eda9cb31ae0a2e18acd)) +* **types:** removed duplicated code ([9e62056](https://github.com/axios/axios/commit/9e6205630e1c9cf863adf141c0edb9e6d8d4b149)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+89/-18 (#5919 #5917 )") +- avatar [David Dallas](https://github.com/DavidJDallas "+11/-5 ()") +- avatar [Sean Sattler](https://github.com/fb-sean "+2/-8 ()") +- avatar [Mustafa Ateş Uzun](https://github.com/0o001 "+4/-4 ()") +- avatar [Przemyslaw Motacki](https://github.com/sfc-gh-pmotacki "+2/-1 (#5892 )") +- avatar [Michael Di Prisco](https://github.com/Cadienvan "+1/-1 ()") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +# [1.5.0](https://github.com/axios/axios/compare/v1.4.0...v1.5.0) (2023-08-26) + + +### Bug Fixes + +* **adapter:** make adapter loading error more clear by using platform-specific adapters explicitly ([#5837](https://github.com/axios/axios/issues/5837)) ([9a414bb](https://github.com/axios/axios/commit/9a414bb6c81796a95c6c7fe668637825458e8b6d)) +* **dns:** fixed `cacheable-lookup` integration; ([#5836](https://github.com/axios/axios/issues/5836)) ([b3e327d](https://github.com/axios/axios/commit/b3e327dcc9277bdce34c7ef57beedf644b00d628)) +* **headers:** added support for setting header names that overlap with class methods; ([#5831](https://github.com/axios/axios/issues/5831)) ([d8b4ca0](https://github.com/axios/axios/commit/d8b4ca0ea5f2f05efa4edfe1e7684593f9f68273)) +* **headers:** fixed common Content-Type header merging; ([#5832](https://github.com/axios/axios/issues/5832)) ([8fda276](https://github.com/axios/axios/commit/8fda2766b1e6bcb72c3fabc146223083ef13ce17)) + + +### Features + +* export getAdapter function ([#5324](https://github.com/axios/axios/issues/5324)) ([ca73eb8](https://github.com/axios/axios/commit/ca73eb878df0ae2dace81fe3a7f1fb5986231bf1)) +* **export:** export adapters without `unsafe` prefix ([#5839](https://github.com/axios/axios/issues/5839)) ([1601f4a](https://github.com/axios/axios/commit/1601f4a27a81ab47fea228f1e244b2c4e3ce28bf)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+66/-29 (#5839 #5837 #5836 #5832 #5831 )") +- avatar [夜葬](https://github.com/geekact "+42/-0 (#5324 )") +- avatar [Jonathan Budiman](https://github.com/JBudiman00 "+30/-0 (#5788 )") +- avatar [Michael Di Prisco](https://github.com/Cadienvan "+3/-5 (#5791 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +# [1.4.0](https://github.com/axios/axios/compare/v1.3.6...v1.4.0) (2023-04-27) + + +### Bug Fixes + +* **formdata:** add `multipart/form-data` content type for FormData payload on custom client environments; ([#5678](https://github.com/axios/axios/issues/5678)) ([bbb61e7](https://github.com/axios/axios/commit/bbb61e70cb1185adfb1cbbb86eaf6652c48d89d1)) +* **package:** export package internals with unsafe path prefix; ([#5677](https://github.com/axios/axios/issues/5677)) ([df38c94](https://github.com/axios/axios/commit/df38c949f26414d88ba29ec1e353c4d4f97eaf09)) + + +### Features + +* **dns:** added support for a custom lookup function; ([#5339](https://github.com/axios/axios/issues/5339)) ([2701911](https://github.com/axios/axios/commit/2701911260a1faa5cc5e1afe437121b330a3b7bb)) +* **types:** export `AxiosHeaderValue` type. ([#5525](https://github.com/axios/axios/issues/5525)) ([726f1c8](https://github.com/axios/axios/commit/726f1c8e00cffa0461a8813a9bdcb8f8b9d762cf)) + + +### Performance Improvements + +* **merge-config:** optimize mergeConfig performance by avoiding duplicate key visits; ([#5679](https://github.com/axios/axios/issues/5679)) ([e6f7053](https://github.com/axios/axios/commit/e6f7053bf1a3e87cf1f9da8677e12e3fe829d68e)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+151/-16 (#5684 #5339 #5679 #5678 #5677 )") +- avatar [Arthur Fiorette](https://github.com/arthurfiorette "+19/-19 (#5525 )") +- avatar [PIYUSH NEGI](https://github.com/npiyush97 "+2/-18 (#5670 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.3.6](https://github.com/axios/axios/compare/v1.3.5...v1.3.6) (2023-04-19) + + +### Bug Fixes + +* **types:** added transport to RawAxiosRequestConfig ([#5445](https://github.com/axios/axios/issues/5445)) ([6f360a2](https://github.com/axios/axios/commit/6f360a2531d8d70363fd9becef6a45a323f170e2)) +* **utils:** make isFormData detection logic stricter to avoid unnecessary calling of the `toString` method on the target; ([#5661](https://github.com/axios/axios/issues/5661)) ([aa372f7](https://github.com/axios/axios/commit/aa372f7306295dfd1100c1c2c77ce95c95808e76)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+48/-10 (#5665 #5661 #5663 )") +- avatar [Michael Di Prisco](https://github.com/Cadienvan "+2/-0 (#5445 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.3.5](https://github.com/axios/axios/compare/v1.3.4...v1.3.5) (2023-04-05) + + +### Bug Fixes + +* **headers:** fixed isValidHeaderName to support full list of allowed characters; ([#5584](https://github.com/axios/axios/issues/5584)) ([e7decef](https://github.com/axios/axios/commit/e7decef6a99f4627e27ed9ea5b00ce8e201c3841)) +* **params:** re-added the ability to set the function as `paramsSerializer` config; ([#5633](https://github.com/axios/axios/issues/5633)) ([a56c866](https://github.com/axios/axios/commit/a56c8661209d5ce5a645a05f294a0e08a6c1f6b3)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+28/-10 (#5633 #5584 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.3.4](https://github.com/axios/axios/compare/v1.3.3...v1.3.4) (2023-02-22) + + +### Bug Fixes + +* **blob:** added a check to make sure the Blob class is available in the browser's global scope; ([#5548](https://github.com/axios/axios/issues/5548)) ([3772c8f](https://github.com/axios/axios/commit/3772c8fe74112a56e3e9551f894d899bc3a9443a)) +* **http:** fixed regression bug when handling synchronous errors inside the adapter; ([#5564](https://github.com/axios/axios/issues/5564)) ([a3b246c](https://github.com/axios/axios/commit/a3b246c9de5c3bc4b5a742e15add55b375479451)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+38/-26 (#5564 )") +- avatar [lcysgsg](https://github.com/lcysgsg "+4/-0 (#5548 )") +- avatar [Michael Di Prisco](https://github.com/Cadienvan "+3/-0 (#5444 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.3.3](https://github.com/axios/axios/compare/v1.3.2...v1.3.3) (2023-02-13) + + +### Bug Fixes + +* **formdata:** added a check to make sure the FormData class is available in the browser's global scope; ([#5545](https://github.com/axios/axios/issues/5545)) ([a6dfa72](https://github.com/axios/axios/commit/a6dfa72010db5ad52db8bd13c0f98e537e8fd05d)) +* **formdata:** fixed setting NaN as Content-Length for form payload in some cases; ([#5535](https://github.com/axios/axios/issues/5535)) ([c19f7bf](https://github.com/axios/axios/commit/c19f7bf770f90ae8307f4ea3104f227056912da1)) +* **headers:** fixed the filtering logic of the clear method; ([#5542](https://github.com/axios/axios/issues/5542)) ([ea87ebf](https://github.com/axios/axios/commit/ea87ebfe6d1699af072b9e7cd40faf8f14b0ab93)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+11/-7 (#5545 #5535 #5542 )") +- avatar [陈若枫](https://github.com/ruofee "+2/-2 (#5467 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.3.2](https://github.com/axios/axios/compare/v1.3.1...v1.3.2) (2023-02-03) + + +### Bug Fixes + +* **http:** treat http://localhost as base URL for relative paths to avoid `ERR_INVALID_URL` error; ([#5528](https://github.com/axios/axios/issues/5528)) ([128d56f](https://github.com/axios/axios/commit/128d56f4a0fb8f5f2ed6e0dd80bc9225fee9538c)) +* **http:** use explicit import instead of TextEncoder global; ([#5530](https://github.com/axios/axios/issues/5530)) ([6b3c305](https://github.com/axios/axios/commit/6b3c305fc40c56428e0afabedc6f4d29c2830f6f)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+2/-1 (#5530 #5528 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.3.1](https://github.com/axios/axios/compare/v1.3.0...v1.3.1) (2023-02-01) + + +### Bug Fixes + +* **formdata:** add hotfix to use the asynchronous API to compute the content-length header value; ([#5521](https://github.com/axios/axios/issues/5521)) ([96d336f](https://github.com/axios/axios/commit/96d336f527619f21da012fe1f117eeb53e5a2120)) +* **serializer:** fixed serialization of array-like objects; ([#5518](https://github.com/axios/axios/issues/5518)) ([08104c0](https://github.com/axios/axios/commit/08104c028c0f9353897b1b6691d74c440fd0c32d)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+27/-8 (#5521 #5518 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +# [1.3.0](https://github.com/axios/axios/compare/v1.2.6...v1.3.0) (2023-01-31) + + +### Bug Fixes + +* **headers:** fixed & optimized clear method; ([#5507](https://github.com/axios/axios/issues/5507)) ([9915635](https://github.com/axios/axios/commit/9915635c69d0ab70daca5738488421f67ca60959)) +* **http:** add zlib headers if missing ([#5497](https://github.com/axios/axios/issues/5497)) ([65e8d1e](https://github.com/axios/axios/commit/65e8d1e28ce829f47a837e45129730e541950d3c)) + + +### Features + +* **fomdata:** added support for spec-compliant FormData & Blob types; ([#5316](https://github.com/axios/axios/issues/5316)) ([6ac574e](https://github.com/axios/axios/commit/6ac574e00a06731288347acea1e8246091196953)) + +### Contributors to this release + +- avatar [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+352/-67 (#5514 #5512 #5510 #5509 #5508 #5316 #5507 )") +- avatar [ItsNotGoodName](https://github.com/ItsNotGoodName "+43/-2 (#5497 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.2.6](https://github.com/axios/axios/compare/v1.2.5...v1.2.6) (2023-01-28) + + +### Bug Fixes + +* **headers:** added missed Authorization accessor; ([#5502](https://github.com/axios/axios/issues/5502)) ([342c0ba](https://github.com/axios/axios/commit/342c0ba9a16ea50f5ed7d2366c5c1a2c877e3f26)) +* **types:** fixed `CommonRequestHeadersList` & `CommonResponseHeadersList` types to be private in commonJS; ([#5503](https://github.com/axios/axios/issues/5503)) ([5a3d0a3](https://github.com/axios/axios/commit/5a3d0a3234d77361a1bc7cedee2da1e11df08e2c)) + +### Contributors to this release + +- ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+24/-9 (#5503 #5502 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.2.5](https://github.com/axios/axios/compare/v1.2.4...v1.2.5) (2023-01-26) + + +### Bug Fixes + +* **types:** fixed AxiosHeaders to handle spread syntax by making all methods non-enumerable; ([#5499](https://github.com/axios/axios/issues/5499)) ([580f1e8](https://github.com/axios/axios/commit/580f1e8033a61baa38149d59fd16019de3932c22)) + +### Contributors to this release + +- ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+82/-54 (#5499 )") +- ![avatar](https://avatars.githubusercontent.com/u/20516159?v=4&s=16) [Elliot Ford](https://github.com/EFord36 "+1/-1 (#5462 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.2.4](https://github.com/axios/axios/compare/v1.2.3...v1.2.4) (2023-01-22) + + +### Bug Fixes + +* **types:** renamed `RawAxiosRequestConfig` back to `AxiosRequestConfig`; ([#5486](https://github.com/axios/axios/issues/5486)) ([2a71f49](https://github.com/axios/axios/commit/2a71f49bc6c68495fa419003a3107ed8bd703ad0)) +* **types:** fix `AxiosRequestConfig` generic; ([#5478](https://github.com/axios/axios/issues/5478)) ([9bce81b](https://github.com/axios/axios/commit/186ea062da8b7d578ae78b1a5c220986b9bce81b)) + +### Contributors to this release + +- ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+242/-108 (#5486 #5482 )") +- ![avatar](https://avatars.githubusercontent.com/u/9430821?v=4&s=16) [Daniel Hillmann](https://github.com/hilleer "+1/-1 (#5478 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.2.3](https://github.com/axios/axios/compare/1.2.2...1.2.3) (2023-01-10) + + +### Bug Fixes + +* **types:** fixed AxiosRequestConfig header interface by refactoring it to RawAxiosRequestConfig; ([#5420](https://github.com/axios/axios/issues/5420)) ([0811963](https://github.com/axios/axios/commit/08119634a22f1d5b19f5c9ea0adccb6d3eebc3bc)) + +### Contributors to this release + +- ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS "+938/-442 (#5456 #5455 #5453 #5451 #5449 #5447 #5446 #5443 #5442 #5439 #5420 )") + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.2.2] - 2022-12-29 + +### Fixed +- fix(ci): fix release script inputs [#5392](https://github.com/axios/axios/pull/5392) +- fix(ci): prerelease scipts [#5377](https://github.com/axios/axios/pull/5377) +- fix(ci): release scripts [#5376](https://github.com/axios/axios/pull/5376) +- fix(ci): typescript tests [#5375](https://github.com/axios/axios/pull/5375) +- fix: Brotli decompression [#5353](https://github.com/axios/axios/pull/5353) +- fix: add missing HttpStatusCode [#5345](https://github.com/axios/axios/pull/5345) + +### Chores +- chore(ci): set conventional-changelog header config [#5406](https://github.com/axios/axios/pull/5406) +- chore(ci): fix automatic contributors resolving [#5403](https://github.com/axios/axios/pull/5403) +- chore(ci): improved logging for the contributors list generator [#5398](https://github.com/axios/axios/pull/5398) +- chore(ci): fix release action [#5397](https://github.com/axios/axios/pull/5397) +- chore(ci): fix version bump script by adding bump argument for target version [#5393](https://github.com/axios/axios/pull/5393) +- chore(deps): bump decode-uri-component from 0.2.0 to 0.2.2 [#5342](https://github.com/axios/axios/pull/5342) +- chore(ci): GitHub Actions Release script [#5384](https://github.com/axios/axios/pull/5384) +- chore(ci): release scripts [#5364](https://github.com/axios/axios/pull/5364) + +### Contributors to this release +- ![avatar](https://avatars.githubusercontent.com/u/12586868?v=4&s=16) [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) +- ![avatar](https://avatars.githubusercontent.com/u/1652293?v=4&s=16) [Winnie](https://github.com/winniehell) + +## [1.2.1] - 2022-12-05 + +### Changed +- feat(exports): export mergeConfig [#5151](https://github.com/axios/axios/pull/5151) + +### Fixed +- fix(CancelledError): include config [#4922](https://github.com/axios/axios/pull/4922) +- fix(general): removing multiple/trailing/leading whitespace [#5022](https://github.com/axios/axios/pull/5022) +- fix(headers): decompression for responses without Content-Length header [#5306](https://github.com/axios/axios/pull/5306) +- fix(webWorker): exception to sending form data in web worker [#5139](https://github.com/axios/axios/pull/5139) + +### Refactors +- refactor(types): AxiosProgressEvent.event type to any [#5308](https://github.com/axios/axios/pull/5308) +- refactor(types): add missing types for static AxiosError.from method [#4956](https://github.com/axios/axios/pull/4956) + +### Chores +- chore(docs): remove README link to non-existent upgrade guide [#5307](https://github.com/axios/axios/pull/5307) +- chore(docs): typo in issue template name [#5159](https://github.com/axios/axios/pull/5159) + +### Contributors to this release + +- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) +- [Zachary Lysobey](https://github.com/zachlysobey) +- [Kevin Ennis](https://github.com/kevincennis) +- [Philipp Loose](https://github.com/phloose) +- [secondl1ght](https://github.com/secondl1ght) +- [wenzheng](https://github.com/0x30) +- [Ivan Barsukov](https://github.com/ovarn) +- [Arthur Fiorette](https://github.com/arthurfiorette) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.2.0] - 2022-11-10 + +### Changed + +- changed: refactored module exports [#5162](https://github.com/axios/axios/pull/5162) +- change: re-added support for loading Axios with require('axios').default [#5225](https://github.com/axios/axios/pull/5225) + +### Fixed + +- fix: improve AxiosHeaders class [#5224](https://github.com/axios/axios/pull/5224) +- fix: TypeScript type definitions for commonjs [#5196](https://github.com/axios/axios/pull/5196) +- fix: type definition of use method on AxiosInterceptorManager to match the the README [#5071](https://github.com/axios/axios/pull/5071) +- fix: __dirname is not defined in the sandbox [#5269](https://github.com/axios/axios/pull/5269) +- fix: AxiosError.toJSON method to avoid circular references [#5247](https://github.com/axios/axios/pull/5247) +- fix: Z_BUF_ERROR when content-encoding is set but the response body is empty [#5250](https://github.com/axios/axios/pull/5250) + +### Refactors +- refactor: allowing adapters to be loaded by name [#5277](https://github.com/axios/axios/pull/5277) + +### Chores + +- chore: force CI restart [#5243](https://github.com/axios/axios/pull/5243) +- chore: update ECOSYSTEM.md [#5077](https://github.com/axios/axios/pull/5077) +- chore: update get/index.html [#5116](https://github.com/axios/axios/pull/5116) +- chore: update Sandbox UI/UX [#5205](https://github.com/axios/axios/pull/5205) +- chore:(actions): remove git credentials after checkout [#5235](https://github.com/axios/axios/pull/5235) +- chore(actions): bump actions/dependency-review-action from 2 to 3 [#5266](https://github.com/axios/axios/pull/5266) +- chore(packages): bump loader-utils from 1.4.1 to 1.4.2 [#5295](https://github.com/axios/axios/pull/5295) +- chore(packages): bump engine.io from 6.2.0 to 6.2.1 [#5294](https://github.com/axios/axios/pull/5294) +- chore(packages): bump socket.io-parser from 4.0.4 to 4.0.5 [#5241](https://github.com/axios/axios/pull/5241) +- chore(packages): bump loader-utils from 1.4.0 to 1.4.1 [#5245](https://github.com/axios/axios/pull/5245) +- chore(docs): update Resources links in README [#5119](https://github.com/axios/axios/pull/5119) +- chore(docs): update the link for JSON url [#5265](https://github.com/axios/axios/pull/5265) +- chore(docs): fix broken links [#5218](https://github.com/axios/axios/pull/5218) +- chore(docs): update and rename UPGRADE_GUIDE.md to MIGRATION_GUIDE.md [#5170](https://github.com/axios/axios/pull/5170) +- chore(docs): typo fix line #856 and #920 [#5194](https://github.com/axios/axios/pull/5194) +- chore(docs): typo fix #800 [#5193](https://github.com/axios/axios/pull/5193) +- chore(docs): fix typos [#5184](https://github.com/axios/axios/pull/5184) +- chore(docs): fix punctuation in README.md [#5197](https://github.com/axios/axios/pull/5197) +- chore(docs): update readme in the Handling Errors section - issue reference #5260 [#5261](https://github.com/axios/axios/pull/5261) +- chore: remove \b from filename [#5207](https://github.com/axios/axios/pull/5207) +- chore(docs): update CHANGELOG.md [#5137](https://github.com/axios/axios/pull/5137) +- chore: add sideEffects false to package.json [#5025](https://github.com/axios/axios/pull/5025) + +### Contributors to this release + +- [Maddy Miller](https://github.com/me4502) +- [Amit Saini](https://github.com/amitsainii) +- [ecyrbe](https://github.com/ecyrbe) +- [Ikko Ashimine](https://github.com/eltociear) +- [Geeth Gunnampalli](https://github.com/thetechie7) +- [Shreem Asati](https://github.com/shreem-123) +- [Frieder Bluemle](https://github.com/friederbluemle) +- [윤세영](https://github.com/yunseyeong) +- [Claudio Busatto](https://github.com/cjcbusatto) +- [Remco Haszing](https://github.com/remcohaszing) +- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) +- [Csaba Maulis](https://github.com/om4csaba) +- [MoPaMo](https://github.com/MoPaMo) +- [Daniel Fjeldstad](https://github.com/w3bdesign) +- [Adrien Brunet](https://github.com/adrien-may) +- [Frazer Smith](https://github.com/Fdawgs) +- [HaiTao](https://github.com/836334258) +- [AZM](https://github.com/aziyatali) +- [relbns](https://github.com/relbns) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.1.3] - 2022-10-15 + +### Added + +- Added custom params serializer support [#5113](https://github.com/axios/axios/pull/5113) + +### Fixed + +- Fixed top-level export to keep them in-line with static properties [#5109](https://github.com/axios/axios/pull/5109) +- Stopped including null values to query string. [#5108](https://github.com/axios/axios/pull/5108) +- Restored proxy config backwards compatibility with 0.x [#5097](https://github.com/axios/axios/pull/5097) +- Added back AxiosHeaders in AxiosHeaderValue [#5103](https://github.com/axios/axios/pull/5103) +- Pin CDN install instructions to a specific version [#5060](https://github.com/axios/axios/pull/5060) +- Handling of array values fixed for AxiosHeaders [#5085](https://github.com/axios/axios/pull/5085) + +### Chores + +- docs: match badge style, add link to them [#5046](https://github.com/axios/axios/pull/5046) +- chore: fixing comments typo [#5054](https://github.com/axios/axios/pull/5054) +- chore: update issue template [#5061](https://github.com/axios/axios/pull/5061) +- chore: added progress capturing section to the docs; [#5084](https://github.com/axios/axios/pull/5084) + +### Contributors to this release + +- [Jason Saayman](https://github.com/jasonsaayman) +- [scarf](https://github.com/scarf005) +- [Lenz Weber-Tronic](https://github.com/phryneas) +- [Arvindh](https://github.com/itsarvindh) +- [Félix Legrelle](https://github.com/FelixLgr) +- [Patrick Petrovic](https://github.com/ppati000) +- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) +- [littledian](https://github.com/littledian) +- [ChronosMasterOfAllTime](https://github.com/ChronosMasterOfAllTime) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.1.2] - 2022-10-07 + +### Fixed + +- Fixed broken exports for UMD builds. + +### Contributors to this release + +- [Jason Saayman](https://github.com/jasonsaayman) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.1.1] - 2022-10-07 + +### Fixed + +- Fixed broken exports for common js. This fix breaks a prior fix, I will fix both issues ASAP but the commonJS use is more impactful. + +### Contributors to this release + +- [Jason Saayman](https://github.com/jasonsaayman) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.1.0] - 2022-10-06 + +### Fixed + +- Fixed missing exports in type definition index.d.ts [#5003](https://github.com/axios/axios/pull/5003) +- Fixed query params composing [#5018](https://github.com/axios/axios/pull/5018) +- Fixed GenericAbortSignal interface by making it more generic [#5021](https://github.com/axios/axios/pull/5021) +- Fixed adding "clear" to AxiosInterceptorManager [#5010](https://github.com/axios/axios/pull/5010) +- Fixed commonjs & umd exports [#5030](https://github.com/axios/axios/pull/5030) +- Fixed inability to access response headers when using axios 1.x with Jest [#5036](https://github.com/axios/axios/pull/5036) + +### Contributors to this release + +- [Trim21](https://github.com/trim21) +- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) +- [shingo.sasaki](https://github.com/s-sasaki-0529) +- [Ivan Pepelko](https://github.com/ivanpepelko) +- [Richard Kořínek](https://github.com/risa) + +### PRs +- CVE 2023 45857 ( [#6028](https://api.github.com/repos/axios/axios/pulls/6028) ) +``` + +⚠️ Critical vulnerability fix. See https://security.snyk.io/vuln/SNYK-JS-AXIOS-6032459 +``` + +## [1.0.0] - 2022-10-04 + +### Added + +- Added stack trace to AxiosError [#4624](https://github.com/axios/axios/pull/4624) +- Add AxiosError to AxiosStatic [#4654](https://github.com/axios/axios/pull/4654) +- Replaced Rollup as our build runner [#4596](https://github.com/axios/axios/pull/4596) +- Added generic TS types for the exposed toFormData helper [#4668](https://github.com/axios/axios/pull/4668) +- Added listen callback function [#4096](https://github.com/axios/axios/pull/4096) +- Added instructions for installing using PNPM [#4207](https://github.com/axios/axios/pull/4207) +- Added generic AxiosAbortSignal TS interface to avoid importing AbortController polyfill [#4229](https://github.com/axios/axios/pull/4229) +- Added axios-url-template in ECOSYSTEM.md [#4238](https://github.com/axios/axios/pull/4238) +- Added a clear() function to the request and response interceptors object so a user can ensure that all interceptors have been removed from an axios instance [#4248](https://github.com/axios/axios/pull/4248) +- Added react hook plugin [#4319](https://github.com/axios/axios/pull/4319) +- Adding HTTP status code for transformResponse [#4580](https://github.com/axios/axios/pull/4580) +- Added blob to the list of protocols supported by the browser [#4678](https://github.com/axios/axios/pull/4678) +- Resolving proxy from env on redirect [#4436](https://github.com/axios/axios/pull/4436) +- Added enhanced toFormData implementation with additional options [4704](https://github.com/axios/axios/pull/4704) +- Adding Canceler parameters config and request [#4711](https://github.com/axios/axios/pull/4711) +- Added automatic payload serialization to application/x-www-form-urlencoded [#4714](https://github.com/axios/axios/pull/4714) +- Added the ability for webpack users to overwrite built-ins [#4715](https://github.com/axios/axios/pull/4715) +- Added string[] to AxiosRequestHeaders type [#4322](https://github.com/axios/axios/pull/4322) +- Added the ability for the url-encoded-form serializer to respect the formSerializer config [#4721](https://github.com/axios/axios/pull/4721) +- Added isCancel type assert [#4293](https://github.com/axios/axios/pull/4293) +- Added data URL support for node.js [#4725](https://github.com/axios/axios/pull/4725) +- Adding types for progress event callbacks [#4675](https://github.com/axios/axios/pull/4675) +- URL params serializer [#4734](https://github.com/axios/axios/pull/4734) +- Added axios.formToJSON method [#4735](https://github.com/axios/axios/pull/4735) +- Bower platform add data protocol [#4804](https://github.com/axios/axios/pull/4804) +- Use WHATWG URL API instead of url.parse() [#4852](https://github.com/axios/axios/pull/4852) +- Add ENUM containing Http Status Codes to typings [#4903](https://github.com/axios/axios/pull/4903) +- Improve typing of timeout in index.d.ts [#4934](https://github.com/axios/axios/pull/4934) + +### Changed + +- Updated AxiosError.config to be optional in the type definition [#4665](https://github.com/axios/axios/pull/4665) +- Updated README emphasizing the URLSearchParam built-in interface over other solutions [#4590](https://github.com/axios/axios/pull/4590) +- Include request and config when creating a CanceledError instance [#4659](https://github.com/axios/axios/pull/4659) +- Changed func-names eslint rule to as-needed [#4492](https://github.com/axios/axios/pull/4492) +- Replacing deprecated substr() with slice() as substr() is deprecated [#4468](https://github.com/axios/axios/pull/4468) +- Updating HTTP links in README.md to use HTTPS [#4387](https://github.com/axios/axios/pull/4387) +- Updated to a better trim() polyfill [#4072](https://github.com/axios/axios/pull/4072) +- Updated types to allow specifying partial default headers on instance create [#4185](https://github.com/axios/axios/pull/4185) +- Expanded isAxiosError types [#4344](https://github.com/axios/axios/pull/4344) +- Updated type definition for axios instance methods [#4224](https://github.com/axios/axios/pull/4224) +- Updated eslint config [#4722](https://github.com/axios/axios/pull/4722) +- Updated Docs [#4742](https://github.com/axios/axios/pull/4742) +- Refactored Axios to use ES2017 [#4787](https://github.com/axios/axios/pull/4787) + + +### Deprecated +- There are multiple deprecations, refactors and fixes provided in this release. Please read through the full release notes to see how this may impact your project and use case. + +### Removed + +- Removed incorrect argument for NetworkError constructor [#4656](https://github.com/axios/axios/pull/4656) +- Removed Webpack [#4596](https://github.com/axios/axios/pull/4596) +- Removed function that transform arguments to array [#4544](https://github.com/axios/axios/pull/4544) + +### Fixed + +- Fixed grammar in README [#4649](https://github.com/axios/axios/pull/4649) +- Fixed code error in README [#4599](https://github.com/axios/axios/pull/4599) +- Optimized the code that checks cancellation [#4587](https://github.com/axios/axios/pull/4587) +- Fix url pointing to defaults.js in README [#4532](https://github.com/axios/axios/pull/4532) +- Use type alias instead of interface for AxiosPromise [#4505](https://github.com/axios/axios/pull/4505) +- Fix some word spelling and lint style in code comments [#4500](https://github.com/axios/axios/pull/4500) +- Edited readme with 3 updated browser icons of Chrome, FireFox and Safari [#4414](https://github.com/axios/axios/pull/4414) +- Bump follow-redirects from 1.14.9 to 1.15.0 [#4673](https://github.com/axios/axios/pull/4673) +- Fixing http tests to avoid hanging when assertions fail [#4435](https://github.com/axios/axios/pull/4435) +- Fix TS definition for AxiosRequestTransformer [#4201](https://github.com/axios/axios/pull/4201) +- Fix grammatical issues in README [#4232](https://github.com/axios/axios/pull/4232) +- Fixing instance.defaults.headers type [#4557](https://github.com/axios/axios/pull/4557) +- Fixed race condition on immediate requests cancellation [#4261](https://github.com/axios/axios/pull/4261) +- Fixing Z_BUF_ERROR when no content [#4701](https://github.com/axios/axios/pull/4701) +- Fixing proxy beforeRedirect regression [#4708](https://github.com/axios/axios/pull/4708) +- Fixed AxiosError status code type [#4717](https://github.com/axios/axios/pull/4717) +- Fixed AxiosError stack capturing [#4718](https://github.com/axios/axios/pull/4718) +- Fixing AxiosRequestHeaders typings [#4334](https://github.com/axios/axios/pull/4334) +- Fixed max body length defaults [#4731](https://github.com/axios/axios/pull/4731) +- Fixed toFormData Blob issue on node>v17 [#4728](https://github.com/axios/axios/pull/4728) +- Bump grunt from 1.5.2 to 1.5.3 [#4743](https://github.com/axios/axios/pull/4743) +- Fixing content-type header repeated [#4745](https://github.com/axios/axios/pull/4745) +- Fixed timeout error message for http [4738](https://github.com/axios/axios/pull/4738) +- Request ignores false, 0 and empty string as body values [#4785](https://github.com/axios/axios/pull/4785) +- Added back missing minified builds [#4805](https://github.com/axios/axios/pull/4805) +- Fixed a type error [#4815](https://github.com/axios/axios/pull/4815) +- Fixed a regression bug with unsubscribing from cancel token; [#4819](https://github.com/axios/axios/pull/4819) +- Remove repeated compression algorithm [#4820](https://github.com/axios/axios/pull/4820) +- The error of calling extend to pass parameters [#4857](https://github.com/axios/axios/pull/4857) +- SerializerOptions.indexes allows boolean | null | undefined [#4862](https://github.com/axios/axios/pull/4862) +- Require interceptors to return values [#4874](https://github.com/axios/axios/pull/4874) +- Removed unused imports [#4949](https://github.com/axios/axios/pull/4949) +- Allow null indexes on formSerializer and paramsSerializer [#4960](https://github.com/axios/axios/pull/4960) + +### Chores +- Set permissions for GitHub actions [#4765](https://github.com/axios/axios/pull/4765) +- Included githubactions in the dependabot config [#4770](https://github.com/axios/axios/pull/4770) +- Included dependency review [#4771](https://github.com/axios/axios/pull/4771) +- Update security.md [#4784](https://github.com/axios/axios/pull/4784) +- Remove unnecessary spaces [#4854](https://github.com/axios/axios/pull/4854) +- Simplify the import path of AxiosError [#4875](https://github.com/axios/axios/pull/4875) +- Fix Gitpod dead link [#4941](https://github.com/axios/axios/pull/4941) +- Enable syntax highlighting for a code block [#4970](https://github.com/axios/axios/pull/4970) +- Using Logo Axios in Readme.md [#4993](https://github.com/axios/axios/pull/4993) +- Fix markup for note in README [#4825](https://github.com/axios/axios/pull/4825) +- Fix typo and formatting, add colons [#4853](https://github.com/axios/axios/pull/4853) +- Fix typo in readme [#4942](https://github.com/axios/axios/pull/4942) + +### Security + +- Update SECURITY.md [#4687](https://github.com/axios/axios/pull/4687) + +### Contributors to this release + +- [Bertrand Marron](https://github.com/tusbar) +- [Dmitriy Mozgovoy](https://github.com/DigitalBrainJS) +- [Dan Mooney](https://github.com/danmooney) +- [Michael Li](https://github.com/xiaoyu-tamu) +- [aong](https://github.com/yxwzaxns) +- [Des Preston](https://github.com/despreston) +- [Ted Robertson](https://github.com/tredondo) +- [zhoulixiang](https://github.com/zh-lx) +- [Arthur Fiorette](https://github.com/arthurfiorette) +- [Kumar Shanu](https://github.com/Kr-Shanu) +- [JALAL](https://github.com/JLL32) +- [Jingyi Lin](https://github.com/MageeLin) +- [Philipp Loose](https://github.com/phloose) +- [Alexander Shchukin](https://github.com/sashsvamir) +- [Dave Cardwell](https://github.com/davecardwell) +- [Cat Scarlet](https://github.com/catscarlet) +- [Luca Pizzini](https://github.com/lpizzinidev) +- [Kai](https://github.com/Schweinepriester) +- [Maxime Bargiel](https://github.com/mbargiel) +- [Brian Helba](https://github.com/brianhelba) +- [reslear](https://github.com/reslear) +- [Jamie Slome](https://github.com/JamieSlome) +- [Landro3](https://github.com/Landro3) +- [rafw87](https://github.com/rafw87) +- [Afzal Sayed](https://github.com/afzalsayed96) +- [Koki Oyatsu](https://github.com/kaishuu0123) +- [Dave](https://github.com/wangcch) +- [暴走老七](https://github.com/baozouai) +- [Spencer](https://github.com/spalger) +- [Adrian Wieprzkowicz](https://github.com/Argeento) +- [Jamie Telin](https://github.com/lejahmie) +- [毛呆](https://github.com/aweikalee) +- [Kirill Shakirov](https://github.com/turisap) +- [Rraji Abdelbari](https://github.com/estarossa0) +- [Jelle Schutter](https://github.com/jelleschutter) +- [Tom Ceuppens](https://github.com/KyorCode) +- [Johann Cooper](https://github.com/JohannCooper) +- [Dimitris Halatsis](https://github.com/mitsos1os) +- [chenjigeng](https://github.com/chenjigeng) +- [João Gabriel Quaresma](https://github.com/joaoGabriel55) +- [Victor Augusto](https://github.com/VictorAugDB) +- [neilnaveen](https://github.com/neilnaveen) +- [Pavlos](https://github.com/psmoros) +- [Kiryl Valkovich](https://github.com/visortelle) +- [Naveen](https://github.com/naveensrinivasan) +- [wenzheng](https://github.com/0x30) +- [hcwhan](https://github.com/hcwhan) +- [Bassel Rachid](https://github.com/basselworkforce) +- [Grégoire Pineau](https://github.com/lyrixx) +- [felipedamin](https://github.com/felipedamin) +- [Karl Horky](https://github.com/karlhorky) +- [Yue JIN](https://github.com/kingyue737) +- [Usman Ali Siddiqui](https://github.com/usman250994) +- [WD](https://github.com/techbirds) +- [Günther Foidl](https://github.com/gfoidl) +- [Stephen Jennings](https://github.com/jennings) +- [C.T.Lin](https://github.com/chentsulin) +- [mia-z](https://github.com/mia-z) +- [Parth Banathia](https://github.com/Parth0105) +- [parth0105pluang](https://github.com/parth0105pluang) +- [Marco Weber](https://github.com/mrcwbr) +- [Luca Pizzini](https://github.com/lpizzinidev) +- [Willian Agostini](https://github.com/WillianAgostini) +- [Huyen Nguyen](https://github.com/huyenltnguyen) \ No newline at end of file diff --git a/node_modules/axios/LICENSE b/node_modules/axios/LICENSE new file mode 100644 index 0000000..05006a5 --- /dev/null +++ b/node_modules/axios/LICENSE @@ -0,0 +1,7 @@ +# Copyright (c) 2014-present Matt Zabriskie & Collaborators + +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. diff --git a/node_modules/axios/MIGRATION_GUIDE.md b/node_modules/axios/MIGRATION_GUIDE.md new file mode 100644 index 0000000..ec3ae0d --- /dev/null +++ b/node_modules/axios/MIGRATION_GUIDE.md @@ -0,0 +1,3 @@ +# Migration Guide + +## 0.x.x -> 1.1.0 diff --git a/node_modules/axios/README.md b/node_modules/axios/README.md new file mode 100644 index 0000000..8cf834c --- /dev/null +++ b/node_modules/axios/README.md @@ -0,0 +1,1756 @@ + +

🥇 Gold sponsors

intra-mart

[1ページ目] CookBook の記事 intra-mart Developer Portal

dev.intra-mart.jp

+
Stytch

API-first authentication, authorization, and fraud prevention

Website | Documentation | Node.js

+
Principal Financial Group

We’re bound by one common purpose: to give you the financial tools, resources and information you ne...

www.principal.com

+
Buy Instagram Followers Twicsy

Buy real Instagram followers from Twicsy starting at only $2.97. Twicsy has been voted the best site...

twicsy.com

+
Descope

Hi, we're Descope! We are building something in the authentication space for app developers and...

Website | Docs | Community

+
Route4Me

Best Route Planning And Route Optimization Software

Explore | Free Trial | Contact

+
Buzzoid - Buy Instagram Followers

At Buzzoid, you can buy Instagram followers quickly, safely, and easily with just a few clicks. Rate...

buzzoid.com

+
Famety - Buy Instagram Followers

At Famety, you can grow your social media following quickly, safely, and easily with just a few clic...

www.famety.net

+
Poprey - Buy Instagram Likes

Buy Instagram Likes

poprey.com

+
Buy Youtube Subscribers

SS Market offers professional social media services that rapidly increase your YouTube subscriber co...

ssmarket.net

+
💜 Become a sponsor + 💜 Become a sponsor +
+ + +

+
+
+
+ +

Promise based HTTP client for the browser and node.js

+ +

+ Website • + Documentation +

+ +
+ +[![npm version](https://img.shields.io/npm/v/axios.svg?style=flat-square)](https://www.npmjs.org/package/axios) +[![CDNJS](https://img.shields.io/cdnjs/v/axios.svg?style=flat-square)](https://cdnjs.com/libraries/axios) +[![Build status](https://img.shields.io/github/actions/workflow/status/axios/axios/ci.yml?branch=v1.x&label=CI&logo=github&style=flat-square)](https://github.com/axios/axios/actions/workflows/ci.yml) +[![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod&style=flat-square)](https://gitpod.io/#https://github.com/axios/axios) +[![code coverage](https://img.shields.io/coveralls/mzabriskie/axios.svg?style=flat-square)](https://coveralls.io/r/mzabriskie/axios) +[![install size](https://img.shields.io/badge/dynamic/json?url=https://packagephobia.com/v2/api.json?p=axios&query=$.install.pretty&label=install%20size&style=flat-square)](https://packagephobia.now.sh/result?p=axios) +[![npm bundle size](https://img.shields.io/bundlephobia/minzip/axios?style=flat-square)](https://bundlephobia.com/package/axios@latest) +[![npm downloads](https://img.shields.io/npm/dm/axios.svg?style=flat-square)](https://npm-stat.com/charts.html?package=axios) +[![gitter chat](https://img.shields.io/gitter/room/mzabriskie/axios.svg?style=flat-square)](https://gitter.im/mzabriskie/axios) +[![code helpers](https://www.codetriage.com/axios/axios/badges/users.svg)](https://www.codetriage.com/axios/axios) +[![Known Vulnerabilities](https://snyk.io/test/npm/axios/badge.svg)](https://snyk.io/test/npm/axios) + + + + +
+ +## Table of Contents + + - [Features](#features) + - [Browser Support](#browser-support) + - [Installing](#installing) + - [Package manager](#package-manager) + - [CDN](#cdn) + - [Example](#example) + - [Axios API](#axios-api) + - [Request method aliases](#request-method-aliases) + - [Concurrency 👎](#concurrency-deprecated) + - [Creating an instance](#creating-an-instance) + - [Instance methods](#instance-methods) + - [Request Config](#request-config) + - [Response Schema](#response-schema) + - [Config Defaults](#config-defaults) + - [Global axios defaults](#global-axios-defaults) + - [Custom instance defaults](#custom-instance-defaults) + - [Config order of precedence](#config-order-of-precedence) + - [Interceptors](#interceptors) + - [Multiple Interceptors](#multiple-interceptors) + - [Handling Errors](#handling-errors) + - [Cancellation](#cancellation) + - [AbortController](#abortcontroller) + - [CancelToken 👎](#canceltoken-deprecated) + - [Using application/x-www-form-urlencoded format](#using-applicationx-www-form-urlencoded-format) + - [URLSearchParams](#urlsearchparams) + - [Query string](#query-string-older-browsers) + - [🆕 Automatic serialization](#-automatic-serialization-to-urlsearchparams) + - [Using multipart/form-data format](#using-multipartform-data-format) + - [FormData](#formdata) + - [🆕 Automatic serialization](#-automatic-serialization-to-formdata) + - [Files Posting](#files-posting) + - [HTML Form Posting](#-html-form-posting-browser) + - [🆕 Progress capturing](#-progress-capturing) + - [🆕 Rate limiting](#-progress-capturing) + - [🆕 AxiosHeaders](#-axiosheaders) + - [🔥 Fetch adapter](#-fetch-adapter) + - [🔥 Custom fetch](#-custom-fetch) + - [🔥 Using with Tauri](#-using-with-tauri) + - [🔥 Using with SvelteKit](#-using-with-sveltekit-) + - [Semver](#semver) + - [Promises](#promises) + - [TypeScript](#typescript) + - [Resources](#resources) + - [Credits](#credits) + - [License](#license) + +## Features + +- Make [XMLHttpRequests](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) from the browser +- Make [http](https://nodejs.org/api/http.html) requests from node.js +- Supports the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) API +- Intercept request and response +- Transform request and response data +- Cancel requests +- Automatic transforms for [JSON](https://www.json.org/json-en.html) data +- 🆕 Automatic data object serialization to `multipart/form-data` and `x-www-form-urlencoded` body encodings +- Client side support for protecting against [XSRF](https://en.wikipedia.org/wiki/Cross-site_request_forgery) + +## Browser Support + +![Chrome](https://raw.githubusercontent.com/alrra/browser-logos/main/src/chrome/chrome_48x48.png) | ![Firefox](https://raw.githubusercontent.com/alrra/browser-logos/main/src/firefox/firefox_48x48.png) | ![Safari](https://raw.githubusercontent.com/alrra/browser-logos/main/src/safari/safari_48x48.png) | ![Opera](https://raw.githubusercontent.com/alrra/browser-logos/main/src/opera/opera_48x48.png) | ![Edge](https://raw.githubusercontent.com/alrra/browser-logos/main/src/edge/edge_48x48.png) | +--- | --- | --- | --- | --- | +Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ | 11 ✔ | + +[![Browser Matrix](https://saucelabs.com/open_sauce/build_matrix/axios.svg)](https://saucelabs.com/u/axios) + +## Installing + +### Package manager + +Using npm: + +```bash +$ npm install axios +``` + +Using bower: + +```bash +$ bower install axios +``` + +Using yarn: + +```bash +$ yarn add axios +``` + +Using pnpm: + +```bash +$ pnpm add axios +``` + +Using bun: + +```bash +$ bun add axios +``` + +Once the package is installed, you can import the library using `import` or `require` approach: + +```js +import axios, {isCancel, AxiosError} from 'axios'; +``` + +You can also use the default export, since the named export is just a re-export from the Axios factory: + +```js +import axios from 'axios'; + +console.log(axios.isCancel('something')); +```` + +If you use `require` for importing, **only default export is available**: + +```js +const axios = require('axios'); + +console.log(axios.isCancel('something')); +``` + +For some bundlers and some ES6 linters you may need to do the following: + +```js +import { default as axios } from 'axios'; +``` + +For cases where something went wrong when trying to import a module into a custom or legacy environment, +you can try importing the module package directly: + +```js +const axios = require('axios/dist/browser/axios.cjs'); // browser commonJS bundle (ES2017) +// const axios = require('axios/dist/node/axios.cjs'); // node commonJS bundle (ES2017) +``` + +### CDN + +Using jsDelivr CDN (ES5 UMD browser module): + +```html + +``` + +Using unpkg CDN: + +```html + +``` + +## Example + +> **Note**: CommonJS usage +> In order to gain the TypeScript typings (for intellisense / autocomplete) while using CommonJS imports with `require()`, use the following approach: + +```js +import axios from 'axios'; +//const axios = require('axios'); // legacy way + +// Make a request for a user with a given ID +axios.get('/user?ID=12345') + .then(function (response) { + // handle success + console.log(response); + }) + .catch(function (error) { + // handle error + console.log(error); + }) + .finally(function () { + // always executed + }); + +// Optionally the request above could also be done as +axios.get('/user', { + params: { + ID: 12345 + } + }) + .then(function (response) { + console.log(response); + }) + .catch(function (error) { + console.log(error); + }) + .finally(function () { + // always executed + }); + +// Want to use async/await? Add the `async` keyword to your outer function/method. +async function getUser() { + try { + const response = await axios.get('/user?ID=12345'); + console.log(response); + } catch (error) { + console.error(error); + } +} +``` + +> **Note**: `async/await` is part of ECMAScript 2017 and is not supported in Internet +> Explorer and older browsers, so use with caution. + +Performing a `POST` request + +```js +axios.post('/user', { + firstName: 'Fred', + lastName: 'Flintstone' + }) + .then(function (response) { + console.log(response); + }) + .catch(function (error) { + console.log(error); + }); +``` + +Performing multiple concurrent requests + +```js +function getUserAccount() { + return axios.get('/user/12345'); +} + +function getUserPermissions() { + return axios.get('/user/12345/permissions'); +} + +Promise.all([getUserAccount(), getUserPermissions()]) + .then(function (results) { + const acct = results[0]; + const perm = results[1]; + }); +``` + +## axios API + +Requests can be made by passing the relevant config to `axios`. + +##### axios(config) + +```js +// Send a POST request +axios({ + method: 'post', + url: '/user/12345', + data: { + firstName: 'Fred', + lastName: 'Flintstone' + } +}); +``` + +```js +// GET request for remote image in node.js +axios({ + method: 'get', + url: 'https://bit.ly/2mTM3nY', + responseType: 'stream' +}) + .then(function (response) { + response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) + }); +``` + +##### axios(url[, config]) + +```js +// Send a GET request (default method) +axios('/user/12345'); +``` + +### Request method aliases + +For convenience, aliases have been provided for all common request methods. + +##### axios.request(config) +##### axios.get(url[, config]) +##### axios.delete(url[, config]) +##### axios.head(url[, config]) +##### axios.options(url[, config]) +##### axios.post(url[, data[, config]]) +##### axios.put(url[, data[, config]]) +##### axios.patch(url[, data[, config]]) + +###### NOTE +When using the alias methods `url`, `method`, and `data` properties don't need to be specified in config. + +### Concurrency (Deprecated) +Please use `Promise.all` to replace the below functions. + +Helper functions for dealing with concurrent requests. + +axios.all(iterable) +axios.spread(callback) + +### Creating an instance + +You can create a new instance of axios with a custom config. + +##### axios.create([config]) + +```js +const instance = axios.create({ + baseURL: 'https://some-domain.com/api/', + timeout: 1000, + headers: {'X-Custom-Header': 'foobar'} +}); +``` + +### Instance methods + +The available instance methods are listed below. The specified config will be merged with the instance config. + +##### axios#request(config) +##### axios#get(url[, config]) +##### axios#delete(url[, config]) +##### axios#head(url[, config]) +##### axios#options(url[, config]) +##### axios#post(url[, data[, config]]) +##### axios#put(url[, data[, config]]) +##### axios#patch(url[, data[, config]]) +##### axios#getUri([config]) + +## Request Config + +These are the available config options for making requests. Only the `url` is required. Requests will default to `GET` if `method` is not specified. + +```js +{ + // `url` is the server URL that will be used for the request + url: '/user', + + // `method` is the request method to be used when making the request + method: 'get', // default + + // `baseURL` will be prepended to `url` unless `url` is absolute and option `allowAbsoluteUrls` is set to true. + // It can be convenient to set `baseURL` for an instance of axios to pass relative URLs + // to methods of that instance. + baseURL: 'https://some-domain.com/api/', + + // `allowAbsoluteUrls` determines whether or not absolute URLs will override a configured `baseUrl`. + // When set to true (default), absolute values for `url` will override `baseUrl`. + // When set to false, absolute values for `url` will always be prepended by `baseUrl`. + allowAbsoluteUrls: true, + + // `transformRequest` allows changes to the request data before it is sent to the server + // This is only applicable for request methods 'PUT', 'POST', 'PATCH' and 'DELETE' + // The last function in the array must return a string or an instance of Buffer, ArrayBuffer, + // FormData or Stream + // You may modify the headers object. + transformRequest: [function (data, headers) { + // Do whatever you want to transform the data + + return data; + }], + + // `transformResponse` allows changes to the response data to be made before + // it is passed to then/catch + transformResponse: [function (data) { + // Do whatever you want to transform the data + + return data; + }], + + // `headers` are custom headers to be sent + headers: {'X-Requested-With': 'XMLHttpRequest'}, + + // `params` are the URL parameters to be sent with the request + // Must be a plain object or a URLSearchParams object + params: { + ID: 12345 + }, + + // `paramsSerializer` is an optional config that allows you to customize serializing `params`. + paramsSerializer: { + + // Custom encoder function which sends key/value pairs in an iterative fashion. + encode?: (param: string): string => { /* Do custom operations here and return transformed string */ }, + + // Custom serializer function for the entire parameter. Allows user to mimic pre 1.x behaviour. + serialize?: (params: Record, options?: ParamsSerializerOptions ), + + // Configuration for formatting array indexes in the params. + indexes: false // Three available options: (1) indexes: null (leads to no brackets), (2) (default) indexes: false (leads to empty brackets), (3) indexes: true (leads to brackets with indexes). + }, + + // `data` is the data to be sent as the request body + // Only applicable for request methods 'PUT', 'POST', 'DELETE , and 'PATCH' + // When no `transformRequest` is set, must be of one of the following types: + // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams + // - Browser only: FormData, File, Blob + // - Node only: Stream, Buffer, FormData (form-data package) + data: { + firstName: 'Fred' + }, + + // syntax alternative to send data into the body + // method post + // only the value is sent, not the key + data: 'Country=Brasil&City=Belo Horizonte', + + // `timeout` specifies the number of milliseconds before the request times out. + // If the request takes longer than `timeout`, the request will be aborted. + timeout: 1000, // default is `0` (no timeout) + + // `withCredentials` indicates whether or not cross-site Access-Control requests + // should be made using credentials + withCredentials: false, // default + + // `adapter` allows custom handling of requests which makes testing easier. + // Return a promise and supply a valid response (see lib/adapters/README.md) + adapter: function (config) { + /* ... */ + }, + // Also, you can set the name of the built-in adapter, or provide an array with their names + // to choose the first available in the environment + adapter: 'xhr', // 'fetch' | 'http' | ['xhr', 'http', 'fetch'] + + // `auth` indicates that HTTP Basic auth should be used, and supplies credentials. + // This will set an `Authorization` header, overwriting any existing + // `Authorization` custom headers you have set using `headers`. + // Please note that only HTTP Basic auth is configurable through this parameter. + // For Bearer tokens and such, use `Authorization` custom headers instead. + auth: { + username: 'janedoe', + password: 's00pers3cret' + }, + + // `responseType` indicates the type of data that the server will respond with + // options are: 'arraybuffer', 'document', 'json', 'text', 'stream' + // browser only: 'blob' + responseType: 'json', // default + + // `responseEncoding` indicates encoding to use for decoding responses (Node.js only) + // Note: Ignored for `responseType` of 'stream' or client-side requests + // options are: 'ascii', 'ASCII', 'ansi', 'ANSI', 'binary', 'BINARY', 'base64', 'BASE64', 'base64url', + // 'BASE64URL', 'hex', 'HEX', 'latin1', 'LATIN1', 'ucs-2', 'UCS-2', 'ucs2', 'UCS2', 'utf-8', 'UTF-8', + // 'utf8', 'UTF8', 'utf16le', 'UTF16LE' + responseEncoding: 'utf8', // default + + // `xsrfCookieName` is the name of the cookie to use as a value for xsrf token + xsrfCookieName: 'XSRF-TOKEN', // default + + // `xsrfHeaderName` is the name of the http header that carries the xsrf token value + xsrfHeaderName: 'X-XSRF-TOKEN', // default + + // `undefined` (default) - set XSRF header only for the same origin requests + withXSRFToken: boolean | undefined | ((config: InternalAxiosRequestConfig) => boolean | undefined), + + // `onUploadProgress` allows handling of progress events for uploads + // browser & node.js + onUploadProgress: function ({loaded, total, progress, bytes, estimated, rate, upload = true}) { + // Do whatever you want with the Axios progress event + }, + + // `onDownloadProgress` allows handling of progress events for downloads + // browser & node.js + onDownloadProgress: function ({loaded, total, progress, bytes, estimated, rate, download = true}) { + // Do whatever you want with the Axios progress event + }, + + // `maxContentLength` defines the max size of the http response content in bytes allowed in node.js + maxContentLength: 2000, + + // `maxBodyLength` (Node only option) defines the max size of the http request content in bytes allowed + maxBodyLength: 2000, + + // `validateStatus` defines whether to resolve or reject the promise for a given + // HTTP response status code. If `validateStatus` returns `true` (or is set to `null` + // or `undefined`), the promise will be resolved; otherwise, the promise will be + // rejected. + validateStatus: function (status) { + return status >= 200 && status < 300; // default + }, + + // `maxRedirects` defines the maximum number of redirects to follow in node.js. + // If set to 0, no redirects will be followed. + maxRedirects: 21, // default + + // `beforeRedirect` defines a function that will be called before redirect. + // Use this to adjust the request options upon redirecting, + // to inspect the latest response headers, + // or to cancel the request by throwing an error + // If maxRedirects is set to 0, `beforeRedirect` is not used. + beforeRedirect: (options, { headers }) => { + if (options.hostname === "example.com") { + options.auth = "user:password"; + } + }, + + // `socketPath` defines a UNIX Socket to be used in node.js. + // e.g. '/var/run/docker.sock' to send requests to the docker daemon. + // Only either `socketPath` or `proxy` can be specified. + // If both are specified, `socketPath` is used. + socketPath: null, // default + + // `transport` determines the transport method that will be used to make the request. + // If defined, it will be used. Otherwise, if `maxRedirects` is 0, + // the default `http` or `https` library will be used, depending on the protocol specified in `protocol`. + // Otherwise, the `httpFollow` or `httpsFollow` library will be used, again depending on the protocol, + // which can handle redirects. + transport: undefined, // default + + // `httpAgent` and `httpsAgent` define a custom agent to be used when performing http + // and https requests, respectively, in node.js. This allows options to be added like + // `keepAlive` that are not enabled by default before Node.js v19.0.0. After Node.js + // v19.0.0, you no longer need to customize the agent to enable `keepAlive` because + // `http.globalAgent` has `keepAlive` enabled by default. + httpAgent: new http.Agent({ keepAlive: true }), + httpsAgent: new https.Agent({ keepAlive: true }), + + // `proxy` defines the hostname, port, and protocol of the proxy server. + // You can also define your proxy using the conventional `http_proxy` and + // `https_proxy` environment variables. If you are using environment variables + // for your proxy configuration, you can also define a `no_proxy` environment + // variable as a comma-separated list of domains that should not be proxied. + // Use `false` to disable proxies, ignoring environment variables. + // `auth` indicates that HTTP Basic auth should be used to connect to the proxy, and + // supplies credentials. + // This will set an `Proxy-Authorization` header, overwriting any existing + // `Proxy-Authorization` custom headers you have set using `headers`. + // If the proxy server uses HTTPS, then you must set the protocol to `https`. + proxy: { + protocol: 'https', + host: '127.0.0.1', + // hostname: '127.0.0.1' // Takes precedence over 'host' if both are defined + port: 9000, + auth: { + username: 'mikeymike', + password: 'rapunz3l' + } + }, + + // `cancelToken` specifies a cancel token that can be used to cancel the request + // (see Cancellation section below for details) + cancelToken: new CancelToken(function (cancel) { + }), + + // an alternative way to cancel Axios requests using AbortController + signal: new AbortController().signal, + + // `decompress` indicates whether or not the response body should be decompressed + // automatically. If set to `true` will also remove the 'content-encoding' header + // from the responses objects of all decompressed responses + // - Node only (XHR cannot turn off decompression) + decompress: true, // default + + // `insecureHTTPParser` boolean. + // Indicates where to use an insecure HTTP parser that accepts invalid HTTP headers. + // This may allow interoperability with non-conformant HTTP implementations. + // Using the insecure parser should be avoided. + // see options https://nodejs.org/dist/latest-v12.x/docs/api/http.html#http_http_request_url_options_callback + // see also https://nodejs.org/en/blog/vulnerability/february-2020-security-releases/#strict-http-header-parsing-none + insecureHTTPParser: undefined, // default + + // transitional options for backward compatibility that may be removed in the newer versions + transitional: { + // silent JSON parsing mode + // `true` - ignore JSON parsing errors and set response.data to null if parsing failed (old behaviour) + // `false` - throw SyntaxError if JSON parsing failed (Note: responseType must be set to 'json') + silentJSONParsing: true, // default value for the current Axios version + + // try to parse the response string as JSON even if `responseType` is not 'json' + forcedJSONParsing: true, + + // throw ETIMEDOUT error instead of generic ECONNABORTED on request timeouts + clarifyTimeoutError: false, + }, + + env: { + // The FormData class to be used to automatically serialize the payload into a FormData object + FormData: window?.FormData || global?.FormData + }, + + formSerializer: { + visitor: (value, key, path, helpers) => {}; // custom visitor function to serialize form values + dots: boolean; // use dots instead of brackets format + metaTokens: boolean; // keep special endings like {} in parameter key + indexes: boolean; // array indexes format null - no brackets, false - empty brackets, true - brackets with indexes + }, + + // http adapter only (node.js) + maxRate: [ + 100 * 1024, // 100KB/s upload limit, + 100 * 1024 // 100KB/s download limit + ] +} +``` + +## Response Schema + +The response for a request contains the following information. + +```js +{ + // `data` is the response that was provided by the server + data: {}, + + // `status` is the HTTP status code from the server response + status: 200, + + // `statusText` is the HTTP status message from the server response + statusText: 'OK', + + // `headers` the HTTP headers that the server responded with + // All header names are lowercase and can be accessed using the bracket notation. + // Example: `response.headers['content-type']` + headers: {}, + + // `config` is the config that was provided to `axios` for the request + config: {}, + + // `request` is the request that generated this response + // It is the last ClientRequest instance in node.js (in redirects) + // and an XMLHttpRequest instance in the browser + request: {} +} +``` + +When using `then`, you will receive the response as follows: + +```js +axios.get('/user/12345') + .then(function (response) { + console.log(response.data); + console.log(response.status); + console.log(response.statusText); + console.log(response.headers); + console.log(response.config); + }); +``` + +When using `catch`, or passing a [rejection callback](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then) as second parameter of `then`, the response will be available through the `error` object as explained in the [Handling Errors](#handling-errors) section. + +## Config Defaults + +You can specify config defaults that will be applied to every request. + +### Global axios defaults + +```js +axios.defaults.baseURL = 'https://api.example.com'; + +// Important: If axios is used with multiple domains, the AUTH_TOKEN will be sent to all of them. +// See below for an example using Custom instance defaults instead. +axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; + +axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; +``` + +### Custom instance defaults + +```js +// Set config defaults when creating the instance +const instance = axios.create({ + baseURL: 'https://api.example.com' +}); + +// Alter defaults after instance has been created +instance.defaults.headers.common['Authorization'] = AUTH_TOKEN; +``` + +### Config order of precedence + +Config will be merged with an order of precedence. The order is library defaults found in [lib/defaults/index.js](https://github.com/axios/axios/blob/main/lib/defaults/index.js#L49), then `defaults` property of the instance, and finally `config` argument for the request. The latter will take precedence over the former. Here's an example. + +```js +// Create an instance using the config defaults provided by the library +// At this point the timeout config value is `0` as is the default for the library +const instance = axios.create(); + +// Override timeout default for the library +// Now all requests using this instance will wait 2.5 seconds before timing out +instance.defaults.timeout = 2500; + +// Override timeout for this request as it's known to take a long time +instance.get('/longRequest', { + timeout: 5000 +}); +``` + +## Interceptors + +You can intercept requests or responses before they are handled by `then` or `catch`. + +```js + +const instance = axios.create(); + +// Add a request interceptor +instance.interceptors.request.use(function (config) { + // Do something before request is sent + return config; + }, function (error) { + // Do something with request error + return Promise.reject(error); + }); + +// Add a response interceptor +instance.interceptors.response.use(function (response) { + // Any status code that lie within the range of 2xx cause this function to trigger + // Do something with response data + return response; + }, function (error) { + // Any status codes that falls outside the range of 2xx cause this function to trigger + // Do something with response error + return Promise.reject(error); + }); +``` + +If you need to remove an interceptor later you can. + +```js +const instance = axios.create(); +const myInterceptor = instance.interceptors.request.use(function () {/*...*/}); +axios.interceptors.request.eject(myInterceptor); +``` + +You can also clear all interceptors for requests or responses. +```js +const instance = axios.create(); +instance.interceptors.request.use(function () {/*...*/}); +instance.interceptors.request.clear(); // Removes interceptors from requests +instance.interceptors.response.use(function () {/*...*/}); +instance.interceptors.response.clear(); // Removes interceptors from responses +``` + +You can add interceptors to a custom instance of axios. + +```js +const instance = axios.create(); +instance.interceptors.request.use(function () {/*...*/}); +``` + +When you add request interceptors, they are presumed to be asynchronous by default. This can cause a delay +in the execution of your axios request when the main thread is blocked (a promise is created under the hood for +the interceptor and your request gets put on the bottom of the call stack). If your request interceptors are synchronous you can add a flag +to the options object that will tell axios to run the code synchronously and avoid any delays in request execution. + +```js +axios.interceptors.request.use(function (config) { + config.headers.test = 'I am only a header!'; + return config; +}, null, { synchronous: true }); +``` + +If you want to execute a particular interceptor based on a runtime check, +you can add a `runWhen` function to the options object. The request interceptor will not be executed **if and only if** the return +of `runWhen` is `false`. The function will be called with the config +object (don't forget that you can bind your own arguments to it as well.) This can be handy when you have an +asynchronous request interceptor that only needs to run at certain times. + +```js +function onGetCall(config) { + return config.method === 'get'; +} +axios.interceptors.request.use(function (config) { + config.headers.test = 'special get headers'; + return config; +}, null, { runWhen: onGetCall }); +``` + +> **Note:** options parameter(having `synchronous` and `runWhen` properties) is only supported for request interceptors at the moment. + +### Multiple Interceptors + +Given you add multiple response interceptors +and when the response was fulfilled +- then each interceptor is executed +- then they are executed in the order they were added +- then only the last interceptor's result is returned +- then every interceptor receives the result of its predecessor +- and when the fulfillment-interceptor throws + - then the following fulfillment-interceptor is not called + - then the following rejection-interceptor is called + - once caught, another following fulfill-interceptor is called again (just like in a promise chain). + +Read [the interceptor tests](./test/specs/interceptors.spec.js) for seeing all this in code. + +## Error Types + +There are many different axios error messages that can appear that can provide basic information about the specifics of the error and where opportunities may lie in debugging. + +The general structure of axios errors is as follows: +| Property | Definition | +| -------- | ---------- | +| message | A quick summary of the error message and the status it failed with. | +| name | This defines where the error originated from. For axios, it will always be an 'AxiosError'. | +| stack | Provides the stack trace of the error. | +| config | An axios config object with specific instance configurations defined by the user from when the request was made | +| code | Represents an axios identified error. The table below lists out specific definitions for internal axios error. | +| status | HTTP response status code. See [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) for common HTTP response status code meanings. + +Below is a list of potential axios identified error: + +| Code | Definition | +| --- | --- | +| ERR_BAD_OPTION_VALUE | Invalid value provided in axios configuration. | +| ERR_BAD_OPTION | Invalid option provided in axios configuration. | +| ERR_NOT_SUPPORT | Feature or method not supported in the current axios environment. | +| ERR_DEPRECATED | Deprecated feature or method used in axios. | +| ERR_INVALID_URL | Invalid URL provided for axios request. | +| ECONNABORTED | Typically indicates that the request has been timed out (unless `transitional.clarifyTimeoutError` is set) or aborted by the browser or its plugin. | +| ERR_CANCELED | Feature or method is canceled explicitly by the user using an AbortSignal (or a CancelToken). | +| ETIMEDOUT | Request timed out due to exceeding default axios timelimit. `transitional.clarifyTimeoutError` must be set to `true`, otherwise a generic `ECONNABORTED` error will be thrown instead. | +| ERR_NETWORK | Network-related issue. In the browser, this error can also be caused by a [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/Guides/CORS) or [Mixed Content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) policy violation. The browser does not allow the JS code to clarify the real reason for the error caused by security issues, so please check the console. | +| ERR_FR_TOO_MANY_REDIRECTS | Request is redirected too many times; exceeds max redirects specified in axios configuration. | +| ERR_BAD_RESPONSE | Response cannot be parsed properly or is in an unexpected format. Usually related to a response with `5xx` status code. | +| ERR_BAD_REQUEST | The request has an unexpected format or is missing required parameters. Usually related to a response with `4xx` status code. | + +## Handling Errors + +the default behavior is to reject every response that returns with a status code that falls out of the range of 2xx and treat it as an error. + +```js +axios.get('/user/12345') + .catch(function (error) { + if (error.response) { + // The request was made and the server responded with a status code + // that falls out of the range of 2xx + console.log(error.response.data); + console.log(error.response.status); + console.log(error.response.headers); + } else if (error.request) { + // The request was made but no response was received + // `error.request` is an instance of XMLHttpRequest in the browser and an instance of + // http.ClientRequest in node.js + console.log(error.request); + } else { + // Something happened in setting up the request that triggered an Error + console.log('Error', error.message); + } + console.log(error.config); + }); +``` + +Using the `validateStatus` config option, you can override the default condition (status >= 200 && status < 300) and define HTTP code(s) that should throw an error. + +```js +axios.get('/user/12345', { + validateStatus: function (status) { + return status < 500; // Resolve only if the status code is less than 500 + } +}) +``` + +Using `toJSON` you get an object with more information about the HTTP error. + +```js +axios.get('/user/12345') + .catch(function (error) { + console.log(error.toJSON()); + }); +``` + +## Cancellation + +### AbortController + +Starting from `v0.22.0` Axios supports AbortController to cancel requests in fetch API way: + +```js +const controller = new AbortController(); + +axios.get('/foo/bar', { + signal: controller.signal +}).then(function(response) { + //... +}); +// cancel the request +controller.abort() +``` + +### CancelToken `👎deprecated` + +You can also cancel a request using a *CancelToken*. + +> The axios cancel token API is based on the withdrawn [cancellable promises proposal](https://github.com/tc39/proposal-cancelable-promises). + +> This API is deprecated since v0.22.0 and shouldn't be used in new projects + +You can create a cancel token using the `CancelToken.source` factory as shown below: + +```js +const CancelToken = axios.CancelToken; +const source = CancelToken.source(); + +axios.get('/user/12345', { + cancelToken: source.token +}).catch(function (thrown) { + if (axios.isCancel(thrown)) { + console.log('Request canceled', thrown.message); + } else { + // handle error + } +}); + +axios.post('/user/12345', { + name: 'new name' +}, { + cancelToken: source.token +}) + +// cancel the request (the message parameter is optional) +source.cancel('Operation canceled by the user.'); +``` + +You can also create a cancel token by passing an executor function to the `CancelToken` constructor: + +```js +const CancelToken = axios.CancelToken; +let cancel; + +axios.get('/user/12345', { + cancelToken: new CancelToken(function executor(c) { + // An executor function receives a cancel function as a parameter + cancel = c; + }) +}); + +// cancel the request +cancel(); +``` + +> **Note:** you can cancel several requests with the same cancel token/abort controller. +> If a cancellation token is already cancelled at the moment of starting an Axios request, then the request is cancelled immediately, without any attempts to make a real request. + +> During the transition period, you can use both cancellation APIs, even for the same request: + +## Using `application/x-www-form-urlencoded` format + +### URLSearchParams + +By default, axios serializes JavaScript objects to `JSON`. To send data in the [`application/x-www-form-urlencoded` format](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) instead, you can use the [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) API, which is [supported](http://www.caniuse.com/#feat=urlsearchparams) in the vast majority of browsers,and [ Node](https://nodejs.org/api/url.html#url_class_urlsearchparams) starting with v10 (released in 2018). + +```js +const params = new URLSearchParams({ foo: 'bar' }); +params.append('extraparam', 'value'); +axios.post('/foo', params); +``` + +### Query string (Older browsers) + +For compatibility with very old browsers, there is a [polyfill](https://github.com/WebReflection/url-search-params) available (make sure to polyfill the global environment). + +Alternatively, you can encode data using the [`qs`](https://github.com/ljharb/qs) library: + +```js +const qs = require('qs'); +axios.post('/foo', qs.stringify({ 'bar': 123 })); +``` + +Or in another way (ES6), + +```js +import qs from 'qs'; +const data = { 'bar': 123 }; +const options = { + method: 'POST', + headers: { 'content-type': 'application/x-www-form-urlencoded' }, + data: qs.stringify(data), + url, +}; +axios(options); +``` + +### Older Node.js versions + +For older Node.js engines, you can use the [`querystring`](https://nodejs.org/api/querystring.html) module as follows: + +```js +const querystring = require('querystring'); +axios.post('https://something.com/', querystring.stringify({ foo: 'bar' })); +``` + +You can also use the [`qs`](https://github.com/ljharb/qs) library. + +> **Note**: The `qs` library is preferable if you need to stringify nested objects, as the `querystring` method has [known issues](https://github.com/nodejs/node-v0.x-archive/issues/1665) with that use case. + +### 🆕 Automatic serialization to URLSearchParams + +Axios will automatically serialize the data object to urlencoded format if the content-type header is set to "application/x-www-form-urlencoded". + +```js +const data = { + x: 1, + arr: [1, 2, 3], + arr2: [1, [2], 3], + users: [{name: 'Peter', surname: 'Griffin'}, {name: 'Thomas', surname: 'Anderson'}], +}; + +await axios.postForm('https://postman-echo.com/post', data, + {headers: {'content-type': 'application/x-www-form-urlencoded'}} +); +``` + +The server will handle it as: + +```js + { + x: '1', + 'arr[]': [ '1', '2', '3' ], + 'arr2[0]': '1', + 'arr2[1][0]': '2', + 'arr2[2]': '3', + 'arr3[]': [ '1', '2', '3' ], + 'users[0][name]': 'Peter', + 'users[0][surname]': 'griffin', + 'users[1][name]': 'Thomas', + 'users[1][surname]': 'Anderson' + } +```` + +If your backend body-parser (like `body-parser` of `express.js`) supports nested objects decoding, you will get the same object on the server-side automatically + +```js + var app = express(); + + app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies + + app.post('/', function (req, res, next) { + // echo body as JSON + res.send(JSON.stringify(req.body)); + }); + + server = app.listen(3000); +``` + +## Using `multipart/form-data` format + +### FormData + +To send the data as a `multipart/formdata` you need to pass a formData instance as a payload. +Setting the `Content-Type` header is not required as Axios guesses it based on the payload type. + +```js +const formData = new FormData(); +formData.append('foo', 'bar'); + +axios.post('https://httpbin.org/post', formData); +``` + +In node.js, you can use the [`form-data`](https://github.com/form-data/form-data) library as follows: + +```js +const FormData = require('form-data'); + +const form = new FormData(); +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_file', fs.createReadStream('/foo/bar.jpg')); + +axios.post('https://example.com', form) +``` + +### 🆕 Automatic serialization to FormData + +Starting from `v0.27.0`, Axios supports automatic object serialization to a FormData object if the request `Content-Type` +header is set to `multipart/form-data`. + +The following request will submit the data in a FormData format (Browser & Node.js): + +```js +import axios from 'axios'; + +axios.post('https://httpbin.org/post', {x: 1}, { + headers: { + 'Content-Type': 'multipart/form-data' + } +}).then(({data}) => console.log(data)); +``` + +In the `node.js` build, the ([`form-data`](https://github.com/form-data/form-data)) polyfill is used by default. + +You can overload the FormData class by setting the `env.FormData` config variable, +but you probably won't need it in most cases: + +```js +const axios = require('axios'); +var FormData = require('form-data'); + +axios.post('https://httpbin.org/post', {x: 1, buf: new Buffer(10)}, { + headers: { + 'Content-Type': 'multipart/form-data' + } +}).then(({data}) => console.log(data)); +``` + +Axios FormData serializer supports some special endings to perform the following operations: + +- `{}` - serialize the value with JSON.stringify +- `[]` - unwrap the array-like object as separate fields with the same key + +> **Note**: unwrap/expand operation will be used by default on arrays and FileList objects + +FormData serializer supports additional options via `config.formSerializer: object` property to handle rare cases: + +- `visitor: Function` - user-defined visitor function that will be called recursively to serialize the data object +to a `FormData` object by following custom rules. + +- `dots: boolean = false` - use dot notation instead of brackets to serialize arrays and objects; + +- `metaTokens: boolean = true` - add the special ending (e.g `user{}: '{"name": "John"}'`) in the FormData key. +The back-end body-parser could potentially use this meta-information to automatically parse the value as JSON. + +- `indexes: null|false|true = false` - controls how indexes will be added to unwrapped keys of `flat` array-like objects. + + - `null` - don't add brackets (`arr: 1`, `arr: 2`, `arr: 3`) + - `false`(default) - add empty brackets (`arr[]: 1`, `arr[]: 2`, `arr[]: 3`) + - `true` - add brackets with indexes (`arr[0]: 1`, `arr[1]: 2`, `arr[2]: 3`) + +Let's say we have an object like this one: + +```js +const obj = { + x: 1, + arr: [1, 2, 3], + arr2: [1, [2], 3], + users: [{name: 'Peter', surname: 'Griffin'}, {name: 'Thomas', surname: 'Anderson'}], + 'obj2{}': [{x:1}] +}; +``` + +The following steps will be executed by the Axios serializer internally: + +```js +const formData = new FormData(); +formData.append('x', '1'); +formData.append('arr[]', '1'); +formData.append('arr[]', '2'); +formData.append('arr[]', '3'); +formData.append('arr2[0]', '1'); +formData.append('arr2[1][0]', '2'); +formData.append('arr2[2]', '3'); +formData.append('users[0][name]', 'Peter'); +formData.append('users[0][surname]', 'Griffin'); +formData.append('users[1][name]', 'Thomas'); +formData.append('users[1][surname]', 'Anderson'); +formData.append('obj2{}', '[{"x":1}]'); +``` + +Axios supports the following shortcut methods: `postForm`, `putForm`, `patchForm` +which are just the corresponding http methods with the `Content-Type` header preset to `multipart/form-data`. + +## Files Posting + +You can easily submit a single file: + +```js +await axios.postForm('https://httpbin.org/post', { + 'myVar' : 'foo', + 'file': document.querySelector('#fileInput').files[0] +}); +``` + +or multiple files as `multipart/form-data`: + +```js +await axios.postForm('https://httpbin.org/post', { + 'files[]': document.querySelector('#fileInput').files +}); +``` + +`FileList` object can be passed directly: + +```js +await axios.postForm('https://httpbin.org/post', document.querySelector('#fileInput').files) +``` + +All files will be sent with the same field names: `files[]`. + +## 🆕 HTML Form Posting (browser) + +Pass HTML Form element as a payload to submit it as `multipart/form-data` content. + +```js +await axios.postForm('https://httpbin.org/post', document.querySelector('#htmlForm')); +``` + +`FormData` and `HTMLForm` objects can also be posted as `JSON` by explicitly setting the `Content-Type` header to `application/json`: + +```js +await axios.post('https://httpbin.org/post', document.querySelector('#htmlForm'), { + headers: { + 'Content-Type': 'application/json' + } +}) +``` + +For example, the Form + +```html +
+ + + + + + + + + +
+``` + +will be submitted as the following JSON object: + +```js +{ + "foo": "1", + "deep": { + "prop": { + "spaced": "3" + } + }, + "baz": [ + "4", + "5" + ], + "user": { + "age": "value2" + } +} +```` + +Sending `Blobs`/`Files` as JSON (`base64`) is not currently supported. + +## 🆕 Progress capturing + +Axios supports both browser and node environments to capture request upload/download progress. +The frequency of progress events is forced to be limited to `3` times per second. + +```js +await axios.post(url, data, { + onUploadProgress: function (axiosProgressEvent) { + /*{ + loaded: number; + total?: number; + progress?: number; // in range [0..1] + bytes: number; // how many bytes have been transferred since the last trigger (delta) + estimated?: number; // estimated time in seconds + rate?: number; // upload speed in bytes + upload: true; // upload sign + }*/ + }, + + onDownloadProgress: function (axiosProgressEvent) { + /*{ + loaded: number; + total?: number; + progress?: number; + bytes: number; + estimated?: number; + rate?: number; // download speed in bytes + download: true; // download sign + }*/ + } +}); +``` + +You can also track stream upload/download progress in node.js: + +```js +const {data} = await axios.post(SERVER_URL, readableStream, { + onUploadProgress: ({progress}) => { + console.log((progress * 100).toFixed(2)); + }, + + headers: { + 'Content-Length': contentLength + }, + + maxRedirects: 0 // avoid buffering the entire stream +}); +```` + +> **Note:** +> Capturing FormData upload progress is not currently supported in node.js environments. + +> **⚠️ Warning** +> It is recommended to disable redirects by setting maxRedirects: 0 to upload the stream in the **node.js** environment, +> as follow-redirects package will buffer the entire stream in RAM without following the "backpressure" algorithm. + + +## 🆕 Rate limiting + +Download and upload rate limits can only be set for the http adapter (node.js): + +```js +const {data} = await axios.post(LOCAL_SERVER_URL, myBuffer, { + onUploadProgress: ({progress, rate}) => { + console.log(`Upload [${(progress*100).toFixed(2)}%]: ${(rate / 1024).toFixed(2)}KB/s`) + }, + + maxRate: [100 * 1024], // 100KB/s limit +}); +``` + +## 🆕 AxiosHeaders + +Axios has its own `AxiosHeaders` class to manipulate headers using a Map-like API that guarantees caseless work. +Although HTTP is case-insensitive in headers, Axios will retain the case of the original header for stylistic reasons +and for a workaround when servers mistakenly consider the header's case. +The old approach of directly manipulating headers object is still available, but deprecated and not recommended for future usage. + +### Working with headers + +An AxiosHeaders object instance can contain different types of internal values. that control setting and merging logic. +The final headers object with string values is obtained by Axios by calling the `toJSON` method. + +> Note: By JSON here we mean an object consisting only of string values intended to be sent over the network. + +The header value can be one of the following types: +- `string` - normal string value that will be sent to the server +- `null` - skip header when rendering to JSON +- `false` - skip header when rendering to JSON, additionally indicates that `set` method must be called with `rewrite` option set to `true` + to overwrite this value (Axios uses this internally to allow users to opt out of installing certain headers like `User-Agent` or `Content-Type`) +- `undefined` - value is not set + +> Note: The header value is considered set if it is not equal to undefined. + +The headers object is always initialized inside interceptors and transformers: + +```ts + axios.interceptors.request.use((request: InternalAxiosRequestConfig) => { + request.headers.set('My-header', 'value'); + + request.headers.set({ + "My-set-header1": "my-set-value1", + "My-set-header2": "my-set-value2" + }); + + request.headers.set('User-Agent', false); // disable subsequent setting the header by Axios + + request.headers.setContentType('text/plain'); + + request.headers['My-set-header2'] = 'newValue' // direct access is deprecated + + return request; + } + ); +```` + +You can iterate over an `AxiosHeaders` instance using a `for...of` statement: + +````js +const headers = new AxiosHeaders({ + foo: '1', + bar: '2', + baz: '3' +}); + +for(const [header, value] of headers) { + console.log(header, value); +} + +// foo 1 +// bar 2 +// baz 3 +```` + +### new AxiosHeaders(headers?) + +Constructs a new `AxiosHeaders` instance. + +``` +constructor(headers?: RawAxiosHeaders | AxiosHeaders | string); +``` + +If the headers object is a string, it will be parsed as RAW HTTP headers. + +````js +const headers = new AxiosHeaders(` +Host: www.bing.com +User-Agent: curl/7.54.0 +Accept: */*`); + +console.log(headers); + +// Object [AxiosHeaders] { +// host: 'www.bing.com', +// 'user-agent': 'curl/7.54.0', +// accept: '*/*' +// } +```` + +### AxiosHeaders#set + +```ts +set(headerName, value: Axios, rewrite?: boolean); +set(headerName, value, rewrite?: (this: AxiosHeaders, value: string, name: string, headers: RawAxiosHeaders) => boolean); +set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean); +``` + +The `rewrite` argument controls the overwriting behavior: +- `false` - do not overwrite if header's value is set (is not `undefined`) +- `undefined` (default) - overwrite the header unless its value is set to `false` +- `true` - rewrite anyway + +The option can also accept a user-defined function that determines whether the value should be overwritten or not. + +Returns `this`. + +### AxiosHeaders#get(header) + +``` + get(headerName: string, matcher?: true | AxiosHeaderMatcher): AxiosHeaderValue; + get(headerName: string, parser: RegExp): RegExpExecArray | null; +```` + +Returns the internal value of the header. It can take an extra argument to parse the header's value with `RegExp.exec`, +matcher function or internal key-value parser. + +```ts +const headers = new AxiosHeaders({ + 'Content-Type': 'multipart/form-data; boundary=Asrf456BGe4h' +}); + +console.log(headers.get('Content-Type')); +// multipart/form-data; boundary=Asrf456BGe4h + +console.log(headers.get('Content-Type', true)); // parse key-value pairs from a string separated with \s,;= delimiters: +// [Object: null prototype] { +// 'multipart/form-data': undefined, +// boundary: 'Asrf456BGe4h' +// } + + +console.log(headers.get('Content-Type', (value, name, headers) => { + return String(value).replace(/a/g, 'ZZZ'); +})); +// multipZZZrt/form-dZZZtZZZ; boundZZZry=Asrf456BGe4h + +console.log(headers.get('Content-Type', /boundary=(\w+)/)?.[0]); +// boundary=Asrf456BGe4h + +``` + +Returns the value of the header. + +### AxiosHeaders#has(header, matcher?) + +``` +has(header: string, matcher?: AxiosHeaderMatcher): boolean; +``` + +Returns `true` if the header is set (has no `undefined` value). + +### AxiosHeaders#delete(header, matcher?) + +``` +delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; +``` + +Returns `true` if at least one header has been removed. + +### AxiosHeaders#clear(matcher?) + +``` +clear(matcher?: AxiosHeaderMatcher): boolean; +``` + +Removes all headers. +Unlike the `delete` method matcher, this optional matcher will be used to match against the header name rather than the value. + +```ts +const headers = new AxiosHeaders({ + 'foo': '1', + 'x-foo': '2', + 'x-bar': '3', +}); + +console.log(headers.clear(/^x-/)); // true + +console.log(headers.toJSON()); // [Object: null prototype] { foo: '1' } +``` + +Returns `true` if at least one header has been cleared. + +### AxiosHeaders#normalize(format); + +If the headers object was changed directly, it can have duplicates with the same name but in different cases. +This method normalizes the headers object by combining duplicate keys into one. +Axios uses this method internally after calling each interceptor. +Set `format` to true for converting headers name to lowercase and capitalize the initial letters (`cOntEnt-type` => `Content-Type`) + +```js +const headers = new AxiosHeaders({ + 'foo': '1', +}); + +headers.Foo = '2'; +headers.FOO = '3'; + +console.log(headers.toJSON()); // [Object: null prototype] { foo: '1', Foo: '2', FOO: '3' } +console.log(headers.normalize().toJSON()); // [Object: null prototype] { foo: '3' } +console.log(headers.normalize(true).toJSON()); // [Object: null prototype] { Foo: '3' } +``` + +Returns `this`. + +### AxiosHeaders#concat(...targets) + +``` +concat(...targets: Array): AxiosHeaders; +``` + +Merges the instance with targets into a new `AxiosHeaders` instance. If the target is a string, it will be parsed as RAW HTTP headers. + +Returns a new `AxiosHeaders` instance. + +### AxiosHeaders#toJSON(asStrings?) + +```` +toJSON(asStrings?: boolean): RawAxiosHeaders; +```` + +Resolve all internal headers values into a new null prototype object. +Set `asStrings` to true to resolve arrays as a string containing all elements, separated by commas. + +### AxiosHeaders.from(thing?) + +```` +from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; +```` + +Returns a new `AxiosHeaders` instance created from the raw headers passed in, +or simply returns the given headers object if it's an `AxiosHeaders` instance. + +### AxiosHeaders.concat(...targets) + +```` +concat(...targets: Array): AxiosHeaders; +```` + +Returns a new `AxiosHeaders` instance created by merging the target objects. + +### Shortcuts + +The following shortcuts are available: + +- `setContentType`, `getContentType`, `hasContentType` + +- `setContentLength`, `getContentLength`, `hasContentLength` + +- `setAccept`, `getAccept`, `hasAccept` + +- `setUserAgent`, `getUserAgent`, `hasUserAgent` + +- `setContentEncoding`, `getContentEncoding`, `hasContentEncoding` + +## 🔥 Fetch adapter + +Fetch adapter was introduced in `v1.7.0`. By default, it will be used if `xhr` and `http` adapters are not available in the build, +or not supported by the environment. +To use it by default, it must be selected explicitly: + +```js +const {data} = axios.get(url, { + adapter: 'fetch' // by default ['xhr', 'http', 'fetch'] +}) +``` + +You can create a separate instance for this: + +```js +const fetchAxios = axios.create({ + adapter: 'fetch' +}); + +const {data} = fetchAxios.get(url); +``` + +The adapter supports the same functionality as `xhr` adapter, **including upload and download progress capturing**. +Also, it supports additional response types such as `stream` and `formdata` (if supported by the environment). + +### 🔥 Custom fetch + +Starting from `v1.12.0`, you can customize the fetch adapter to use a custom fetch API instead of environment globals. +You can pass a custom `fetch` function, `Request`, and `Response` constructors via env config. +This can be helpful in case of custom environments & app frameworks. + +Also, when using a custom fetch, you may need to set custom Request and Response too. If you don't set them, global objects will be used. +If your custom fetch api does not have these objects, and the globals are incompatible with a custom fetch, +you must disable their use inside the fetch adapter by passing null. + +> Note: Setting `Request` & `Response` to `null` will make it impossible for the fetch adapter to capture the upload & download progress. + +Basic example: + +```js +import customFetchFunction from 'customFetchModule'; + +const instance = axios.create({ + adapter: 'fetch', + onDownloadProgress(e) { + console.log('downloadProgress', e); + }, + env: { + fetch: customFetchFunction, + Request: null, // undefined -> use the global constructor + Response: null + } +}); +``` + +#### 🔥 Using with Tauri + +A minimal example of setting up Axios for use in a [Tauri](https://tauri.app/plugin/http-client/) app with a platform fetch function that ignores CORS policy for requests. + +```js +import { fetch } from "@tauri-apps/plugin-http"; +import axios from "axios"; + +const instance = axios.create({ + adapter: 'fetch', + onDownloadProgress(e) { + console.log('downloadProgress', e); + }, + env: { + fetch + } +}); + + const {data} = await instance.get("https://google.com"); +``` + +#### 🔥 Using with SvelteKit + +[SvelteKit](https://svelte.dev/docs/kit/web-standards#Fetch-APIs) framework has a custom implementation of the fetch function for server rendering (so called `load` functions), and also uses relative paths, +which makes it incompatible with the standard URL API. So, Axios must be configured to use the custom fetch API: + +```js +export async function load({ fetch }) { + const {data: post} = await axios.get('https://jsonplaceholder.typicode.com/posts/1', { + adapter: 'fetch', + env: { + fetch, + Request: null, + Response: null + } + }); + + return { post }; +} +``` + +## Semver + +Since Axios has reached a `v.1.0.0` we will fully embrace semver as per the spec [here](https://semver.org/) + +## Promises + +axios depends on a native ES6 Promise implementation to be [supported](https://caniuse.com/promises). +If your environment doesn't support ES6 Promises, you can [polyfill](https://github.com/jakearchibald/es6-promise). + +## TypeScript + +axios includes [TypeScript](https://typescriptlang.org) definitions and a type guard for axios errors. + +```typescript +let user: User = null; +try { + const { data } = await axios.get('/user?ID=12345'); + user = data.userDetails; +} catch (error) { + if (axios.isAxiosError(error)) { + handleAxiosError(error); + } else { + handleUnexpectedError(error); + } +} +``` + +Because axios dual publishes with an ESM default export and a CJS `module.exports`, there are some caveats. +The recommended setting is to use `"moduleResolution": "node16"` (this is implied by `"module": "node16"`). Note that this requires TypeScript 4.7 or greater. +If use ESM, your settings should be fine. +If you compile TypeScript to CJS and you can’t use `"moduleResolution": "node 16"`, you have to enable `esModuleInterop`. +If you use TypeScript to type check CJS JavaScript code, your only option is to use `"moduleResolution": "node16"`. + +## Online one-click setup + +You can use Gitpod, an online IDE(which is free for Open Source) for contributing or running the examples online. + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/axios/axios/blob/main/examples/server.js) + + +## Resources + +* [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) +* [Ecosystem](https://github.com/axios/axios/blob/v1.x/ECOSYSTEM.md) +* [Contributing Guide](https://github.com/axios/axios/blob/v1.x/CONTRIBUTING.md) +* [Code of Conduct](https://github.com/axios/axios/blob/v1.x/CODE_OF_CONDUCT.md) + +## Credits + +axios is heavily inspired by the [$http service](https://docs.angularjs.org/api/ng/service/$http) provided in [AngularJS](https://angularjs.org/). Ultimately axios is an effort to provide a standalone `$http`-like service for use outside of AngularJS. + +## License + +[MIT](LICENSE) diff --git a/node_modules/axios/dist/axios.js b/node_modules/axios/dist/axios.js new file mode 100644 index 0000000..b65237a --- /dev/null +++ b/node_modules/axios/dist/axios.js @@ -0,0 +1,4396 @@ +/*! Axios v1.12.2 Copyright (c) 2025 Matt Zabriskie and contributors */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.axios = factory()); +})(this, (function () { 'use strict'; + + function _AsyncGenerator(e) { + var r, t; + function resume(r, t) { + try { + var n = e[r](t), + o = n.value, + u = o instanceof _OverloadYield; + Promise.resolve(u ? o.v : o).then(function (t) { + if (u) { + var i = "return" === r ? "return" : "next"; + if (!o.k || t.done) return resume(i, t); + t = e[i](t).value; + } + settle(n.done ? "return" : "normal", t); + }, function (e) { + resume("throw", e); + }); + } catch (e) { + settle("throw", e); + } + } + function settle(e, n) { + switch (e) { + case "return": + r.resolve({ + value: n, + done: !0 + }); + break; + case "throw": + r.reject(n); + break; + default: + r.resolve({ + value: n, + done: !1 + }); + } + (r = r.next) ? resume(r.key, r.arg) : t = null; + } + this._invoke = function (e, n) { + return new Promise(function (o, u) { + var i = { + key: e, + arg: n, + resolve: o, + reject: u, + next: null + }; + t ? t = t.next = i : (r = t = i, resume(e, n)); + }); + }, "function" != typeof e.return && (this.return = void 0); + } + _AsyncGenerator.prototype["function" == typeof Symbol && Symbol.asyncIterator || "@@asyncIterator"] = function () { + return this; + }, _AsyncGenerator.prototype.next = function (e) { + return this._invoke("next", e); + }, _AsyncGenerator.prototype.throw = function (e) { + return this._invoke("throw", e); + }, _AsyncGenerator.prototype.return = function (e) { + return this._invoke("return", e); + }; + function _OverloadYield(t, e) { + this.v = t, this.k = e; + } + function _asyncGeneratorDelegate(t) { + var e = {}, + n = !1; + function pump(e, r) { + return n = !0, r = new Promise(function (n) { + n(t[e](r)); + }), { + done: !1, + value: new _OverloadYield(r, 1) + }; + } + return e["undefined" != typeof Symbol && Symbol.iterator || "@@iterator"] = function () { + return this; + }, e.next = function (t) { + return n ? (n = !1, t) : pump("next", t); + }, "function" == typeof t.throw && (e.throw = function (t) { + if (n) throw n = !1, t; + return pump("throw", t); + }), "function" == typeof t.return && (e.return = function (t) { + return n ? (n = !1, t) : pump("return", t); + }), e; + } + function _asyncIterator(r) { + var n, + t, + o, + e = 2; + for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) { + if (t && null != (n = r[t])) return n.call(r); + if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r)); + t = "@@asyncIterator", o = "@@iterator"; + } + throw new TypeError("Object is not async iterable"); + } + function AsyncFromSyncIterator(r) { + function AsyncFromSyncIteratorContinuation(r) { + if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); + var n = r.done; + return Promise.resolve(r.value).then(function (r) { + return { + value: r, + done: n + }; + }); + } + return AsyncFromSyncIterator = function (r) { + this.s = r, this.n = r.next; + }, AsyncFromSyncIterator.prototype = { + s: null, + n: null, + next: function () { + return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); + }, + return: function (r) { + var n = this.s.return; + return void 0 === n ? Promise.resolve({ + value: r, + done: !0 + }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); + }, + throw: function (r) { + var n = this.s.return; + return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); + } + }, new AsyncFromSyncIterator(r); + } + function _awaitAsyncGenerator(e) { + return new _OverloadYield(e, 0); + } + function _iterableToArrayLimit(r, l) { + var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; + if (null != t) { + var e, + n, + i, + u, + a = [], + f = !0, + o = !1; + try { + if (i = (t = t.call(r)).next, 0 === l) { + if (Object(t) !== t) return; + f = !1; + } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); + } catch (r) { + o = !0, n = r; + } finally { + try { + if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; + } finally { + if (o) throw n; + } + } + return a; + } + } + function ownKeys(e, r) { + var t = Object.keys(e); + if (Object.getOwnPropertySymbols) { + var o = Object.getOwnPropertySymbols(e); + r && (o = o.filter(function (r) { + return Object.getOwnPropertyDescriptor(e, r).enumerable; + })), t.push.apply(t, o); + } + return t; + } + function _objectSpread2(e) { + for (var r = 1; r < arguments.length; r++) { + var t = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { + _defineProperty(e, r, t[r]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { + Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); + }); + } + return e; + } + function _regeneratorRuntime() { + _regeneratorRuntime = function () { + return e; + }; + var t, + e = {}, + r = Object.prototype, + n = r.hasOwnProperty, + o = Object.defineProperty || function (t, e, r) { + t[e] = r.value; + }, + i = "function" == typeof Symbol ? Symbol : {}, + a = i.iterator || "@@iterator", + c = i.asyncIterator || "@@asyncIterator", + u = i.toStringTag || "@@toStringTag"; + function define(t, e, r) { + return Object.defineProperty(t, e, { + value: r, + enumerable: !0, + configurable: !0, + writable: !0 + }), t[e]; + } + try { + define({}, ""); + } catch (t) { + define = function (t, e, r) { + return t[e] = r; + }; + } + function wrap(t, e, r, n) { + var i = e && e.prototype instanceof Generator ? e : Generator, + a = Object.create(i.prototype), + c = new Context(n || []); + return o(a, "_invoke", { + value: makeInvokeMethod(t, r, c) + }), a; + } + function tryCatch(t, e, r) { + try { + return { + type: "normal", + arg: t.call(e, r) + }; + } catch (t) { + return { + type: "throw", + arg: t + }; + } + } + e.wrap = wrap; + var h = "suspendedStart", + l = "suspendedYield", + f = "executing", + s = "completed", + y = {}; + function Generator() {} + function GeneratorFunction() {} + function GeneratorFunctionPrototype() {} + var p = {}; + define(p, a, function () { + return this; + }); + var d = Object.getPrototypeOf, + v = d && d(d(values([]))); + v && v !== r && n.call(v, a) && (p = v); + var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); + function defineIteratorMethods(t) { + ["next", "throw", "return"].forEach(function (e) { + define(t, e, function (t) { + return this._invoke(e, t); + }); + }); + } + function AsyncIterator(t, e) { + function invoke(r, o, i, a) { + var c = tryCatch(t[r], t, o); + if ("throw" !== c.type) { + var u = c.arg, + h = u.value; + return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { + invoke("next", t, i, a); + }, function (t) { + invoke("throw", t, i, a); + }) : e.resolve(h).then(function (t) { + u.value = t, i(u); + }, function (t) { + return invoke("throw", t, i, a); + }); + } + a(c.arg); + } + var r; + o(this, "_invoke", { + value: function (t, n) { + function callInvokeWithMethodAndArg() { + return new e(function (e, r) { + invoke(t, n, e, r); + }); + } + return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); + } + }); + } + function makeInvokeMethod(e, r, n) { + var o = h; + return function (i, a) { + if (o === f) throw new Error("Generator is already running"); + if (o === s) { + if ("throw" === i) throw a; + return { + value: t, + done: !0 + }; + } + for (n.method = i, n.arg = a;;) { + var c = n.delegate; + if (c) { + var u = maybeInvokeDelegate(c, n); + if (u) { + if (u === y) continue; + return u; + } + } + if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { + if (o === h) throw o = s, n.arg; + n.dispatchException(n.arg); + } else "return" === n.method && n.abrupt("return", n.arg); + o = f; + var p = tryCatch(e, r, n); + if ("normal" === p.type) { + if (o = n.done ? s : l, p.arg === y) continue; + return { + value: p.arg, + done: n.done + }; + } + "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); + } + }; + } + function maybeInvokeDelegate(e, r) { + var n = r.method, + o = e.iterator[n]; + if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; + var i = tryCatch(o, e.iterator, r.arg); + if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; + var a = i.arg; + return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); + } + function pushTryEntry(t) { + var e = { + tryLoc: t[0] + }; + 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); + } + function resetTryEntry(t) { + var e = t.completion || {}; + e.type = "normal", delete e.arg, t.completion = e; + } + function Context(t) { + this.tryEntries = [{ + tryLoc: "root" + }], t.forEach(pushTryEntry, this), this.reset(!0); + } + function values(e) { + if (e || "" === e) { + var r = e[a]; + if (r) return r.call(e); + if ("function" == typeof e.next) return e; + if (!isNaN(e.length)) { + var o = -1, + i = function next() { + for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; + return next.value = t, next.done = !0, next; + }; + return i.next = i; + } + } + throw new TypeError(typeof e + " is not iterable"); + } + return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { + value: GeneratorFunctionPrototype, + configurable: !0 + }), o(GeneratorFunctionPrototype, "constructor", { + value: GeneratorFunction, + configurable: !0 + }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { + var e = "function" == typeof t && t.constructor; + return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); + }, e.mark = function (t) { + return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; + }, e.awrap = function (t) { + return { + __await: t + }; + }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { + return this; + }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { + void 0 === i && (i = Promise); + var a = new AsyncIterator(wrap(t, r, n, o), i); + return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { + return t.done ? t.value : a.next(); + }); + }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { + return this; + }), define(g, "toString", function () { + return "[object Generator]"; + }), e.keys = function (t) { + var e = Object(t), + r = []; + for (var n in e) r.push(n); + return r.reverse(), function next() { + for (; r.length;) { + var t = r.pop(); + if (t in e) return next.value = t, next.done = !1, next; + } + return next.done = !0, next; + }; + }, e.values = values, Context.prototype = { + constructor: Context, + reset: function (e) { + if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); + }, + stop: function () { + this.done = !0; + var t = this.tryEntries[0].completion; + if ("throw" === t.type) throw t.arg; + return this.rval; + }, + dispatchException: function (e) { + if (this.done) throw e; + var r = this; + function handle(n, o) { + return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; + } + for (var o = this.tryEntries.length - 1; o >= 0; --o) { + var i = this.tryEntries[o], + a = i.completion; + if ("root" === i.tryLoc) return handle("end"); + if (i.tryLoc <= this.prev) { + var c = n.call(i, "catchLoc"), + u = n.call(i, "finallyLoc"); + if (c && u) { + if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); + if (this.prev < i.finallyLoc) return handle(i.finallyLoc); + } else if (c) { + if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); + } else { + if (!u) throw new Error("try statement without catch or finally"); + if (this.prev < i.finallyLoc) return handle(i.finallyLoc); + } + } + } + }, + abrupt: function (t, e) { + for (var r = this.tryEntries.length - 1; r >= 0; --r) { + var o = this.tryEntries[r]; + if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { + var i = o; + break; + } + } + i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); + var a = i ? i.completion : {}; + return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); + }, + complete: function (t, e) { + if ("throw" === t.type) throw t.arg; + return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; + }, + finish: function (t) { + for (var e = this.tryEntries.length - 1; e >= 0; --e) { + var r = this.tryEntries[e]; + if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; + } + }, + catch: function (t) { + for (var e = this.tryEntries.length - 1; e >= 0; --e) { + var r = this.tryEntries[e]; + if (r.tryLoc === t) { + var n = r.completion; + if ("throw" === n.type) { + var o = n.arg; + resetTryEntry(r); + } + return o; + } + } + throw new Error("illegal catch attempt"); + }, + delegateYield: function (e, r, n) { + return this.delegate = { + iterator: values(e), + resultName: r, + nextLoc: n + }, "next" === this.method && (this.arg = t), y; + } + }, e; + } + function _toPrimitive(t, r) { + if ("object" != typeof t || !t) return t; + var e = t[Symbol.toPrimitive]; + if (void 0 !== e) { + var i = e.call(t, r || "default"); + if ("object" != typeof i) return i; + throw new TypeError("@@toPrimitive must return a primitive value."); + } + return ("string" === r ? String : Number)(t); + } + function _toPropertyKey(t) { + var i = _toPrimitive(t, "string"); + return "symbol" == typeof i ? i : String(i); + } + function _typeof(o) { + "@babel/helpers - typeof"; + + return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { + return typeof o; + } : function (o) { + return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; + }, _typeof(o); + } + function _wrapAsyncGenerator(fn) { + return function () { + return new _AsyncGenerator(fn.apply(this, arguments)); + }; + } + function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } + } + function _asyncToGenerator(fn) { + return function () { + var self = this, + args = arguments; + return new Promise(function (resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + _next(undefined); + }); + }; + } + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); + } + } + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + Object.defineProperty(Constructor, "prototype", { + writable: false + }); + return Constructor; + } + function _defineProperty(obj, key, value) { + key = _toPropertyKey(key); + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; + } + function _slicedToArray(arr, i) { + return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); + } + function _toConsumableArray(arr) { + return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); + } + function _arrayWithoutHoles(arr) { + if (Array.isArray(arr)) return _arrayLikeToArray(arr); + } + function _arrayWithHoles(arr) { + if (Array.isArray(arr)) return arr; + } + function _iterableToArray(iter) { + if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); + } + function _unsupportedIterableToArray(o, minLen) { + if (!o) return; + if (typeof o === "string") return _arrayLikeToArray(o, minLen); + var n = Object.prototype.toString.call(o).slice(8, -1); + if (n === "Object" && o.constructor) n = o.constructor.name; + if (n === "Map" || n === "Set") return Array.from(o); + if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); + } + function _arrayLikeToArray(arr, len) { + if (len == null || len > arr.length) len = arr.length; + for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; + return arr2; + } + function _nonIterableSpread() { + throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + function _nonIterableRest() { + throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + function _createForOfIteratorHelper(o, allowArrayLike) { + var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; + if (!it) { + if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { + if (it) o = it; + var i = 0; + var F = function () {}; + return { + s: F, + n: function () { + if (i >= o.length) return { + done: true + }; + return { + done: false, + value: o[i++] + }; + }, + e: function (e) { + throw e; + }, + f: F + }; + } + throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); + } + var normalCompletion = true, + didErr = false, + err; + return { + s: function () { + it = it.call(o); + }, + n: function () { + var step = it.next(); + normalCompletion = step.done; + return step; + }, + e: function (e) { + didErr = true; + err = e; + }, + f: function () { + try { + if (!normalCompletion && it.return != null) it.return(); + } finally { + if (didErr) throw err; + } + } + }; + } + + function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; + } + + // utils is a library of generic helper functions non-specific to axios + + var toString = Object.prototype.toString; + var getPrototypeOf = Object.getPrototypeOf; + var iterator = Symbol.iterator, + toStringTag = Symbol.toStringTag; + var kindOf = function (cache) { + return function (thing) { + var str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); + }; + }(Object.create(null)); + var kindOfTest = function kindOfTest(type) { + type = type.toLowerCase(); + return function (thing) { + return kindOf(thing) === type; + }; + }; + var typeOfTest = function typeOfTest(type) { + return function (thing) { + return _typeof(thing) === type; + }; + }; + + /** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * + * @returns {boolean} True if value is an Array, otherwise false + */ + var isArray = Array.isArray; + + /** + * Determine if a value is undefined + * + * @param {*} val The value to test + * + * @returns {boolean} True if the value is undefined, otherwise false + */ + var isUndefined = typeOfTest('undefined'); + + /** + * Determine if a value is a Buffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Buffer, otherwise false + */ + function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); + } + + /** + * Determine if a value is an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ + var isArrayBuffer = kindOfTest('ArrayBuffer'); + + /** + * Determine if a value is a view on an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ + function isArrayBufferView(val) { + var result; + if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) { + result = ArrayBuffer.isView(val); + } else { + result = val && val.buffer && isArrayBuffer(val.buffer); + } + return result; + } + + /** + * Determine if a value is a String + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a String, otherwise false + */ + var isString = typeOfTest('string'); + + /** + * Determine if a value is a Function + * + * @param {*} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ + var isFunction$1 = typeOfTest('function'); + + /** + * Determine if a value is a Number + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Number, otherwise false + */ + var isNumber = typeOfTest('number'); + + /** + * Determine if a value is an Object + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an Object, otherwise false + */ + var isObject = function isObject(thing) { + return thing !== null && _typeof(thing) === 'object'; + }; + + /** + * Determine if a value is a Boolean + * + * @param {*} thing The value to test + * @returns {boolean} True if value is a Boolean, otherwise false + */ + var isBoolean = function isBoolean(thing) { + return thing === true || thing === false; + }; + + /** + * Determine if a value is a plain Object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a plain Object, otherwise false + */ + var isPlainObject = function isPlainObject(val) { + if (kindOf(val) !== 'object') { + return false; + } + var prototype = getPrototypeOf(val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); + }; + + /** + * Determine if a value is an empty object (safely handles Buffers) + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an empty object, otherwise false + */ + var isEmptyObject = function isEmptyObject(val) { + // Early return for non-objects or Buffers to prevent RangeError + if (!isObject(val) || isBuffer(val)) { + return false; + } + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + // Fallback for any other objects that might cause RangeError with Object.keys() + return false; + } + }; + + /** + * Determine if a value is a Date + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Date, otherwise false + */ + var isDate = kindOfTest('Date'); + + /** + * Determine if a value is a File + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ + var isFile = kindOfTest('File'); + + /** + * Determine if a value is a Blob + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Blob, otherwise false + */ + var isBlob = kindOfTest('Blob'); + + /** + * Determine if a value is a FileList + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ + var isFileList = kindOfTest('FileList'); + + /** + * Determine if a value is a Stream + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Stream, otherwise false + */ + var isStream = function isStream(val) { + return isObject(val) && isFunction$1(val.pipe); + }; + + /** + * Determine if a value is a FormData + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an FormData, otherwise false + */ + var isFormData = function isFormData(thing) { + var kind; + return thing && (typeof FormData === 'function' && thing instanceof FormData || isFunction$1(thing.append) && ((kind = kindOf(thing)) === 'formdata' || + // detect form-data instance + kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]')); + }; + + /** + * Determine if a value is a URLSearchParams object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ + var isURLSearchParams = kindOfTest('URLSearchParams'); + var _map = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest), + _map2 = _slicedToArray(_map, 4), + isReadableStream = _map2[0], + isRequest = _map2[1], + isResponse = _map2[2], + isHeaders = _map2[3]; + + /** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * + * @returns {String} The String freed of excess whitespace + */ + var trim = function trim(str) { + return str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + }; + + /** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + * + * @param {Boolean} [allOwnKeys = false] + * @returns {any} + */ + function forEach(obj, fn) { + var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, + _ref$allOwnKeys = _ref.allOwnKeys, + allOwnKeys = _ref$allOwnKeys === void 0 ? false : _ref$allOwnKeys; + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + var i; + var l; + + // Force an array if not already something iterable + if (_typeof(obj) !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + if (isArray(obj)) { + // Iterate over array values + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Buffer check + if (isBuffer(obj)) { + return; + } + + // Iterate over object keys + var keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + var len = keys.length; + var key; + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } + } + function findKey(obj, key) { + if (isBuffer(obj)) { + return null; + } + key = key.toLowerCase(); + var keys = Object.keys(obj); + var i = keys.length; + var _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; + } + var _global = function () { + /*eslint no-undef:0*/ + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : typeof window !== 'undefined' ? window : global; + }(); + var isContextDefined = function isContextDefined(context) { + return !isUndefined(context) && context !== _global; + }; + + /** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * + * @returns {Object} Result of all merge properties + */ + function merge( /* obj1, obj2, obj3, ... */ + ) { + var _ref2 = isContextDefined(this) && this || {}, + caseless = _ref2.caseless, + skipUndefined = _ref2.skipUndefined; + var result = {}; + var assignValue = function assignValue(val, key) { + var targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + }; + for (var i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; + } + + /** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * + * @param {Boolean} [allOwnKeys] + * @returns {Object} The resulting value of object a + */ + var extend = function extend(a, b, thisArg) { + var _ref3 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}, + allOwnKeys = _ref3.allOwnKeys; + forEach(b, function (val, key) { + if (thisArg && isFunction$1(val)) { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }, { + allOwnKeys: allOwnKeys + }); + return a; + }; + + /** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * + * @returns {string} content value without BOM + */ + var stripBOM = function stripBOM(content) { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; + }; + + /** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + * + * @returns {void} + */ + var inherits = function inherits(constructor, superConstructor, props, descriptors) { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + Object.defineProperty(constructor, 'super', { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); + }; + + /** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function|Boolean} [filter] + * @param {Function} [propFilter] + * + * @returns {Object} + */ + var toFlatObject = function toFlatObject(sourceObj, destObj, filter, propFilter) { + var props; + var i; + var prop; + var merged = {}; + destObj = destObj || {}; + // eslint-disable-next-line no-eq-null,eqeqeq + if (sourceObj == null) return destObj; + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + return destObj; + }; + + /** + * Determines whether a string ends with the characters of a specified string + * + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * + * @returns {boolean} + */ + var endsWith = function endsWith(str, searchString, position) { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + var lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; + }; + + /** + * Returns new array from array like object or null if failed + * + * @param {*} [thing] + * + * @returns {?Array} + */ + var toArray = function toArray(thing) { + if (!thing) return null; + if (isArray(thing)) return thing; + var i = thing.length; + if (!isNumber(i)) return null; + var arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; + }; + + /** + * Checking if the Uint8Array exists and if it does, it returns a function that checks if the + * thing passed in is an instance of Uint8Array + * + * @param {TypedArray} + * + * @returns {Array} + */ + // eslint-disable-next-line func-names + var isTypedArray = function (TypedArray) { + // eslint-disable-next-line func-names + return function (thing) { + return TypedArray && thing instanceof TypedArray; + }; + }(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); + + /** + * For each entry in the object, call the function with the key and value. + * + * @param {Object} obj - The object to iterate over. + * @param {Function} fn - The function to call for each entry. + * + * @returns {void} + */ + var forEachEntry = function forEachEntry(obj, fn) { + var generator = obj && obj[iterator]; + var _iterator = generator.call(obj); + var result; + while ((result = _iterator.next()) && !result.done) { + var pair = result.value; + fn.call(obj, pair[0], pair[1]); + } + }; + + /** + * It takes a regular expression and a string, and returns an array of all the matches + * + * @param {string} regExp - The regular expression to match against. + * @param {string} str - The string to search. + * + * @returns {Array} + */ + var matchAll = function matchAll(regExp, str) { + var matches; + var arr = []; + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + return arr; + }; + + /* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ + var isHTMLForm = kindOfTest('HTMLFormElement'); + var toCamelCase = function toCamelCase(str) { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + }); + }; + + /* Creating a function that will check if an object has a property. */ + var hasOwnProperty = function (_ref4) { + var hasOwnProperty = _ref4.hasOwnProperty; + return function (obj, prop) { + return hasOwnProperty.call(obj, prop); + }; + }(Object.prototype); + + /** + * Determine if a value is a RegExp object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a RegExp object, otherwise false + */ + var isRegExp = kindOfTest('RegExp'); + var reduceDescriptors = function reduceDescriptors(obj, reducer) { + var descriptors = Object.getOwnPropertyDescriptors(obj); + var reducedDescriptors = {}; + forEach(descriptors, function (descriptor, name) { + var ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + Object.defineProperties(obj, reducedDescriptors); + }; + + /** + * Makes all methods read-only + * @param {Object} obj + */ + + var freezeMethods = function freezeMethods(obj) { + reduceDescriptors(obj, function (descriptor, name) { + // skip restricted props in strict mode + if (isFunction$1(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { + return false; + } + var value = obj[name]; + if (!isFunction$1(value)) return; + descriptor.enumerable = false; + if ('writable' in descriptor) { + descriptor.writable = false; + return; + } + if (!descriptor.set) { + descriptor.set = function () { + throw Error('Can not rewrite read-only method \'' + name + '\''); + }; + } + }); + }; + var toObjectSet = function toObjectSet(arrayOrString, delimiter) { + var obj = {}; + var define = function define(arr) { + arr.forEach(function (value) { + obj[value] = true; + }); + }; + isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); + return obj; + }; + var noop = function noop() {}; + var toFiniteNumber = function toFiniteNumber(value, defaultValue) { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; + }; + + /** + * If the thing is a FormData object, return true, otherwise return false. + * + * @param {unknown} thing - The thing to check. + * + * @returns {boolean} + */ + function isSpecCompliantForm(thing) { + return !!(thing && isFunction$1(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); + } + var toJSONObject = function toJSONObject(obj) { + var stack = new Array(10); + var visit = function visit(source, i) { + if (isObject(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + + //Buffer check + if (isBuffer(source)) { + return source; + } + if (!('toJSON' in source)) { + stack[i] = source; + var target = isArray(source) ? [] : {}; + forEach(source, function (value, key) { + var reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + stack[i] = undefined; + return target; + } + } + return source; + }; + return visit(obj, 0); + }; + var isAsyncFn = kindOfTest('AsyncFunction'); + var isThenable = function isThenable(thing) { + return thing && (isObject(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing["catch"]); + }; + + // original code + // https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 + + var _setImmediate = function (setImmediateSupported, postMessageSupported) { + if (setImmediateSupported) { + return setImmediate; + } + return postMessageSupported ? function (token, callbacks) { + _global.addEventListener("message", function (_ref5) { + var source = _ref5.source, + data = _ref5.data; + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + return function (cb) { + callbacks.push(cb); + _global.postMessage(token, "*"); + }; + }("axios@".concat(Math.random()), []) : function (cb) { + return setTimeout(cb); + }; + }(typeof setImmediate === 'function', isFunction$1(_global.postMessage)); + var asap = typeof queueMicrotask !== 'undefined' ? queueMicrotask.bind(_global) : typeof process !== 'undefined' && process.nextTick || _setImmediate; + + // ********************* + + var isIterable = function isIterable(thing) { + return thing != null && isFunction$1(thing[iterator]); + }; + var utils$1 = { + isArray: isArray, + isArrayBuffer: isArrayBuffer, + isBuffer: isBuffer, + isFormData: isFormData, + isArrayBufferView: isArrayBufferView, + isString: isString, + isNumber: isNumber, + isBoolean: isBoolean, + isObject: isObject, + isPlainObject: isPlainObject, + isEmptyObject: isEmptyObject, + isReadableStream: isReadableStream, + isRequest: isRequest, + isResponse: isResponse, + isHeaders: isHeaders, + isUndefined: isUndefined, + isDate: isDate, + isFile: isFile, + isBlob: isBlob, + isRegExp: isRegExp, + isFunction: isFunction$1, + isStream: isStream, + isURLSearchParams: isURLSearchParams, + isTypedArray: isTypedArray, + isFileList: isFileList, + forEach: forEach, + merge: merge, + extend: extend, + trim: trim, + stripBOM: stripBOM, + inherits: inherits, + toFlatObject: toFlatObject, + kindOf: kindOf, + kindOfTest: kindOfTest, + endsWith: endsWith, + toArray: toArray, + forEachEntry: forEachEntry, + matchAll: matchAll, + isHTMLForm: isHTMLForm, + hasOwnProperty: hasOwnProperty, + hasOwnProp: hasOwnProperty, + // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors: reduceDescriptors, + freezeMethods: freezeMethods, + toObjectSet: toObjectSet, + toCamelCase: toCamelCase, + noop: noop, + toFiniteNumber: toFiniteNumber, + findKey: findKey, + global: _global, + isContextDefined: isContextDefined, + isSpecCompliantForm: isSpecCompliantForm, + toJSONObject: toJSONObject, + isAsyncFn: isAsyncFn, + isThenable: isThenable, + setImmediate: _setImmediate, + asap: asap, + isIterable: isIterable + }; + + /** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ + function AxiosError(message, code, config, request, response) { + Error.call(this); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = new Error().stack; + } + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status ? response.status : null; + } + } + utils$1.inherits(AxiosError, Error, { + toJSON: function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils$1.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } + }); + var prototype$1 = AxiosError.prototype; + var descriptors = {}; + ['ERR_BAD_OPTION_VALUE', 'ERR_BAD_OPTION', 'ECONNABORTED', 'ETIMEDOUT', 'ERR_NETWORK', 'ERR_FR_TOO_MANY_REDIRECTS', 'ERR_DEPRECATED', 'ERR_BAD_RESPONSE', 'ERR_BAD_REQUEST', 'ERR_CANCELED', 'ERR_NOT_SUPPORT', 'ERR_INVALID_URL' + // eslint-disable-next-line func-names + ].forEach(function (code) { + descriptors[code] = { + value: code + }; + }); + Object.defineProperties(AxiosError, descriptors); + Object.defineProperty(prototype$1, 'isAxiosError', { + value: true + }); + + // eslint-disable-next-line func-names + AxiosError.from = function (error, code, config, request, response, customProps) { + var axiosError = Object.create(prototype$1); + utils$1.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }, function (prop) { + return prop !== 'isAxiosError'; + }); + var msg = error && error.message ? error.message : 'Error'; + + // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED) + var errCode = code == null && error ? error.code : code; + AxiosError.call(axiosError, msg, errCode, config, request, response); + + // Chain the original error on the standard field; non-enumerable to avoid JSON noise + if (error && axiosError.cause == null) { + Object.defineProperty(axiosError, 'cause', { + value: error, + configurable: true + }); + } + axiosError.name = error && error.name || 'Error'; + customProps && Object.assign(axiosError, customProps); + return axiosError; + }; + + // eslint-disable-next-line strict + var httpAdapter = null; + + /** + * Determines if the given thing is a array or js object. + * + * @param {string} thing - The object or array to be visited. + * + * @returns {boolean} + */ + function isVisitable(thing) { + return utils$1.isPlainObject(thing) || utils$1.isArray(thing); + } + + /** + * It removes the brackets from the end of a string + * + * @param {string} key - The key of the parameter. + * + * @returns {string} the key without the brackets. + */ + function removeBrackets(key) { + return utils$1.endsWith(key, '[]') ? key.slice(0, -2) : key; + } + + /** + * It takes a path, a key, and a boolean, and returns a string + * + * @param {string} path - The path to the current key. + * @param {string} key - The key of the current object being iterated over. + * @param {string} dots - If true, the key will be rendered with dots instead of brackets. + * + * @returns {string} The path to the current key. + */ + function renderKey(path, key, dots) { + if (!path) return key; + return path.concat(key).map(function each(token, i) { + // eslint-disable-next-line no-param-reassign + token = removeBrackets(token); + return !dots && i ? '[' + token + ']' : token; + }).join(dots ? '.' : ''); + } + + /** + * If the array is an array and none of its elements are visitable, then it's a flat array. + * + * @param {Array} arr - The array to check + * + * @returns {boolean} + */ + function isFlatArray(arr) { + return utils$1.isArray(arr) && !arr.some(isVisitable); + } + var predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); + }); + + /** + * Convert a data object to FormData + * + * @param {Object} obj + * @param {?Object} [formData] + * @param {?Object} [options] + * @param {Function} [options.visitor] + * @param {Boolean} [options.metaTokens = true] + * @param {Boolean} [options.dots = false] + * @param {?Boolean} [options.indexes = false] + * + * @returns {Object} + **/ + + /** + * It converts an object into a FormData object + * + * @param {Object} obj - The object to convert to form data. + * @param {string} formData - The FormData object to append to. + * @param {Object} options + * + * @returns + */ + function toFormData(obj, formData, options) { + if (!utils$1.isObject(obj)) { + throw new TypeError('target must be an object'); + } + + // eslint-disable-next-line no-param-reassign + formData = formData || new (FormData)(); + + // eslint-disable-next-line no-param-reassign + options = utils$1.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + // eslint-disable-next-line no-eq-null,eqeqeq + return !utils$1.isUndefined(source[option]); + }); + var metaTokens = options.metaTokens; + // eslint-disable-next-line no-use-before-define + var visitor = options.visitor || defaultVisitor; + var dots = options.dots; + var indexes = options.indexes; + var _Blob = options.Blob || typeof Blob !== 'undefined' && Blob; + var useBlob = _Blob && utils$1.isSpecCompliantForm(formData); + if (!utils$1.isFunction(visitor)) { + throw new TypeError('visitor must be a function'); + } + function convertValue(value) { + if (value === null) return ''; + if (utils$1.isDate(value)) { + return value.toISOString(); + } + if (utils$1.isBoolean(value)) { + return value.toString(); + } + if (!useBlob && utils$1.isBlob(value)) { + throw new AxiosError('Blob is not supported. Use a Buffer instead.'); + } + if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) { + return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + return value; + } + + /** + * Default visitor. + * + * @param {*} value + * @param {String|Number} key + * @param {Array} path + * @this {FormData} + * + * @returns {boolean} return true to visit the each prop of the value recursively + */ + function defaultVisitor(value, key, path) { + var arr = value; + if (value && !path && _typeof(value) === 'object') { + if (utils$1.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + key = metaTokens ? key : key.slice(0, -2); + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if (utils$1.isArray(value) && isFlatArray(value) || (utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value))) { + // eslint-disable-next-line no-param-reassign + key = removeBrackets(key); + arr.forEach(function each(el, index) { + !(utils$1.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : indexes === null ? key : key + '[]', convertValue(el)); + }); + return false; + } + } + if (isVisitable(value)) { + return true; + } + formData.append(renderKey(path, key, dots), convertValue(value)); + return false; + } + var stack = []; + var exposedHelpers = Object.assign(predicates, { + defaultVisitor: defaultVisitor, + convertValue: convertValue, + isVisitable: isVisitable + }); + function build(value, path) { + if (utils$1.isUndefined(value)) return; + if (stack.indexOf(value) !== -1) { + throw Error('Circular reference detected in ' + path.join('.')); + } + stack.push(value); + utils$1.forEach(value, function each(el, key) { + var result = !(utils$1.isUndefined(el) || el === null) && visitor.call(formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers); + if (result === true) { + build(el, path ? path.concat(key) : [key]); + } + }); + stack.pop(); + } + if (!utils$1.isObject(obj)) { + throw new TypeError('data must be an object'); + } + build(obj); + return formData; + } + + /** + * It encodes a string by replacing all characters that are not in the unreserved set with + * their percent-encoded equivalents + * + * @param {string} str - The string to encode. + * + * @returns {string} The encoded string. + */ + function encode$1(str) { + var charMap = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); + } + + /** + * It takes a params object and converts it to a FormData object + * + * @param {Object} params - The parameters to be converted to a FormData object. + * @param {Object} options - The options object passed to the Axios constructor. + * + * @returns {void} + */ + function AxiosURLSearchParams(params, options) { + this._pairs = []; + params && toFormData(params, this, options); + } + var prototype = AxiosURLSearchParams.prototype; + prototype.append = function append(name, value) { + this._pairs.push([name, value]); + }; + prototype.toString = function toString(encoder) { + var _encode = encoder ? function (value) { + return encoder.call(this, value, encode$1); + } : encode$1; + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + '=' + _encode(pair[1]); + }, '').join('&'); + }; + + /** + * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their + * URI encoded counterparts + * + * @param {string} val The value to be encoded. + * + * @returns {string} The encoded value. + */ + function encode(val) { + return encodeURIComponent(val).replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+'); + } + + /** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @param {?(object|Function)} options + * + * @returns {string} The formatted url + */ + function buildURL(url, params, options) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + var _encode = options && options.encode || encode; + if (utils$1.isFunction(options)) { + options = { + serialize: options + }; + } + var serializeFn = options && options.serialize; + var serializedParams; + if (serializeFn) { + serializedParams = serializeFn(params, options); + } else { + serializedParams = utils$1.isURLSearchParams(params) ? params.toString() : new AxiosURLSearchParams(params, options).toString(_encode); + } + if (serializedParams) { + var hashmarkIndex = url.indexOf("#"); + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + return url; + } + + var InterceptorManager = /*#__PURE__*/function () { + function InterceptorManager() { + _classCallCheck(this, InterceptorManager); + this.handlers = []; + } + + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ + _createClass(InterceptorManager, [{ + key: "use", + value: function use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled: fulfilled, + rejected: rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise + */ + }, { + key: "eject", + value: function eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + }, { + key: "clear", + value: function clear() { + if (this.handlers) { + this.handlers = []; + } + } + + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + }, { + key: "forEach", + value: function forEach(fn) { + utils$1.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } + }]); + return InterceptorManager; + }(); + var InterceptorManager$1 = InterceptorManager; + + var transitionalDefaults = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false + }; + + var URLSearchParams$1 = typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams; + + var FormData$1 = typeof FormData !== 'undefined' ? FormData : null; + + var Blob$1 = typeof Blob !== 'undefined' ? Blob : null; + + var platform$1 = { + isBrowser: true, + classes: { + URLSearchParams: URLSearchParams$1, + FormData: FormData$1, + Blob: Blob$1 + }, + protocols: ['http', 'https', 'file', 'blob', 'url', 'data'] + }; + + var hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; + var _navigator = (typeof navigator === "undefined" ? "undefined" : _typeof(navigator)) === 'object' && navigator || undefined; + + /** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + * + * @returns {boolean} + */ + var hasStandardBrowserEnv = hasBrowserEnv && (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); + + /** + * Determine if we're running in a standard browser webWorker environment + * + * Although the `isStandardBrowserEnv` method indicates that + * `allows axios to run in a web worker`, the WebWorker will still be + * filtered out due to its judgment standard + * `typeof window !== 'undefined' && typeof document !== 'undefined'`. + * This leads to a problem when axios post `FormData` in webWorker + */ + var hasStandardBrowserWebWorkerEnv = function () { + return typeof WorkerGlobalScope !== 'undefined' && + // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && typeof self.importScripts === 'function'; + }(); + var origin = hasBrowserEnv && window.location.href || 'http://localhost'; + + var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + hasBrowserEnv: hasBrowserEnv, + hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv, + hasStandardBrowserEnv: hasStandardBrowserEnv, + navigator: _navigator, + origin: origin + }); + + var platform = _objectSpread2(_objectSpread2({}, utils), platform$1); + + function toURLEncodedForm(data, options) { + return toFormData(data, new platform.classes.URLSearchParams(), _objectSpread2({ + visitor: function visitor(value, key, path, helpers) { + if (platform.isNode && utils$1.isBuffer(value)) { + this.append(key, value.toString('base64')); + return false; + } + return helpers.defaultVisitor.apply(this, arguments); + } + }, options)); + } + + /** + * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] + * + * @param {string} name - The name of the property to get. + * + * @returns An array of strings. + */ + function parsePropPath(name) { + // foo[x][y][z] + // foo.x.y.z + // foo-x-y-z + // foo x y z + return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(function (match) { + return match[0] === '[]' ? '' : match[1] || match[0]; + }); + } + + /** + * Convert an array to an object. + * + * @param {Array} arr - The array to convert to an object. + * + * @returns An object with the same keys and values as the array. + */ + function arrayToObject(arr) { + var obj = {}; + var keys = Object.keys(arr); + var i; + var len = keys.length; + var key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; + } + + /** + * It takes a FormData object and returns a JavaScript object + * + * @param {string} formData The FormData object to convert to JSON. + * + * @returns {Object | null} The converted object. + */ + function formDataToJSON(formData) { + function buildPath(path, value, target, index) { + var name = path[index++]; + if (name === '__proto__') return true; + var isNumericKey = Number.isFinite(+name); + var isLast = index >= path.length; + name = !name && utils$1.isArray(target) ? target.length : name; + if (isLast) { + if (utils$1.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + return !isNumericKey; + } + if (!target[name] || !utils$1.isObject(target[name])) { + target[name] = []; + } + var result = buildPath(path, value, target[name], index); + if (result && utils$1.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + return !isNumericKey; + } + if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) { + var obj = {}; + utils$1.forEachEntry(formData, function (name, value) { + buildPath(parsePropPath(name), value, obj, 0); + }); + return obj; + } + return null; + } + + /** + * It takes a string, tries to parse it, and if it fails, it returns the stringified version + * of the input + * + * @param {any} rawValue - The value to be stringified. + * @param {Function} parser - A function that parses a string into a JavaScript object. + * @param {Function} encoder - A function that takes a value and returns a string. + * + * @returns {string} A stringified version of the rawValue. + */ + function stringifySafely(rawValue, parser, encoder) { + if (utils$1.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils$1.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + return (encoder || JSON.stringify)(rawValue); + } + var defaults = { + transitional: transitionalDefaults, + adapter: ['xhr', 'http', 'fetch'], + transformRequest: [function transformRequest(data, headers) { + var contentType = headers.getContentType() || ''; + var hasJSONContentType = contentType.indexOf('application/json') > -1; + var isObjectPayload = utils$1.isObject(data); + if (isObjectPayload && utils$1.isHTMLForm(data)) { + data = new FormData(data); + } + var isFormData = utils$1.isFormData(data); + if (isFormData) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + if (utils$1.isArrayBuffer(data) || utils$1.isBuffer(data) || utils$1.isStream(data) || utils$1.isFile(data) || utils$1.isBlob(data) || utils$1.isReadableStream(data)) { + return data; + } + if (utils$1.isArrayBufferView(data)) { + return data.buffer; + } + if (utils$1.isURLSearchParams(data)) { + headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); + return data.toString(); + } + var isFileList; + if (isObjectPayload) { + if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) { + var _FormData = this.env && this.env.FormData; + return toFormData(isFileList ? { + 'files[]': data + } : data, _FormData && new _FormData(), this.formSerializer); + } + } + if (isObjectPayload || hasJSONContentType) { + headers.setContentType('application/json', false); + return stringifySafely(data); + } + return data; + }], + transformResponse: [function transformResponse(data) { + var transitional = this.transitional || defaults.transitional; + var forcedJSONParsing = transitional && transitional.forcedJSONParsing; + var JSONRequested = this.responseType === 'json'; + if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) { + return data; + } + if (data && utils$1.isString(data) && (forcedJSONParsing && !this.responseType || JSONRequested)) { + var silentJSONParsing = transitional && transitional.silentJSONParsing; + var strictJSONParsing = !silentJSONParsing && JSONRequested; + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + return data; + }], + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + maxContentLength: -1, + maxBodyLength: -1, + env: { + FormData: platform.classes.FormData, + Blob: platform.classes.Blob + }, + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': undefined + } + } + }; + utils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], function (method) { + defaults.headers[method] = {}; + }); + var defaults$1 = defaults; + + // RawAxiosHeaders whose duplicates are ignored by node + // c.f. https://nodejs.org/api/http.html#http_message_headers + var ignoreDuplicateOf = utils$1.toObjectSet(['age', 'authorization', 'content-length', 'content-type', 'etag', 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 'referer', 'retry-after', 'user-agent']); + + /** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} rawHeaders Headers needing to be parsed + * + * @returns {Object} Headers parsed into an object + */ + var parseHeaders = (function (rawHeaders) { + var parsed = {}; + var key; + var val; + var i; + rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { + i = line.indexOf(':'); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + if (!key || parsed[key] && ignoreDuplicateOf[key]) { + return; + } + if (key === 'set-cookie') { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + }); + return parsed; + }); + + var $internals = Symbol('internals'); + function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); + } + function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + return utils$1.isArray(value) ? value.map(normalizeValue) : String(value); + } + function parseTokens(str) { + var tokens = Object.create(null); + var tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + var match; + while (match = tokensRE.exec(str)) { + tokens[match[1]] = match[2]; + } + return tokens; + } + var isValidHeaderName = function isValidHeaderName(str) { + return /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + }; + function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils$1.isFunction(filter)) { + return filter.call(this, value, header); + } + if (isHeaderNameFilter) { + value = header; + } + if (!utils$1.isString(value)) return; + if (utils$1.isString(filter)) { + return value.indexOf(filter) !== -1; + } + if (utils$1.isRegExp(filter)) { + return filter.test(value); + } + } + function formatHeader(header) { + return header.trim().toLowerCase().replace(/([a-z\d])(\w*)/g, function (w, _char, str) { + return _char.toUpperCase() + str; + }); + } + function buildAccessors(obj, header) { + var accessorName = utils$1.toCamelCase(' ' + header); + ['get', 'set', 'has'].forEach(function (methodName) { + Object.defineProperty(obj, methodName + accessorName, { + value: function value(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); + } + var AxiosHeaders = /*#__PURE__*/function (_Symbol$iterator, _Symbol$toStringTag) { + function AxiosHeaders(headers) { + _classCallCheck(this, AxiosHeaders); + headers && this.set(headers); + } + _createClass(AxiosHeaders, [{ + key: "set", + value: function set(header, valueOrRewrite, rewrite) { + var self = this; + function setHeader(_value, _header, _rewrite) { + var lHeader = normalizeHeader(_header); + if (!lHeader) { + throw new Error('header name must be a non-empty string'); + } + var key = utils$1.findKey(self, lHeader); + if (!key || self[key] === undefined || _rewrite === true || _rewrite === undefined && self[key] !== false) { + self[key || _header] = normalizeValue(_value); + } + } + var setHeaders = function setHeaders(headers, _rewrite) { + return utils$1.forEach(headers, function (_value, _header) { + return setHeader(_value, _header, _rewrite); + }); + }; + if (utils$1.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite); + } else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils$1.isObject(header) && utils$1.isIterable(header)) { + var obj = {}, + dest, + key; + var _iterator = _createForOfIteratorHelper(header), + _step; + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var entry = _step.value; + if (!utils$1.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + obj[key = entry[0]] = (dest = obj[key]) ? utils$1.isArray(dest) ? [].concat(_toConsumableArray(dest), [entry[1]]) : [dest, entry[1]] : entry[1]; + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + setHeaders(obj, valueOrRewrite); + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + return this; + } + }, { + key: "get", + value: function get(header, parser) { + header = normalizeHeader(header); + if (header) { + var key = utils$1.findKey(this, header); + if (key) { + var value = this[key]; + if (!parser) { + return value; + } + if (parser === true) { + return parseTokens(value); + } + if (utils$1.isFunction(parser)) { + return parser.call(this, value, key); + } + if (utils$1.isRegExp(parser)) { + return parser.exec(value); + } + throw new TypeError('parser must be boolean|regexp|function'); + } + } + } + }, { + key: "has", + value: function has(header, matcher) { + header = normalizeHeader(header); + if (header) { + var key = utils$1.findKey(this, header); + return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + return false; + } + }, { + key: "delete", + value: function _delete(header, matcher) { + var self = this; + var deleted = false; + function deleteHeader(_header) { + _header = normalizeHeader(_header); + if (_header) { + var key = utils$1.findKey(self, _header); + if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { + delete self[key]; + deleted = true; + } + } + } + if (utils$1.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + return deleted; + } + }, { + key: "clear", + value: function clear(matcher) { + var keys = Object.keys(this); + var i = keys.length; + var deleted = false; + while (i--) { + var key = keys[i]; + if (!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + return deleted; + } + }, { + key: "normalize", + value: function normalize(format) { + var self = this; + var headers = {}; + utils$1.forEach(this, function (value, header) { + var key = utils$1.findKey(headers, header); + if (key) { + self[key] = normalizeValue(value); + delete self[header]; + return; + } + var normalized = format ? formatHeader(header) : String(header).trim(); + if (normalized !== header) { + delete self[header]; + } + self[normalized] = normalizeValue(value); + headers[normalized] = true; + }); + return this; + } + }, { + key: "concat", + value: function concat() { + var _this$constructor; + for (var _len = arguments.length, targets = new Array(_len), _key = 0; _key < _len; _key++) { + targets[_key] = arguments[_key]; + } + return (_this$constructor = this.constructor).concat.apply(_this$constructor, [this].concat(targets)); + } + }, { + key: "toJSON", + value: function toJSON(asStrings) { + var obj = Object.create(null); + utils$1.forEach(this, function (value, header) { + value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(', ') : value); + }); + return obj; + } + }, { + key: _Symbol$iterator, + value: function value() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + }, { + key: "toString", + value: function toString() { + return Object.entries(this.toJSON()).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + header = _ref2[0], + value = _ref2[1]; + return header + ': ' + value; + }).join('\n'); + } + }, { + key: "getSetCookie", + value: function getSetCookie() { + return this.get("set-cookie") || []; + } + }, { + key: _Symbol$toStringTag, + get: function get() { + return 'AxiosHeaders'; + } + }], [{ + key: "from", + value: function from(thing) { + return thing instanceof this ? thing : new this(thing); + } + }, { + key: "concat", + value: function concat(first) { + var computed = new this(first); + for (var _len2 = arguments.length, targets = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + targets[_key2 - 1] = arguments[_key2]; + } + targets.forEach(function (target) { + return computed.set(target); + }); + return computed; + } + }, { + key: "accessor", + value: function accessor(header) { + var internals = this[$internals] = this[$internals] = { + accessors: {} + }; + var accessors = internals.accessors; + var prototype = this.prototype; + function defineAccessor(_header) { + var lHeader = normalizeHeader(_header); + if (!accessors[lHeader]) { + buildAccessors(prototype, _header); + accessors[lHeader] = true; + } + } + utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + return this; + } + }]); + return AxiosHeaders; + }(Symbol.iterator, Symbol.toStringTag); + AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); + + // reserved names hotfix + utils$1.reduceDescriptors(AxiosHeaders.prototype, function (_ref3, key) { + var value = _ref3.value; + var mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` + return { + get: function get() { + return value; + }, + set: function set(headerValue) { + this[mapped] = headerValue; + } + }; + }); + utils$1.freezeMethods(AxiosHeaders); + var AxiosHeaders$1 = AxiosHeaders; + + /** + * Transform the data for a request or a response + * + * @param {Array|Function} fns A single function or Array of functions + * @param {?Object} response The response object + * + * @returns {*} The resulting transformed data + */ + function transformData(fns, response) { + var config = this || defaults$1; + var context = response || config; + var headers = AxiosHeaders$1.from(context.headers); + var data = context.data; + utils$1.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); + }); + headers.normalize(); + return data; + } + + function isCancel(value) { + return !!(value && value.__CANCEL__); + } + + /** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ + function CanceledError(message, config, request) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); + this.name = 'CanceledError'; + } + utils$1.inherits(CanceledError, AxiosError, { + __CANCEL__: true + }); + + /** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + * + * @returns {object} The response. + */ + function settle(resolve, reject, response) { + var validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError('Request failed with status code ' + response.status, [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], response.config, response.request, response)); + } + } + + function parseProtocol(url) { + var match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; + } + + /** + * Calculate data maxRate + * @param {Number} [samplesCount= 10] + * @param {Number} [min= 1000] + * @returns {Function} + */ + function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + var bytes = new Array(samplesCount); + var timestamps = new Array(samplesCount); + var head = 0; + var tail = 0; + var firstSampleTS; + min = min !== undefined ? min : 1000; + return function push(chunkLength) { + var now = Date.now(); + var startedAt = timestamps[tail]; + if (!firstSampleTS) { + firstSampleTS = now; + } + bytes[head] = chunkLength; + timestamps[head] = now; + var i = tail; + var bytesCount = 0; + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + head = (head + 1) % samplesCount; + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + if (now - firstSampleTS < min) { + return; + } + var passed = startedAt && now - startedAt; + return passed ? Math.round(bytesCount * 1000 / passed) : undefined; + }; + } + + /** + * Throttle decorator + * @param {Function} fn + * @param {Number} freq + * @return {Function} + */ + function throttle(fn, freq) { + var timestamp = 0; + var threshold = 1000 / freq; + var lastArgs; + var timer; + var invoke = function invoke(args) { + var now = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Date.now(); + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn.apply(void 0, _toConsumableArray(args)); + }; + var throttled = function throttled() { + var now = Date.now(); + var passed = now - timestamp; + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + if (passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(function () { + timer = null; + invoke(lastArgs); + }, threshold - passed); + } + } + }; + var flush = function flush() { + return lastArgs && invoke(lastArgs); + }; + return [throttled, flush]; + } + + var progressEventReducer = function progressEventReducer(listener, isDownloadStream) { + var freq = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 3; + var bytesNotified = 0; + var _speedometer = speedometer(50, 250); + return throttle(function (e) { + var loaded = e.loaded; + var total = e.lengthComputable ? e.total : undefined; + var progressBytes = loaded - bytesNotified; + var rate = _speedometer(progressBytes); + var inRange = loaded <= total; + bytesNotified = loaded; + var data = _defineProperty({ + loaded: loaded, + total: total, + progress: total ? loaded / total : undefined, + bytes: progressBytes, + rate: rate ? rate : undefined, + estimated: rate && total && inRange ? (total - loaded) / rate : undefined, + event: e, + lengthComputable: total != null + }, isDownloadStream ? 'download' : 'upload', true); + listener(data); + }, freq); + }; + var progressEventDecorator = function progressEventDecorator(total, throttled) { + var lengthComputable = total != null; + return [function (loaded) { + return throttled[0]({ + lengthComputable: lengthComputable, + total: total, + loaded: loaded + }); + }, throttled[1]]; + }; + var asyncDecorator = function asyncDecorator(fn) { + return function () { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + return utils$1.asap(function () { + return fn.apply(void 0, args); + }); + }; + }; + + var isURLSameOrigin = platform.hasStandardBrowserEnv ? function (origin, isMSIE) { + return function (url) { + url = new URL(url, platform.origin); + return origin.protocol === url.protocol && origin.host === url.host && (isMSIE || origin.port === url.port); + }; + }(new URL(platform.origin), platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)) : function () { + return true; + }; + + var cookies = platform.hasStandardBrowserEnv ? + // Standard browser envs support document.cookie + { + write: function write(name, value, expires, path, domain, secure) { + var cookie = [name + '=' + encodeURIComponent(value)]; + utils$1.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString()); + utils$1.isString(path) && cookie.push('path=' + path); + utils$1.isString(domain) && cookie.push('domain=' + domain); + secure === true && cookie.push('secure'); + document.cookie = cookie.join('; '); + }, + read: function read(name) { + var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return match ? decodeURIComponent(match[3]) : null; + }, + remove: function remove(name) { + this.write(name, '', Date.now() - 86400000); + } + } : + // Non-standard browser env (web workers, react-native) lack needed support. + { + write: function write() {}, + read: function read() { + return null; + }, + remove: function remove() {} + }; + + /** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ + function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); + } + + /** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * + * @returns {string} The combined URL + */ + function combineURLs(baseURL, relativeURL) { + return relativeURL ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL; + } + + /** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * + * @returns {string} The combined full path + */ + function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + var isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; + } + + var headersToObject = function headersToObject(thing) { + return thing instanceof AxiosHeaders$1 ? _objectSpread2({}, thing) : thing; + }; + + /** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * + * @returns {Object} New object resulting from merging config2 to config1 + */ + function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + var config = {}; + function getMergedValue(target, source, prop, caseless) { + if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) { + return utils$1.merge.call({ + caseless: caseless + }, target, source); + } else if (utils$1.isPlainObject(source)) { + return utils$1.merge({}, source); + } else if (utils$1.isArray(source)) { + return source.slice(); + } + return source; + } + + // eslint-disable-next-line consistent-return + function mergeDeepProperties(a, b, prop, caseless) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(a, b, prop, caseless); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a, prop, caseless); + } + } + + // eslint-disable-next-line consistent-return + function valueFromConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } + } + + // eslint-disable-next-line consistent-return + function defaultToConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a); + } + } + + // eslint-disable-next-line consistent-return + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(undefined, a); + } + } + var mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: function headers(a, b, prop) { + return mergeDeepProperties(headersToObject(a), headersToObject(b), prop, true); + } + }; + utils$1.forEach(Object.keys(_objectSpread2(_objectSpread2({}, config1), config2)), function computeConfigValue(prop) { + var merge = mergeMap[prop] || mergeDeepProperties; + var configValue = merge(config1[prop], config2[prop], prop); + utils$1.isUndefined(configValue) && merge !== mergeDirectKeys || (config[prop] = configValue); + }); + return config; + } + + var resolveConfig = (function (config) { + var newConfig = mergeConfig({}, config); + var data = newConfig.data, + withXSRFToken = newConfig.withXSRFToken, + xsrfHeaderName = newConfig.xsrfHeaderName, + xsrfCookieName = newConfig.xsrfCookieName, + headers = newConfig.headers, + auth = newConfig.auth; + newConfig.headers = headers = AxiosHeaders$1.from(headers); + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + + // HTTP basic authentication + if (auth) { + headers.set('Authorization', 'Basic ' + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))); + } + if (utils$1.isFormData(data)) { + if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(undefined); // browser handles it + } else if (utils$1.isFunction(data.getHeaders)) { + // Node.js FormData (like form-data package) + var formHeaders = data.getHeaders(); + // Only set safe headers to avoid overwriting security headers + var allowedHeaders = ['content-type', 'content-length']; + Object.entries(formHeaders).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + val = _ref2[1]; + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + + if (platform.hasStandardBrowserEnv) { + withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + if (withXSRFToken || withXSRFToken !== false && isURLSameOrigin(newConfig.url)) { + // Add xsrf header + var xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + return newConfig; + }); + + var isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; + var xhrAdapter = isXHRAdapterSupported && function (config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + var _config = resolveConfig(config); + var requestData = _config.data; + var requestHeaders = AxiosHeaders$1.from(_config.headers).normalize(); + var responseType = _config.responseType, + onUploadProgress = _config.onUploadProgress, + onDownloadProgress = _config.onDownloadProgress; + var onCanceled; + var uploadThrottled, downloadThrottled; + var flushUpload, flushDownload; + function done() { + flushUpload && flushUpload(); // flush events + flushDownload && flushDownload(); // flush events + + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + _config.signal && _config.signal.removeEventListener('abort', onCanceled); + } + var request = new XMLHttpRequest(); + request.open(_config.method.toUpperCase(), _config.url, true); + + // Set the request timeout in MS + request.timeout = _config.timeout; + function onloadend() { + if (!request) { + return; + } + // Prepare the response + var responseHeaders = AxiosHeaders$1.from('getAllResponseHeaders' in request && request.getAllResponseHeaders()); + var responseData = !responseType || responseType === 'text' || responseType === 'json' ? request.responseText : request.response; + var response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config: config, + request: request + }; + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + + // Clean up request + request = null; + } + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError(event) { + // Browsers deliver a ProgressEvent in XHR onerror + // (message may be empty; when present, surface it) + // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event + var msg = event && event.message ? event.message : 'Network Error'; + var err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); + // attach the underlying event for consumers who want details + err.event = event || null; + reject(err); + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + var timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; + var transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError(timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Remove Content-Type if data is undefined + requestData === undefined && requestHeaders.setContentType(null); + + // Add headers to the request + if ('setRequestHeader' in request) { + utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + + // Add withCredentials to request if needed + if (!utils$1.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + + // Add responseType to request if needed + if (responseType && responseType !== 'json') { + request.responseType = _config.responseType; + } + + // Handle progress if needed + if (onDownloadProgress) { + var _progressEventReducer = progressEventReducer(onDownloadProgress, true); + var _progressEventReducer2 = _slicedToArray(_progressEventReducer, 2); + downloadThrottled = _progressEventReducer2[0]; + flushDownload = _progressEventReducer2[1]; + request.addEventListener('progress', downloadThrottled); + } + + // Not all browsers support upload events + if (onUploadProgress && request.upload) { + var _progressEventReducer3 = progressEventReducer(onUploadProgress); + var _progressEventReducer4 = _slicedToArray(_progressEventReducer3, 2); + uploadThrottled = _progressEventReducer4[0]; + flushUpload = _progressEventReducer4[1]; + request.upload.addEventListener('progress', uploadThrottled); + request.upload.addEventListener('loadend', flushUpload); + } + if (_config.cancelToken || _config.signal) { + // Handle cancellation + // eslint-disable-next-line func-names + onCanceled = function onCanceled(cancel) { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); + request.abort(); + request = null; + }; + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); + } + } + var protocol = parseProtocol(_config.url); + if (protocol && platform.protocols.indexOf(protocol) === -1) { + reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config)); + return; + } + + // Send the request + request.send(requestData || null); + }); + }; + + var composeSignals = function composeSignals(signals, timeout) { + var _signals = signals = signals ? signals.filter(Boolean) : [], + length = _signals.length; + if (timeout || length) { + var controller = new AbortController(); + var aborted; + var onabort = function onabort(reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + var err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err)); + } + }; + var timer = timeout && setTimeout(function () { + timer = null; + onabort(new AxiosError("timeout ".concat(timeout, " of ms exceeded"), AxiosError.ETIMEDOUT)); + }, timeout); + var unsubscribe = function unsubscribe() { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach(function (signal) { + signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); + }); + signals = null; + } + }; + signals.forEach(function (signal) { + return signal.addEventListener('abort', onabort); + }); + var signal = controller.signal; + signal.unsubscribe = function () { + return utils$1.asap(unsubscribe); + }; + return signal; + } + }; + var composeSignals$1 = composeSignals; + + var streamChunk = /*#__PURE__*/_regeneratorRuntime().mark(function streamChunk(chunk, chunkSize) { + var len, pos, end; + return _regeneratorRuntime().wrap(function streamChunk$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + len = chunk.byteLength; + if (!(!chunkSize || len < chunkSize)) { + _context.next = 5; + break; + } + _context.next = 4; + return chunk; + case 4: + return _context.abrupt("return"); + case 5: + pos = 0; + case 6: + if (!(pos < len)) { + _context.next = 13; + break; + } + end = pos + chunkSize; + _context.next = 10; + return chunk.slice(pos, end); + case 10: + pos = end; + _context.next = 6; + break; + case 13: + case "end": + return _context.stop(); + } + }, streamChunk); + }); + var readBytes = /*#__PURE__*/function () { + var _ref = _wrapAsyncGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(iterable, chunkSize) { + var _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, chunk; + return _regeneratorRuntime().wrap(function _callee$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + _iteratorAbruptCompletion = false; + _didIteratorError = false; + _context2.prev = 2; + _iterator = _asyncIterator(readStream(iterable)); + case 4: + _context2.next = 6; + return _awaitAsyncGenerator(_iterator.next()); + case 6: + if (!(_iteratorAbruptCompletion = !(_step = _context2.sent).done)) { + _context2.next = 12; + break; + } + chunk = _step.value; + return _context2.delegateYield(_asyncGeneratorDelegate(_asyncIterator(streamChunk(chunk, chunkSize))), "t0", 9); + case 9: + _iteratorAbruptCompletion = false; + _context2.next = 4; + break; + case 12: + _context2.next = 18; + break; + case 14: + _context2.prev = 14; + _context2.t1 = _context2["catch"](2); + _didIteratorError = true; + _iteratorError = _context2.t1; + case 18: + _context2.prev = 18; + _context2.prev = 19; + if (!(_iteratorAbruptCompletion && _iterator["return"] != null)) { + _context2.next = 23; + break; + } + _context2.next = 23; + return _awaitAsyncGenerator(_iterator["return"]()); + case 23: + _context2.prev = 23; + if (!_didIteratorError) { + _context2.next = 26; + break; + } + throw _iteratorError; + case 26: + return _context2.finish(23); + case 27: + return _context2.finish(18); + case 28: + case "end": + return _context2.stop(); + } + }, _callee, null, [[2, 14, 18, 28], [19,, 23, 27]]); + })); + return function readBytes(_x, _x2) { + return _ref.apply(this, arguments); + }; + }(); + var readStream = /*#__PURE__*/function () { + var _ref2 = _wrapAsyncGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(stream) { + var reader, _yield$_awaitAsyncGen, done, value; + return _regeneratorRuntime().wrap(function _callee2$(_context3) { + while (1) switch (_context3.prev = _context3.next) { + case 0: + if (!stream[Symbol.asyncIterator]) { + _context3.next = 3; + break; + } + return _context3.delegateYield(_asyncGeneratorDelegate(_asyncIterator(stream)), "t0", 2); + case 2: + return _context3.abrupt("return"); + case 3: + reader = stream.getReader(); + _context3.prev = 4; + case 5: + _context3.next = 7; + return _awaitAsyncGenerator(reader.read()); + case 7: + _yield$_awaitAsyncGen = _context3.sent; + done = _yield$_awaitAsyncGen.done; + value = _yield$_awaitAsyncGen.value; + if (!done) { + _context3.next = 12; + break; + } + return _context3.abrupt("break", 16); + case 12: + _context3.next = 14; + return value; + case 14: + _context3.next = 5; + break; + case 16: + _context3.prev = 16; + _context3.next = 19; + return _awaitAsyncGenerator(reader.cancel()); + case 19: + return _context3.finish(16); + case 20: + case "end": + return _context3.stop(); + } + }, _callee2, null, [[4,, 16, 20]]); + })); + return function readStream(_x3) { + return _ref2.apply(this, arguments); + }; + }(); + var trackStream = function trackStream(stream, chunkSize, onProgress, onFinish) { + var iterator = readBytes(stream, chunkSize); + var bytes = 0; + var done; + var _onFinish = function _onFinish(e) { + if (!done) { + done = true; + onFinish && onFinish(e); + } + }; + return new ReadableStream({ + pull: function pull(controller) { + return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { + var _yield$iterator$next, _done, value, len, loadedBytes; + return _regeneratorRuntime().wrap(function _callee3$(_context4) { + while (1) switch (_context4.prev = _context4.next) { + case 0: + _context4.prev = 0; + _context4.next = 3; + return iterator.next(); + case 3: + _yield$iterator$next = _context4.sent; + _done = _yield$iterator$next.done; + value = _yield$iterator$next.value; + if (!_done) { + _context4.next = 10; + break; + } + _onFinish(); + controller.close(); + return _context4.abrupt("return"); + case 10: + len = value.byteLength; + if (onProgress) { + loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + _context4.next = 19; + break; + case 15: + _context4.prev = 15; + _context4.t0 = _context4["catch"](0); + _onFinish(_context4.t0); + throw _context4.t0; + case 19: + case "end": + return _context4.stop(); + } + }, _callee3, null, [[0, 15]]); + }))(); + }, + cancel: function cancel(reason) { + _onFinish(reason); + return iterator["return"](); + } + }, { + highWaterMark: 2 + }); + }; + + var DEFAULT_CHUNK_SIZE = 64 * 1024; + var isFunction = utils$1.isFunction; + var globalFetchAPI = function (_ref) { + var Request = _ref.Request, + Response = _ref.Response; + return { + Request: Request, + Response: Response + }; + }(utils$1.global); + var _utils$global = utils$1.global, + ReadableStream$1 = _utils$global.ReadableStream, + TextEncoder = _utils$global.TextEncoder; + var test = function test(fn) { + try { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + return !!fn.apply(void 0, args); + } catch (e) { + return false; + } + }; + var factory = function factory(env) { + env = utils$1.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + var _env = env, + envFetch = _env.fetch, + Request = _env.Request, + Response = _env.Response; + var isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; + var isRequestSupported = isFunction(Request); + var isResponseSupported = isFunction(Response); + if (!isFetchSupported) { + return false; + } + var isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1); + var encodeText = isFetchSupported && (typeof TextEncoder === 'function' ? function (encoder) { + return function (str) { + return encoder.encode(str); + }; + }(new TextEncoder()) : ( /*#__PURE__*/function () { + var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(str) { + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + _context.t0 = Uint8Array; + _context.next = 3; + return new Request(str).arrayBuffer(); + case 3: + _context.t1 = _context.sent; + return _context.abrupt("return", new _context.t0(_context.t1)); + case 5: + case "end": + return _context.stop(); + } + }, _callee); + })); + return function (_x) { + return _ref2.apply(this, arguments); + }; + }())); + var supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(function () { + var duplexAccessed = false; + var hasContentType = new Request(platform.origin, { + body: new ReadableStream$1(), + method: 'POST', + get duplex() { + duplexAccessed = true; + return 'half'; + } + }).headers.has('Content-Type'); + return duplexAccessed && !hasContentType; + }); + var supportsResponseStream = isResponseSupported && isReadableStreamSupported && test(function () { + return utils$1.isReadableStream(new Response('').body); + }); + var resolvers = { + stream: supportsResponseStream && function (res) { + return res.body; + } + }; + isFetchSupported && function () { + ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(function (type) { + !resolvers[type] && (resolvers[type] = function (res, config) { + var method = res && res[type]; + if (method) { + return method.call(res); + } + throw new AxiosError("Response type '".concat(type, "' is not supported"), AxiosError.ERR_NOT_SUPPORT, config); + }); + }); + }(); + var getBodyLength = /*#__PURE__*/function () { + var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(body) { + var _request; + return _regeneratorRuntime().wrap(function _callee2$(_context2) { + while (1) switch (_context2.prev = _context2.next) { + case 0: + if (!(body == null)) { + _context2.next = 2; + break; + } + return _context2.abrupt("return", 0); + case 2: + if (!utils$1.isBlob(body)) { + _context2.next = 4; + break; + } + return _context2.abrupt("return", body.size); + case 4: + if (!utils$1.isSpecCompliantForm(body)) { + _context2.next = 9; + break; + } + _request = new Request(platform.origin, { + method: 'POST', + body: body + }); + _context2.next = 8; + return _request.arrayBuffer(); + case 8: + return _context2.abrupt("return", _context2.sent.byteLength); + case 9: + if (!(utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body))) { + _context2.next = 11; + break; + } + return _context2.abrupt("return", body.byteLength); + case 11: + if (utils$1.isURLSearchParams(body)) { + body = body + ''; + } + if (!utils$1.isString(body)) { + _context2.next = 16; + break; + } + _context2.next = 15; + return encodeText(body); + case 15: + return _context2.abrupt("return", _context2.sent.byteLength); + case 16: + case "end": + return _context2.stop(); + } + }, _callee2); + })); + return function getBodyLength(_x2) { + return _ref3.apply(this, arguments); + }; + }(); + var resolveBodyLength = /*#__PURE__*/function () { + var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(headers, body) { + var length; + return _regeneratorRuntime().wrap(function _callee3$(_context3) { + while (1) switch (_context3.prev = _context3.next) { + case 0: + length = utils$1.toFiniteNumber(headers.getContentLength()); + return _context3.abrupt("return", length == null ? getBodyLength(body) : length); + case 2: + case "end": + return _context3.stop(); + } + }, _callee3); + })); + return function resolveBodyLength(_x3, _x4) { + return _ref4.apply(this, arguments); + }; + }(); + return /*#__PURE__*/function () { + var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(config) { + var _resolveConfig, url, method, data, signal, cancelToken, timeout, onDownloadProgress, onUploadProgress, responseType, headers, _resolveConfig$withCr, withCredentials, fetchOptions, _fetch, composedSignal, request, unsubscribe, requestContentLength, _request, contentTypeHeader, _progressEventDecorat, _progressEventDecorat2, onProgress, flush, isCredentialsSupported, resolvedOptions, response, isStreamResponse, options, responseContentLength, _ref6, _ref7, _onProgress, _flush, responseData; + return _regeneratorRuntime().wrap(function _callee4$(_context4) { + while (1) switch (_context4.prev = _context4.next) { + case 0: + _resolveConfig = resolveConfig(config), url = _resolveConfig.url, method = _resolveConfig.method, data = _resolveConfig.data, signal = _resolveConfig.signal, cancelToken = _resolveConfig.cancelToken, timeout = _resolveConfig.timeout, onDownloadProgress = _resolveConfig.onDownloadProgress, onUploadProgress = _resolveConfig.onUploadProgress, responseType = _resolveConfig.responseType, headers = _resolveConfig.headers, _resolveConfig$withCr = _resolveConfig.withCredentials, withCredentials = _resolveConfig$withCr === void 0 ? 'same-origin' : _resolveConfig$withCr, fetchOptions = _resolveConfig.fetchOptions; + _fetch = envFetch || fetch; + responseType = responseType ? (responseType + '').toLowerCase() : 'text'; + composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + request = null; + unsubscribe = composedSignal && composedSignal.unsubscribe && function () { + composedSignal.unsubscribe(); + }; + _context4.prev = 6; + _context4.t0 = onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head'; + if (!_context4.t0) { + _context4.next = 13; + break; + } + _context4.next = 11; + return resolveBodyLength(headers, data); + case 11: + _context4.t1 = requestContentLength = _context4.sent; + _context4.t0 = _context4.t1 !== 0; + case 13: + if (!_context4.t0) { + _context4.next = 17; + break; + } + _request = new Request(url, { + method: 'POST', + body: data, + duplex: "half" + }); + if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { + headers.setContentType(contentTypeHeader); + } + if (_request.body) { + _progressEventDecorat = progressEventDecorator(requestContentLength, progressEventReducer(asyncDecorator(onUploadProgress))), _progressEventDecorat2 = _slicedToArray(_progressEventDecorat, 2), onProgress = _progressEventDecorat2[0], flush = _progressEventDecorat2[1]; + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + case 17: + if (!utils$1.isString(withCredentials)) { + withCredentials = withCredentials ? 'include' : 'omit'; + } + + // Cloudflare Workers throws when credentials are defined + // see https://github.com/cloudflare/workerd/issues/902 + isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + resolvedOptions = _objectSpread2(_objectSpread2({}, fetchOptions), {}, { + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : undefined + }); + request = isRequestSupported && new Request(url, resolvedOptions); + _context4.next = 23; + return isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions); + case 23: + response = _context4.sent; + isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); + if (supportsResponseStream && (onDownloadProgress || isStreamResponse && unsubscribe)) { + options = {}; + ['status', 'statusText', 'headers'].forEach(function (prop) { + options[prop] = response[prop]; + }); + responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length')); + _ref6 = onDownloadProgress && progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true)) || [], _ref7 = _slicedToArray(_ref6, 2), _onProgress = _ref7[0], _flush = _ref7[1]; + response = new Response(trackStream(response.body, DEFAULT_CHUNK_SIZE, _onProgress, function () { + _flush && _flush(); + unsubscribe && unsubscribe(); + }), options); + } + responseType = responseType || 'text'; + _context4.next = 29; + return resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config); + case 29: + responseData = _context4.sent; + !isStreamResponse && unsubscribe && unsubscribe(); + _context4.next = 33; + return new Promise(function (resolve, reject) { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders$1.from(response.headers), + status: response.status, + statusText: response.statusText, + config: config, + request: request + }); + }); + case 33: + return _context4.abrupt("return", _context4.sent); + case 36: + _context4.prev = 36; + _context4.t2 = _context4["catch"](6); + unsubscribe && unsubscribe(); + if (!(_context4.t2 && _context4.t2.name === 'TypeError' && /Load failed|fetch/i.test(_context4.t2.message))) { + _context4.next = 41; + break; + } + throw Object.assign(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request), { + cause: _context4.t2.cause || _context4.t2 + }); + case 41: + throw AxiosError.from(_context4.t2, _context4.t2 && _context4.t2.code, config, request); + case 42: + case "end": + return _context4.stop(); + } + }, _callee4, null, [[6, 36]]); + })); + return function (_x5) { + return _ref5.apply(this, arguments); + }; + }(); + }; + var seedCache = new Map(); + var getFetch = function getFetch(config) { + var env = config ? config.env : {}; + var fetch = env.fetch, + Request = env.Request, + Response = env.Response; + var seeds = [Request, Response, fetch]; + var len = seeds.length, + i = len, + seed, + target, + map = seedCache; + while (i--) { + seed = seeds[i]; + target = map.get(seed); + target === undefined && map.set(seed, target = i ? new Map() : factory(env)); + map = target; + } + return target; + }; + getFetch(); + + var knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: getFetch + } + }; + utils$1.forEach(knownAdapters, function (fn, value) { + if (fn) { + try { + Object.defineProperty(fn, 'name', { + value: value + }); + } catch (e) { + // eslint-disable-next-line no-empty + } + Object.defineProperty(fn, 'adapterName', { + value: value + }); + } + }); + var renderReason = function renderReason(reason) { + return "- ".concat(reason); + }; + var isResolvedHandle = function isResolvedHandle(adapter) { + return utils$1.isFunction(adapter) || adapter === null || adapter === false; + }; + var adapters = { + getAdapter: function getAdapter(adapters, config) { + adapters = utils$1.isArray(adapters) ? adapters : [adapters]; + var _adapters = adapters, + length = _adapters.length; + var nameOrAdapter; + var adapter; + var rejectedReasons = {}; + for (var i = 0; i < length; i++) { + nameOrAdapter = adapters[i]; + var id = void 0; + adapter = nameOrAdapter; + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + if (adapter === undefined) { + throw new AxiosError("Unknown adapter '".concat(id, "'")); + } + } + if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + rejectedReasons[id || '#' + i] = adapter; + } + if (!adapter) { + var reasons = Object.entries(rejectedReasons).map(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + id = _ref2[0], + state = _ref2[1]; + return "adapter ".concat(id, " ") + (state === false ? 'is not supported by the environment' : 'is not available in the build'); + }); + var s = length ? reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0]) : 'as no adapter specified'; + throw new AxiosError("There is no suitable adapter to dispatch the request " + s, 'ERR_NOT_SUPPORT'); + } + return adapter; + }, + adapters: knownAdapters + }; + + /** + * Throws a `CanceledError` if cancellation has been requested. + * + * @param {Object} config The config that is to be used for the request + * + * @returns {void} + */ + function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + if (config.signal && config.signal.aborted) { + throw new CanceledError(null, config); + } + } + + /** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * + * @returns {Promise} The Promise to be fulfilled + */ + function dispatchRequest(config) { + throwIfCancellationRequested(config); + config.headers = AxiosHeaders$1.from(config.headers); + + // Transform request data + config.data = transformData.call(config, config.transformRequest); + if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { + config.headers.setContentType('application/x-www-form-urlencoded', false); + } + var adapter = adapters.getAdapter(config.adapter || defaults$1.adapter, config); + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData.call(config, config.transformResponse, response); + response.headers = AxiosHeaders$1.from(response.headers); + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData.call(config, config.transformResponse, reason.response); + reason.response.headers = AxiosHeaders$1.from(reason.response.headers); + } + } + return Promise.reject(reason); + }); + } + + var VERSION = "1.12.2"; + + var validators$1 = {}; + + // eslint-disable-next-line func-names + ['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach(function (type, i) { + validators$1[type] = function validator(thing) { + return _typeof(thing) === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; + }); + var deprecatedWarnings = {}; + + /** + * Transitional option validator + * + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * + * @returns {function} + */ + validators$1.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return function (value, opt, opts) { + if (validator === false) { + throw new AxiosError(formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), AxiosError.ERR_DEPRECATED); + } + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn(formatMessage(opt, ' has been deprecated since v' + version + ' and will be removed in the near future')); + } + return validator ? validator(value, opt, opts) : true; + }; + }; + validators$1.spelling = function spelling(correctSpelling) { + return function (value, opt) { + // eslint-disable-next-line no-console + console.warn("".concat(opt, " is likely a misspelling of ").concat(correctSpelling)); + return true; + }; + }; + + /** + * Assert object's properties type + * + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + * + * @returns {object} + */ + + function assertOptions(options, schema, allowUnknown) { + if (_typeof(options) !== 'object') { + throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE); + } + var keys = Object.keys(options); + var i = keys.length; + while (i-- > 0) { + var opt = keys[i]; + var validator = schema[opt]; + if (validator) { + var value = options[opt]; + var result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION); + } + } + } + var validator = { + assertOptions: assertOptions, + validators: validators$1 + }; + + var validators = validator.validators; + + /** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + * + * @return {Axios} A new instance of Axios + */ + var Axios = /*#__PURE__*/function () { + function Axios(instanceConfig) { + _classCallCheck(this, Axios); + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager$1(), + response: new InterceptorManager$1() + }; + } + + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + _createClass(Axios, [{ + key: "request", + value: (function () { + var _request2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(configOrUrl, config) { + var dummy, stack; + return _regeneratorRuntime().wrap(function _callee$(_context) { + while (1) switch (_context.prev = _context.next) { + case 0: + _context.prev = 0; + _context.next = 3; + return this._request(configOrUrl, config); + case 3: + return _context.abrupt("return", _context.sent); + case 6: + _context.prev = 6; + _context.t0 = _context["catch"](0); + if (_context.t0 instanceof Error) { + dummy = {}; + Error.captureStackTrace ? Error.captureStackTrace(dummy) : dummy = new Error(); + + // slice off the Error: ... line + stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : ''; + try { + if (!_context.t0.stack) { + _context.t0.stack = stack; + // match without the 2 top stack lines + } else if (stack && !String(_context.t0.stack).endsWith(stack.replace(/^.+\n.+\n/, ''))) { + _context.t0.stack += '\n' + stack; + } + } catch (e) { + // ignore the case where "stack" is an un-writable property + } + } + throw _context.t0; + case 10: + case "end": + return _context.stop(); + } + }, _callee, this, [[0, 6]]); + })); + function request(_x, _x2) { + return _request2.apply(this, arguments); + } + return request; + }()) + }, { + key: "_request", + value: function _request(configOrUrl, config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof configOrUrl === 'string') { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + config = mergeConfig(this.defaults, config); + var _config = config, + transitional = _config.transitional, + paramsSerializer = _config.paramsSerializer, + headers = _config.headers; + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators["boolean"]), + forcedJSONParsing: validators.transitional(validators["boolean"]), + clarifyTimeoutError: validators.transitional(validators["boolean"]) + }, false); + } + if (paramsSerializer != null) { + if (utils$1.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + }; + } else { + validator.assertOptions(paramsSerializer, { + encode: validators["function"], + serialize: validators["function"] + }, true); + } + } + + // Set config.allowAbsoluteUrls + if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + validator.assertOptions(config, { + baseUrl: validators.spelling('baseURL'), + withXsrfToken: validators.spelling('withXSRFToken') + }, true); + + // Set config.method + config.method = (config.method || this.defaults.method || 'get').toLowerCase(); + + // Flatten headers + var contextHeaders = headers && utils$1.merge(headers.common, headers[config.method]); + headers && utils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], function (method) { + delete headers[method]; + }); + config.headers = AxiosHeaders$1.concat(contextHeaders, headers); + + // filter out skipped interceptors + var requestInterceptorChain = []; + var synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + var responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + var promise; + var i = 0; + var len; + if (!synchronousRequestInterceptors) { + var chain = [dispatchRequest.bind(this), undefined]; + chain.unshift.apply(chain, requestInterceptorChain); + chain.push.apply(chain, responseInterceptorChain); + len = chain.length; + promise = Promise.resolve(config); + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + return promise; + } + len = requestInterceptorChain.length; + var newConfig = config; + while (i < len) { + var onFulfilled = requestInterceptorChain[i++]; + var onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + i = 0; + len = responseInterceptorChain.length; + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + return promise; + } + }, { + key: "getUri", + value: function getUri(config) { + config = mergeConfig(this.defaults, config); + var fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } + }]); + return Axios; + }(); // Provide aliases for supported request methods + utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function (url, config) { + return this.request(mergeConfig(config || {}, { + method: method, + url: url, + data: (config || {}).data + })); + }; + }); + utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig(config || {}, { + method: method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url: url, + data: data + })); + }; + } + Axios.prototype[method] = generateHTTPMethod(); + Axios.prototype[method + 'Form'] = generateHTTPMethod(true); + }); + var Axios$1 = Axios; + + /** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @param {Function} executor The executor function. + * + * @returns {CancelToken} + */ + var CancelToken = /*#__PURE__*/function () { + function CancelToken(executor) { + _classCallCheck(this, CancelToken); + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + var resolvePromise; + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + var token = this; + + // eslint-disable-next-line func-names + this.promise.then(function (cancel) { + if (!token._listeners) return; + var i = token._listeners.length; + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = function (onfulfilled) { + var _resolve; + // eslint-disable-next-line func-names + var promise = new Promise(function (resolve) { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + return promise; + }; + executor(function cancel(message, config, request) { + if (token.reason) { + // Cancellation has already been requested + return; + } + token.reason = new CanceledError(message, config, request); + resolvePromise(token.reason); + }); + } + + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + _createClass(CancelToken, [{ + key: "throwIfRequested", + value: function throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + + /** + * Subscribe to the cancel signal + */ + }, { + key: "subscribe", + value: function subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + + /** + * Unsubscribe from the cancel signal + */ + }, { + key: "unsubscribe", + value: function unsubscribe(listener) { + if (!this._listeners) { + return; + } + var index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + }, { + key: "toAbortSignal", + value: function toAbortSignal() { + var _this = this; + var controller = new AbortController(); + var abort = function abort(err) { + controller.abort(err); + }; + this.subscribe(abort); + controller.signal.unsubscribe = function () { + return _this.unsubscribe(abort); + }; + return controller.signal; + } + + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + }], [{ + key: "source", + value: function source() { + var cancel; + var token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token: token, + cancel: cancel + }; + } + }]); + return CancelToken; + }(); + var CancelToken$1 = CancelToken; + + /** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * + * @returns {Function} + */ + function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; + } + + /** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ + function isAxiosError(payload) { + return utils$1.isObject(payload) && payload.isAxiosError === true; + } + + var HttpStatusCode = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511 + }; + Object.entries(HttpStatusCode).forEach(function (_ref) { + var _ref2 = _slicedToArray(_ref, 2), + key = _ref2[0], + value = _ref2[1]; + HttpStatusCode[value] = key; + }); + var HttpStatusCode$1 = HttpStatusCode; + + /** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * + * @returns {Axios} A new instance of Axios + */ + function createInstance(defaultConfig) { + var context = new Axios$1(defaultConfig); + var instance = bind(Axios$1.prototype.request, context); + + // Copy axios.prototype to instance + utils$1.extend(instance, Axios$1.prototype, context, { + allOwnKeys: true + }); + + // Copy context to instance + utils$1.extend(instance, context, null, { + allOwnKeys: true + }); + + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + return instance; + } + + // Create the default instance to be exported + var axios = createInstance(defaults$1); + + // Expose Axios class to allow class inheritance + axios.Axios = Axios$1; + + // Expose Cancel & CancelToken + axios.CanceledError = CanceledError; + axios.CancelToken = CancelToken$1; + axios.isCancel = isCancel; + axios.VERSION = VERSION; + axios.toFormData = toFormData; + + // Expose AxiosError class + axios.AxiosError = AxiosError; + + // alias for CanceledError for backward compatibility + axios.Cancel = axios.CanceledError; + + // Expose all/spread + axios.all = function all(promises) { + return Promise.all(promises); + }; + axios.spread = spread; + + // Expose isAxiosError + axios.isAxiosError = isAxiosError; + + // Expose mergeConfig + axios.mergeConfig = mergeConfig; + axios.AxiosHeaders = AxiosHeaders$1; + axios.formToJSON = function (thing) { + return formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing); + }; + axios.getAdapter = adapters.getAdapter; + axios.HttpStatusCode = HttpStatusCode$1; + axios["default"] = axios; + + return axios; + +})); +//# sourceMappingURL=axios.js.map diff --git a/node_modules/axios/dist/axios.js.map b/node_modules/axios/dist/axios.js.map new file mode 100644 index 0000000..72a541a --- /dev/null +++ b/node_modules/axios/dist/axios.js.map @@ -0,0 +1 @@ +{"version":3,"file":"axios.js","sources":["../lib/helpers/bind.js","../lib/utils.js","../lib/core/AxiosError.js","../lib/helpers/null.js","../lib/helpers/toFormData.js","../lib/helpers/AxiosURLSearchParams.js","../lib/helpers/buildURL.js","../lib/core/InterceptorManager.js","../lib/defaults/transitional.js","../lib/platform/browser/classes/URLSearchParams.js","../lib/platform/browser/classes/FormData.js","../lib/platform/browser/classes/Blob.js","../lib/platform/browser/index.js","../lib/platform/common/utils.js","../lib/platform/index.js","../lib/helpers/toURLEncodedForm.js","../lib/helpers/formDataToJSON.js","../lib/defaults/index.js","../lib/helpers/parseHeaders.js","../lib/core/AxiosHeaders.js","../lib/core/transformData.js","../lib/cancel/isCancel.js","../lib/cancel/CanceledError.js","../lib/core/settle.js","../lib/helpers/parseProtocol.js","../lib/helpers/speedometer.js","../lib/helpers/throttle.js","../lib/helpers/progressEventReducer.js","../lib/helpers/isURLSameOrigin.js","../lib/helpers/cookies.js","../lib/helpers/isAbsoluteURL.js","../lib/helpers/combineURLs.js","../lib/core/buildFullPath.js","../lib/core/mergeConfig.js","../lib/helpers/resolveConfig.js","../lib/adapters/xhr.js","../lib/helpers/composeSignals.js","../lib/helpers/trackStream.js","../lib/adapters/fetch.js","../lib/adapters/adapters.js","../lib/core/dispatchRequest.js","../lib/env/data.js","../lib/helpers/validator.js","../lib/core/Axios.js","../lib/cancel/CancelToken.js","../lib/helpers/spread.js","../lib/helpers/isAxiosError.js","../lib/helpers/HttpStatusCode.js","../lib/axios.js"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n // Early return for non-objects or Buffers to prevent RangeError\n if (!isObject(val) || isBuffer(val)) {\n return false;\n }\n\n try {\n return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n } catch (e) {\n // Fallback for any other objects that might cause RangeError with Object.keys()\n return false;\n }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Buffer check\n if (isBuffer(obj)) {\n return;\n }\n\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n if (isBuffer(obj)){\n return null;\n }\n\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else if (!skipUndefined || !isUndefined(val)) {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n //Buffer check\n if (isBuffer(source)) {\n return source;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isEmptyObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n const msg = error && error.message ? error.message : 'Error';\n\n // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n const errCode = code == null && error ? error.code : code;\n AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n if (error && axiosError.cause == null) {\n Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n }\n\n axiosError.name = (error && error.name) || 'Error';\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), {\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n },\n ...options\n });\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data, this.parseReviver);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn(...args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // browser handles it\n } else if (utils.isFunction(data.getHeaders)) {\n // Node.js FormData (like form-data package)\n const formHeaders = data.getHeaders();\n // Only set safe headers to avoid overwriting security headers\n const allowedHeaders = ['content-type', 'content-length'];\n Object.entries(formHeaders).forEach(([key, val]) => {\n if (allowedHeaders.includes(key.toLowerCase())) {\n headers.set(key, val);\n }\n });\n }\n } \n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError(event) {\n // Browsers deliver a ProgressEvent in XHR onerror\n // (message may be empty; when present, surface it)\n // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n const msg = event && event.message ? event.message : 'Network Error';\n const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n // attach the underlying event for consumers who want details\n err.event = event || null;\n reject(err);\n request = null;\n };\n \n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n Request, Response\n}))(utils.global);\n\nconst {\n ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst factory = (env) => {\n env = utils.merge.call({\n skipUndefined: true\n }, globalFetchAPI, env);\n\n const {fetch: envFetch, Request, Response} = env;\n const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n const isRequestSupported = isFunction(Request);\n const isResponseSupported = isFunction(Response);\n\n if (!isFetchSupported) {\n return false;\n }\n\n const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n );\n\n const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n });\n\n const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n const resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n };\n\n isFetchSupported && ((() => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = (res, config) => {\n let method = res && res[type];\n\n if (method) {\n return method.call(res);\n }\n\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n })());\n\n const getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if (utils.isBlob(body)) {\n return body.size;\n }\n\n if (utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if (utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if (utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n }\n\n const resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n }\n\n return async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n let _fetch = envFetch || fetch;\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request = null;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n const resolvedOptions = {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n };\n\n request = isRequestSupported && new Request(url, resolvedOptions);\n\n let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n let env = config ? config.env : {};\n const {fetch, Request, Response} = env;\n const seeds = [\n Request, Response, fetch\n ];\n\n let len = seeds.length, i = len,\n seed, target, map = seedCache;\n\n while (i--) {\n seed = seeds[i];\n target = map.get(seed);\n\n target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n map = target;\n }\n\n return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: {\n get: fetchAdapter.getFetch,\n }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters, config) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift(...requestInterceptorChain);\n chain.push(...responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n"],"names":["bind","fn","thisArg","wrap","apply","arguments","toString","Object","prototype","getPrototypeOf","iterator","Symbol","toStringTag","kindOf","cache","thing","str","call","slice","toLowerCase","create","kindOfTest","type","typeOfTest","_typeof","isArray","Array","isUndefined","isBuffer","val","constructor","isFunction","isArrayBuffer","isArrayBufferView","result","ArrayBuffer","isView","buffer","isString","isNumber","isObject","isBoolean","isPlainObject","isEmptyObject","keys","length","e","isDate","isFile","isBlob","isFileList","isStream","pipe","isFormData","kind","FormData","append","isURLSearchParams","_map","map","_map2","_slicedToArray","isReadableStream","isRequest","isResponse","isHeaders","trim","replace","forEach","obj","_ref","undefined","_ref$allOwnKeys","allOwnKeys","i","l","getOwnPropertyNames","len","key","findKey","_key","_global","globalThis","self","window","global","isContextDefined","context","merge","_ref2","caseless","skipUndefined","assignValue","targetKey","extend","a","b","_ref3","stripBOM","content","charCodeAt","inherits","superConstructor","props","descriptors","defineProperty","value","assign","toFlatObject","sourceObj","destObj","filter","propFilter","prop","merged","endsWith","searchString","position","String","lastIndex","indexOf","toArray","arr","isTypedArray","TypedArray","Uint8Array","forEachEntry","generator","_iterator","next","done","pair","matchAll","regExp","matches","exec","push","isHTMLForm","toCamelCase","replacer","m","p1","p2","toUpperCase","hasOwnProperty","_ref4","isRegExp","reduceDescriptors","reducer","getOwnPropertyDescriptors","reducedDescriptors","descriptor","name","ret","defineProperties","freezeMethods","enumerable","writable","set","Error","toObjectSet","arrayOrString","delimiter","define","split","noop","toFiniteNumber","defaultValue","Number","isFinite","isSpecCompliantForm","toJSONObject","stack","visit","source","target","reducedValue","isAsyncFn","isThenable","then","_setImmediate","setImmediateSupported","postMessageSupported","setImmediate","token","callbacks","addEventListener","_ref5","data","shift","cb","postMessage","concat","Math","random","setTimeout","asap","queueMicrotask","process","nextTick","isIterable","hasOwnProp","AxiosError","message","code","config","request","response","captureStackTrace","status","utils","toJSON","description","number","fileName","lineNumber","columnNumber","from","error","customProps","axiosError","msg","errCode","cause","configurable","isVisitable","removeBrackets","renderKey","path","dots","each","join","isFlatArray","some","predicates","test","toFormData","formData","options","TypeError","metaTokens","indexes","defined","option","visitor","defaultVisitor","_Blob","Blob","useBlob","convertValue","toISOString","Buffer","JSON","stringify","el","index","exposedHelpers","build","pop","encode","charMap","encodeURIComponent","match","AxiosURLSearchParams","params","_pairs","encoder","_encode","buildURL","url","serialize","serializeFn","serializedParams","hashmarkIndex","InterceptorManager","_classCallCheck","handlers","_createClass","use","fulfilled","rejected","synchronous","runWhen","eject","id","clear","forEachHandler","h","silentJSONParsing","forcedJSONParsing","clarifyTimeoutError","URLSearchParams","isBrowser","classes","protocols","hasBrowserEnv","document","_navigator","navigator","hasStandardBrowserEnv","product","hasStandardBrowserWebWorkerEnv","WorkerGlobalScope","importScripts","origin","location","href","_objectSpread","platform","toURLEncodedForm","helpers","isNode","parsePropPath","arrayToObject","formDataToJSON","buildPath","isNumericKey","isLast","entries","stringifySafely","rawValue","parser","parse","defaults","transitional","transitionalDefaults","adapter","transformRequest","headers","contentType","getContentType","hasJSONContentType","isObjectPayload","setContentType","formSerializer","_FormData","env","transformResponse","JSONRequested","responseType","strictJSONParsing","parseReviver","ERR_BAD_RESPONSE","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","maxBodyLength","validateStatus","common","method","ignoreDuplicateOf","rawHeaders","parsed","line","substring","$internals","normalizeHeader","header","normalizeValue","parseTokens","tokens","tokensRE","isValidHeaderName","matchHeaderValue","isHeaderNameFilter","formatHeader","w","char","buildAccessors","accessorName","methodName","arg1","arg2","arg3","AxiosHeaders","_Symbol$iterator","_Symbol$toStringTag","valueOrRewrite","rewrite","setHeader","_value","_header","_rewrite","lHeader","setHeaders","parseHeaders","dest","_createForOfIteratorHelper","_step","s","n","entry","_toConsumableArray","err","f","get","has","matcher","_delete","deleted","deleteHeader","normalize","format","normalized","_this$constructor","_len","targets","asStrings","getSetCookie","first","computed","_len2","_key2","accessor","internals","accessors","defineAccessor","mapped","headerValue","transformData","fns","transform","isCancel","__CANCEL__","CanceledError","ERR_CANCELED","settle","resolve","reject","ERR_BAD_REQUEST","floor","parseProtocol","speedometer","samplesCount","min","bytes","timestamps","head","tail","firstSampleTS","chunkLength","now","Date","startedAt","bytesCount","passed","round","throttle","freq","timestamp","threshold","lastArgs","timer","invoke","args","clearTimeout","throttled","flush","progressEventReducer","listener","isDownloadStream","bytesNotified","_speedometer","loaded","total","lengthComputable","progressBytes","rate","inRange","_defineProperty","progress","estimated","event","progressEventDecorator","asyncDecorator","isMSIE","URL","protocol","host","port","userAgent","write","expires","domain","secure","cookie","toGMTString","read","RegExp","decodeURIComponent","remove","isAbsoluteURL","combineURLs","baseURL","relativeURL","buildFullPath","requestedURL","allowAbsoluteUrls","isRelativeUrl","headersToObject","mergeConfig","config1","config2","getMergedValue","mergeDeepProperties","valueFromConfig2","defaultToConfig2","mergeDirectKeys","mergeMap","paramsSerializer","timeoutMessage","withCredentials","withXSRFToken","onUploadProgress","onDownloadProgress","decompress","beforeRedirect","transport","httpAgent","httpsAgent","cancelToken","socketPath","responseEncoding","computeConfigValue","configValue","newConfig","auth","btoa","username","password","unescape","getHeaders","formHeaders","allowedHeaders","includes","isURLSameOrigin","xsrfValue","cookies","isXHRAdapterSupported","XMLHttpRequest","Promise","dispatchXhrRequest","_config","resolveConfig","requestData","requestHeaders","onCanceled","uploadThrottled","downloadThrottled","flushUpload","flushDownload","unsubscribe","signal","removeEventListener","open","onloadend","responseHeaders","getAllResponseHeaders","responseData","responseText","statusText","_resolve","_reject","onreadystatechange","handleLoad","readyState","responseURL","onabort","handleAbort","ECONNABORTED","onerror","handleError","ERR_NETWORK","ontimeout","handleTimeout","timeoutErrorMessage","ETIMEDOUT","setRequestHeader","_progressEventReducer","_progressEventReducer2","upload","_progressEventReducer3","_progressEventReducer4","cancel","abort","subscribe","aborted","send","composeSignals","signals","_signals","Boolean","controller","AbortController","reason","streamChunk","_regeneratorRuntime","mark","chunk","chunkSize","pos","end","streamChunk$","_context","prev","byteLength","abrupt","stop","readBytes","_wrapAsyncGenerator","_callee","iterable","_iteratorAbruptCompletion","_didIteratorError","_iteratorError","_callee$","_context2","_asyncIterator","readStream","_awaitAsyncGenerator","sent","delegateYield","_asyncGeneratorDelegate","t1","finish","_x","_x2","_callee2","stream","reader","_yield$_awaitAsyncGen","_callee2$","_context3","asyncIterator","getReader","_x3","trackStream","onProgress","onFinish","_onFinish","ReadableStream","pull","_asyncToGenerator","_callee3","_yield$iterator$next","_done","loadedBytes","_callee3$","_context4","close","enqueue","t0","highWaterMark","DEFAULT_CHUNK_SIZE","globalFetchAPI","Request","Response","_utils$global","TextEncoder","factory","_env","envFetch","fetch","isFetchSupported","isRequestSupported","isResponseSupported","isReadableStreamSupported","encodeText","arrayBuffer","supportsRequestStream","duplexAccessed","hasContentType","body","duplex","supportsResponseStream","resolvers","res","ERR_NOT_SUPPORT","getBodyLength","_request","size","resolveBodyLength","getContentLength","_x4","_callee4","_resolveConfig","_resolveConfig$withCr","fetchOptions","_fetch","composedSignal","requestContentLength","contentTypeHeader","_progressEventDecorat","_progressEventDecorat2","isCredentialsSupported","resolvedOptions","isStreamResponse","responseContentLength","_ref6","_ref7","_onProgress","_flush","_callee4$","toAbortSignal","credentials","t2","_x5","seedCache","Map","getFetch","seeds","seed","knownAdapters","http","httpAdapter","xhr","xhrAdapter","fetchAdapter","renderReason","isResolvedHandle","getAdapter","adapters","_adapters","nameOrAdapter","rejectedReasons","reasons","state","throwIfCancellationRequested","throwIfRequested","dispatchRequest","onAdapterResolution","onAdapterRejection","VERSION","validators","validator","deprecatedWarnings","version","formatMessage","opt","desc","opts","ERR_DEPRECATED","console","warn","spelling","correctSpelling","assertOptions","schema","allowUnknown","ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","Axios","instanceConfig","interceptors","_request2","configOrUrl","dummy","baseUrl","withXsrfToken","contextHeaders","requestInterceptorChain","synchronousRequestInterceptors","unshiftRequestInterceptors","interceptor","unshift","responseInterceptorChain","pushResponseInterceptors","promise","chain","onFulfilled","onRejected","getUri","fullPath","forEachMethodNoData","forEachMethodWithData","generateHTTPMethod","isForm","httpMethod","CancelToken","executor","resolvePromise","promiseExecutor","_listeners","onfulfilled","splice","_this","c","spread","callback","isAxiosError","payload","HttpStatusCode","Continue","SwitchingProtocols","Processing","EarlyHints","Ok","Created","Accepted","NonAuthoritativeInformation","NoContent","ResetContent","PartialContent","MultiStatus","AlreadyReported","ImUsed","MultipleChoices","MovedPermanently","Found","SeeOther","NotModified","UseProxy","Unused","TemporaryRedirect","PermanentRedirect","BadRequest","Unauthorized","PaymentRequired","Forbidden","NotFound","MethodNotAllowed","NotAcceptable","ProxyAuthenticationRequired","RequestTimeout","Conflict","Gone","LengthRequired","PreconditionFailed","PayloadTooLarge","UriTooLong","UnsupportedMediaType","RangeNotSatisfiable","ExpectationFailed","ImATeapot","MisdirectedRequest","UnprocessableEntity","Locked","FailedDependency","TooEarly","UpgradeRequired","PreconditionRequired","TooManyRequests","RequestHeaderFieldsTooLarge","UnavailableForLegalReasons","InternalServerError","NotImplemented","BadGateway","ServiceUnavailable","GatewayTimeout","HttpVersionNotSupported","VariantAlsoNegotiates","InsufficientStorage","LoopDetected","NotExtended","NetworkAuthenticationRequired","createInstance","defaultConfig","instance","axios","Cancel","all","promises","formToJSON"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEe,SAASA,IAAIA,CAACC,EAAE,EAAEC,OAAO,EAAE;IACxC,OAAO,SAASC,IAAIA,GAAG;EACrB,IAAA,OAAOF,EAAE,CAACG,KAAK,CAACF,OAAO,EAAEG,SAAS,CAAC,CAAA;KACpC,CAAA;EACH;;ECFA;;EAEA,IAAOC,QAAQ,GAAIC,MAAM,CAACC,SAAS,CAA5BF,QAAQ,CAAA;EACf,IAAOG,cAAc,GAAIF,MAAM,CAAxBE,cAAc,CAAA;EACrB,IAAOC,QAAQ,GAAiBC,MAAM,CAA/BD,QAAQ;IAAEE,WAAW,GAAID,MAAM,CAArBC,WAAW,CAAA;EAE5B,IAAMC,MAAM,GAAI,UAAAC,KAAK,EAAA;IAAA,OAAI,UAAAC,KAAK,EAAI;EAC9B,IAAA,IAAMC,GAAG,GAAGV,QAAQ,CAACW,IAAI,CAACF,KAAK,CAAC,CAAA;MAChC,OAAOD,KAAK,CAACE,GAAG,CAAC,KAAKF,KAAK,CAACE,GAAG,CAAC,GAAGA,GAAG,CAACE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAACC,WAAW,EAAE,CAAC,CAAA;KACrE,CAAA;EAAA,CAAA,CAAEZ,MAAM,CAACa,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;EAEvB,IAAMC,UAAU,GAAG,SAAbA,UAAUA,CAAIC,IAAI,EAAK;EAC3BA,EAAAA,IAAI,GAAGA,IAAI,CAACH,WAAW,EAAE,CAAA;EACzB,EAAA,OAAO,UAACJ,KAAK,EAAA;EAAA,IAAA,OAAKF,MAAM,CAACE,KAAK,CAAC,KAAKO,IAAI,CAAA;EAAA,GAAA,CAAA;EAC1C,CAAC,CAAA;EAED,IAAMC,UAAU,GAAG,SAAbA,UAAUA,CAAGD,IAAI,EAAA;EAAA,EAAA,OAAI,UAAAP,KAAK,EAAA;EAAA,IAAA,OAAIS,OAAA,CAAOT,KAAK,CAAA,KAAKO,IAAI,CAAA;EAAA,GAAA,CAAA;EAAA,CAAA,CAAA;;EAEzD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAOG,OAAO,GAAIC,KAAK,CAAhBD,OAAO,CAAA;;EAEd;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAME,WAAW,GAAGJ,UAAU,CAAC,WAAW,CAAC,CAAA;;EAE3C;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASK,QAAQA,CAACC,GAAG,EAAE;EACrB,EAAA,OAAOA,GAAG,KAAK,IAAI,IAAI,CAACF,WAAW,CAACE,GAAG,CAAC,IAAIA,GAAG,CAACC,WAAW,KAAK,IAAI,IAAI,CAACH,WAAW,CAACE,GAAG,CAACC,WAAW,CAAC,IAChGC,YAAU,CAACF,GAAG,CAACC,WAAW,CAACF,QAAQ,CAAC,IAAIC,GAAG,CAACC,WAAW,CAACF,QAAQ,CAACC,GAAG,CAAC,CAAA;EAC5E,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMG,aAAa,GAAGX,UAAU,CAAC,aAAa,CAAC,CAAA;;EAG/C;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASY,iBAAiBA,CAACJ,GAAG,EAAE;EAC9B,EAAA,IAAIK,MAAM,CAAA;IACV,IAAK,OAAOC,WAAW,KAAK,WAAW,IAAMA,WAAW,CAACC,MAAO,EAAE;EAChEF,IAAAA,MAAM,GAAGC,WAAW,CAACC,MAAM,CAACP,GAAG,CAAC,CAAA;EAClC,GAAC,MAAM;EACLK,IAAAA,MAAM,GAAIL,GAAG,IAAMA,GAAG,CAACQ,MAAO,IAAKL,aAAa,CAACH,GAAG,CAACQ,MAAM,CAAE,CAAA;EAC/D,GAAA;EACA,EAAA,OAAOH,MAAM,CAAA;EACf,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMI,QAAQ,GAAGf,UAAU,CAAC,QAAQ,CAAC,CAAA;;EAErC;EACA;EACA;EACA;EACA;EACA;EACA,IAAMQ,YAAU,GAAGR,UAAU,CAAC,UAAU,CAAC,CAAA;;EAEzC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMgB,QAAQ,GAAGhB,UAAU,CAAC,QAAQ,CAAC,CAAA;;EAErC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMiB,QAAQ,GAAG,SAAXA,QAAQA,CAAIzB,KAAK,EAAA;IAAA,OAAKA,KAAK,KAAK,IAAI,IAAIS,OAAA,CAAOT,KAAK,MAAK,QAAQ,CAAA;EAAA,CAAA,CAAA;;EAEvE;EACA;EACA;EACA;EACA;EACA;EACA,IAAM0B,SAAS,GAAG,SAAZA,SAASA,CAAG1B,KAAK,EAAA;EAAA,EAAA,OAAIA,KAAK,KAAK,IAAI,IAAIA,KAAK,KAAK,KAAK,CAAA;EAAA,CAAA,CAAA;;EAE5D;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM2B,aAAa,GAAG,SAAhBA,aAAaA,CAAIb,GAAG,EAAK;EAC7B,EAAA,IAAIhB,MAAM,CAACgB,GAAG,CAAC,KAAK,QAAQ,EAAE;EAC5B,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;EAEA,EAAA,IAAMrB,SAAS,GAAGC,cAAc,CAACoB,GAAG,CAAC,CAAA;EACrC,EAAA,OAAO,CAACrB,SAAS,KAAK,IAAI,IAAIA,SAAS,KAAKD,MAAM,CAACC,SAAS,IAAID,MAAM,CAACE,cAAc,CAACD,SAAS,CAAC,KAAK,IAAI,KAAK,EAAEI,WAAW,IAAIiB,GAAG,CAAC,IAAI,EAAEnB,QAAQ,IAAImB,GAAG,CAAC,CAAA;EAC3J,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMc,aAAa,GAAG,SAAhBA,aAAaA,CAAId,GAAG,EAAK;EAC7B;IACA,IAAI,CAACW,QAAQ,CAACX,GAAG,CAAC,IAAID,QAAQ,CAACC,GAAG,CAAC,EAAE;EACnC,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;IAEA,IAAI;MACF,OAAOtB,MAAM,CAACqC,IAAI,CAACf,GAAG,CAAC,CAACgB,MAAM,KAAK,CAAC,IAAItC,MAAM,CAACE,cAAc,CAACoB,GAAG,CAAC,KAAKtB,MAAM,CAACC,SAAS,CAAA;KACxF,CAAC,OAAOsC,CAAC,EAAE;EACV;EACA,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;EACF,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMC,MAAM,GAAG1B,UAAU,CAAC,MAAM,CAAC,CAAA;;EAEjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM2B,MAAM,GAAG3B,UAAU,CAAC,MAAM,CAAC,CAAA;;EAEjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM4B,MAAM,GAAG5B,UAAU,CAAC,MAAM,CAAC,CAAA;;EAEjC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM6B,UAAU,GAAG7B,UAAU,CAAC,UAAU,CAAC,CAAA;;EAEzC;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM8B,QAAQ,GAAG,SAAXA,QAAQA,CAAItB,GAAG,EAAA;IAAA,OAAKW,QAAQ,CAACX,GAAG,CAAC,IAAIE,YAAU,CAACF,GAAG,CAACuB,IAAI,CAAC,CAAA;EAAA,CAAA,CAAA;;EAE/D;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMC,UAAU,GAAG,SAAbA,UAAUA,CAAItC,KAAK,EAAK;EAC5B,EAAA,IAAIuC,IAAI,CAAA;IACR,OAAOvC,KAAK,KACT,OAAOwC,QAAQ,KAAK,UAAU,IAAIxC,KAAK,YAAYwC,QAAQ,IAC1DxB,YAAU,CAAChB,KAAK,CAACyC,MAAM,CAAC,KACtB,CAACF,IAAI,GAAGzC,MAAM,CAACE,KAAK,CAAC,MAAM,UAAU;EACrC;EACCuC,EAAAA,IAAI,KAAK,QAAQ,IAAIvB,YAAU,CAAChB,KAAK,CAACT,QAAQ,CAAC,IAAIS,KAAK,CAACT,QAAQ,EAAE,KAAK,mBAAoB,CAEhG,CACF,CAAA;EACH,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMmD,iBAAiB,GAAGpC,UAAU,CAAC,iBAAiB,CAAC,CAAA;EAEvD,IAAAqC,IAAA,GAA6D,CAAC,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,CAAC,CAACC,GAAG,CAACtC,UAAU,CAAC;IAAAuC,KAAA,GAAAC,cAAA,CAAAH,IAAA,EAAA,CAAA,CAAA;EAA1HI,EAAAA,gBAAgB,GAAAF,KAAA,CAAA,CAAA,CAAA;EAAEG,EAAAA,SAAS,GAAAH,KAAA,CAAA,CAAA,CAAA;EAAEI,EAAAA,UAAU,GAAAJ,KAAA,CAAA,CAAA,CAAA;EAAEK,EAAAA,SAAS,GAAAL,KAAA,CAAA,CAAA,CAAA,CAAA;;EAEzD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMM,IAAI,GAAG,SAAPA,IAAIA,CAAIlD,GAAG,EAAA;EAAA,EAAA,OAAKA,GAAG,CAACkD,IAAI,GAC5BlD,GAAG,CAACkD,IAAI,EAAE,GAAGlD,GAAG,CAACmD,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAA;EAAA,CAAA,CAAA;;EAEpE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASC,OAAOA,CAACC,GAAG,EAAEpE,EAAE,EAA6B;EAAA,EAAA,IAAAqE,IAAA,GAAAjE,SAAA,CAAAwC,MAAA,GAAA,CAAA,IAAAxC,SAAA,CAAA,CAAA,CAAA,KAAAkE,SAAA,GAAAlE,SAAA,CAAA,CAAA,CAAA,GAAJ,EAAE;MAAAmE,eAAA,GAAAF,IAAA,CAAxBG,UAAU;EAAVA,IAAAA,UAAU,GAAAD,eAAA,KAAG,KAAA,CAAA,GAAA,KAAK,GAAAA,eAAA,CAAA;EAC3C;IACA,IAAIH,GAAG,KAAK,IAAI,IAAI,OAAOA,GAAG,KAAK,WAAW,EAAE;EAC9C,IAAA,OAAA;EACF,GAAA;EAEA,EAAA,IAAIK,CAAC,CAAA;EACL,EAAA,IAAIC,CAAC,CAAA;;EAEL;EACA,EAAA,IAAInD,OAAA,CAAO6C,GAAG,CAAA,KAAK,QAAQ,EAAE;EAC3B;MACAA,GAAG,GAAG,CAACA,GAAG,CAAC,CAAA;EACb,GAAA;EAEA,EAAA,IAAI5C,OAAO,CAAC4C,GAAG,CAAC,EAAE;EAChB;EACA,IAAA,KAAKK,CAAC,GAAG,CAAC,EAAEC,CAAC,GAAGN,GAAG,CAACxB,MAAM,EAAE6B,CAAC,GAAGC,CAAC,EAAED,CAAC,EAAE,EAAE;EACtCzE,MAAAA,EAAE,CAACgB,IAAI,CAAC,IAAI,EAAEoD,GAAG,CAACK,CAAC,CAAC,EAAEA,CAAC,EAAEL,GAAG,CAAC,CAAA;EAC/B,KAAA;EACF,GAAC,MAAM;EACL;EACA,IAAA,IAAIzC,QAAQ,CAACyC,GAAG,CAAC,EAAE;EACjB,MAAA,OAAA;EACF,KAAA;;EAEA;EACA,IAAA,IAAMzB,IAAI,GAAG6B,UAAU,GAAGlE,MAAM,CAACqE,mBAAmB,CAACP,GAAG,CAAC,GAAG9D,MAAM,CAACqC,IAAI,CAACyB,GAAG,CAAC,CAAA;EAC5E,IAAA,IAAMQ,GAAG,GAAGjC,IAAI,CAACC,MAAM,CAAA;EACvB,IAAA,IAAIiC,GAAG,CAAA;MAEP,KAAKJ,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGG,GAAG,EAAEH,CAAC,EAAE,EAAE;EACxBI,MAAAA,GAAG,GAAGlC,IAAI,CAAC8B,CAAC,CAAC,CAAA;EACbzE,MAAAA,EAAE,CAACgB,IAAI,CAAC,IAAI,EAAEoD,GAAG,CAACS,GAAG,CAAC,EAAEA,GAAG,EAAET,GAAG,CAAC,CAAA;EACnC,KAAA;EACF,GAAA;EACF,CAAA;EAEA,SAASU,OAAOA,CAACV,GAAG,EAAES,GAAG,EAAE;EACzB,EAAA,IAAIlD,QAAQ,CAACyC,GAAG,CAAC,EAAC;EAChB,IAAA,OAAO,IAAI,CAAA;EACb,GAAA;EAEAS,EAAAA,GAAG,GAAGA,GAAG,CAAC3D,WAAW,EAAE,CAAA;EACvB,EAAA,IAAMyB,IAAI,GAAGrC,MAAM,CAACqC,IAAI,CAACyB,GAAG,CAAC,CAAA;EAC7B,EAAA,IAAIK,CAAC,GAAG9B,IAAI,CAACC,MAAM,CAAA;EACnB,EAAA,IAAImC,IAAI,CAAA;EACR,EAAA,OAAON,CAAC,EAAE,GAAG,CAAC,EAAE;EACdM,IAAAA,IAAI,GAAGpC,IAAI,CAAC8B,CAAC,CAAC,CAAA;EACd,IAAA,IAAII,GAAG,KAAKE,IAAI,CAAC7D,WAAW,EAAE,EAAE;EAC9B,MAAA,OAAO6D,IAAI,CAAA;EACb,KAAA;EACF,GAAA;EACA,EAAA,OAAO,IAAI,CAAA;EACb,CAAA;EAEA,IAAMC,OAAO,GAAI,YAAM;EACrB;EACA,EAAA,IAAI,OAAOC,UAAU,KAAK,WAAW,EAAE,OAAOA,UAAU,CAAA;EACxD,EAAA,OAAO,OAAOC,IAAI,KAAK,WAAW,GAAGA,IAAI,GAAI,OAAOC,MAAM,KAAK,WAAW,GAAGA,MAAM,GAAGC,MAAO,CAAA;EAC/F,CAAC,EAAG,CAAA;EAEJ,IAAMC,gBAAgB,GAAG,SAAnBA,gBAAgBA,CAAIC,OAAO,EAAA;IAAA,OAAK,CAAC5D,WAAW,CAAC4D,OAAO,CAAC,IAAIA,OAAO,KAAKN,OAAO,CAAA;EAAA,CAAA,CAAA;;EAElF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASO,KAAKA;EAAC,EAA6B;IAC1C,IAAAC,KAAA,GAAkCH,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE;MAA/DI,QAAQ,GAAAD,KAAA,CAARC,QAAQ;MAAEC,aAAa,GAAAF,KAAA,CAAbE,aAAa,CAAA;IAC9B,IAAMzD,MAAM,GAAG,EAAE,CAAA;IACjB,IAAM0D,WAAW,GAAG,SAAdA,WAAWA,CAAI/D,GAAG,EAAEiD,GAAG,EAAK;MAChC,IAAMe,SAAS,GAAGH,QAAQ,IAAIX,OAAO,CAAC7C,MAAM,EAAE4C,GAAG,CAAC,IAAIA,GAAG,CAAA;EACzD,IAAA,IAAIpC,aAAa,CAACR,MAAM,CAAC2D,SAAS,CAAC,CAAC,IAAInD,aAAa,CAACb,GAAG,CAAC,EAAE;EAC1DK,MAAAA,MAAM,CAAC2D,SAAS,CAAC,GAAGL,KAAK,CAACtD,MAAM,CAAC2D,SAAS,CAAC,EAAEhE,GAAG,CAAC,CAAA;EACnD,KAAC,MAAM,IAAIa,aAAa,CAACb,GAAG,CAAC,EAAE;QAC7BK,MAAM,CAAC2D,SAAS,CAAC,GAAGL,KAAK,CAAC,EAAE,EAAE3D,GAAG,CAAC,CAAA;EACpC,KAAC,MAAM,IAAIJ,OAAO,CAACI,GAAG,CAAC,EAAE;QACvBK,MAAM,CAAC2D,SAAS,CAAC,GAAGhE,GAAG,CAACX,KAAK,EAAE,CAAA;OAChC,MAAM,IAAI,CAACyE,aAAa,IAAI,CAAChE,WAAW,CAACE,GAAG,CAAC,EAAE;EAC9CK,MAAAA,MAAM,CAAC2D,SAAS,CAAC,GAAGhE,GAAG,CAAA;EACzB,KAAA;KACD,CAAA;EAED,EAAA,KAAK,IAAI6C,CAAC,GAAG,CAAC,EAAEC,CAAC,GAAGtE,SAAS,CAACwC,MAAM,EAAE6B,CAAC,GAAGC,CAAC,EAAED,CAAC,EAAE,EAAE;EAChDrE,IAAAA,SAAS,CAACqE,CAAC,CAAC,IAAIN,OAAO,CAAC/D,SAAS,CAACqE,CAAC,CAAC,EAAEkB,WAAW,CAAC,CAAA;EACpD,GAAA;EACA,EAAA,OAAO1D,MAAM,CAAA;EACf,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM4D,MAAM,GAAG,SAATA,MAAMA,CAAIC,CAAC,EAAEC,CAAC,EAAE9F,OAAO,EAAuB;EAAA,EAAA,IAAA+F,KAAA,GAAA5F,SAAA,CAAAwC,MAAA,GAAA,CAAA,IAAAxC,SAAA,CAAA,CAAA,CAAA,KAAAkE,SAAA,GAAAlE,SAAA,CAAA,CAAA,CAAA,GAAP,EAAE;MAAfoE,UAAU,GAAAwB,KAAA,CAAVxB,UAAU,CAAA;EACxCL,EAAAA,OAAO,CAAC4B,CAAC,EAAE,UAACnE,GAAG,EAAEiD,GAAG,EAAK;EACvB,IAAA,IAAI5E,OAAO,IAAI6B,YAAU,CAACF,GAAG,CAAC,EAAE;QAC9BkE,CAAC,CAACjB,GAAG,CAAC,GAAG9E,IAAI,CAAC6B,GAAG,EAAE3B,OAAO,CAAC,CAAA;EAC7B,KAAC,MAAM;EACL6F,MAAAA,CAAC,CAACjB,GAAG,CAAC,GAAGjD,GAAG,CAAA;EACd,KAAA;EACF,GAAC,EAAE;EAAC4C,IAAAA,UAAU,EAAVA,UAAAA;EAAU,GAAC,CAAC,CAAA;EAChB,EAAA,OAAOsB,CAAC,CAAA;EACV,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMG,QAAQ,GAAG,SAAXA,QAAQA,CAAIC,OAAO,EAAK;IAC5B,IAAIA,OAAO,CAACC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE;EACpCD,IAAAA,OAAO,GAAGA,OAAO,CAACjF,KAAK,CAAC,CAAC,CAAC,CAAA;EAC5B,GAAA;EACA,EAAA,OAAOiF,OAAO,CAAA;EAChB,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAME,QAAQ,GAAG,SAAXA,QAAQA,CAAIvE,WAAW,EAAEwE,gBAAgB,EAAEC,KAAK,EAAEC,WAAW,EAAK;EACtE1E,EAAAA,WAAW,CAACtB,SAAS,GAAGD,MAAM,CAACa,MAAM,CAACkF,gBAAgB,CAAC9F,SAAS,EAAEgG,WAAW,CAAC,CAAA;EAC9E1E,EAAAA,WAAW,CAACtB,SAAS,CAACsB,WAAW,GAAGA,WAAW,CAAA;EAC/CvB,EAAAA,MAAM,CAACkG,cAAc,CAAC3E,WAAW,EAAE,OAAO,EAAE;MAC1C4E,KAAK,EAAEJ,gBAAgB,CAAC9F,SAAAA;EAC1B,GAAC,CAAC,CAAA;IACF+F,KAAK,IAAIhG,MAAM,CAACoG,MAAM,CAAC7E,WAAW,CAACtB,SAAS,EAAE+F,KAAK,CAAC,CAAA;EACtD,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMK,YAAY,GAAG,SAAfA,YAAYA,CAAIC,SAAS,EAAEC,OAAO,EAAEC,MAAM,EAAEC,UAAU,EAAK;EAC/D,EAAA,IAAIT,KAAK,CAAA;EACT,EAAA,IAAI7B,CAAC,CAAA;EACL,EAAA,IAAIuC,IAAI,CAAA;IACR,IAAMC,MAAM,GAAG,EAAE,CAAA;EAEjBJ,EAAAA,OAAO,GAAGA,OAAO,IAAI,EAAE,CAAA;EACvB;EACA,EAAA,IAAID,SAAS,IAAI,IAAI,EAAE,OAAOC,OAAO,CAAA;IAErC,GAAG;EACDP,IAAAA,KAAK,GAAGhG,MAAM,CAACqE,mBAAmB,CAACiC,SAAS,CAAC,CAAA;MAC7CnC,CAAC,GAAG6B,KAAK,CAAC1D,MAAM,CAAA;EAChB,IAAA,OAAO6B,CAAC,EAAE,GAAG,CAAC,EAAE;EACduC,MAAAA,IAAI,GAAGV,KAAK,CAAC7B,CAAC,CAAC,CAAA;EACf,MAAA,IAAI,CAAC,CAACsC,UAAU,IAAIA,UAAU,CAACC,IAAI,EAAEJ,SAAS,EAAEC,OAAO,CAAC,KAAK,CAACI,MAAM,CAACD,IAAI,CAAC,EAAE;EAC1EH,QAAAA,OAAO,CAACG,IAAI,CAAC,GAAGJ,SAAS,CAACI,IAAI,CAAC,CAAA;EAC/BC,QAAAA,MAAM,CAACD,IAAI,CAAC,GAAG,IAAI,CAAA;EACrB,OAAA;EACF,KAAA;MACAJ,SAAS,GAAGE,MAAM,KAAK,KAAK,IAAItG,cAAc,CAACoG,SAAS,CAAC,CAAA;EAC3D,GAAC,QAAQA,SAAS,KAAK,CAACE,MAAM,IAAIA,MAAM,CAACF,SAAS,EAAEC,OAAO,CAAC,CAAC,IAAID,SAAS,KAAKtG,MAAM,CAACC,SAAS,EAAA;EAE/F,EAAA,OAAOsG,OAAO,CAAA;EAChB,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMK,QAAQ,GAAG,SAAXA,QAAQA,CAAInG,GAAG,EAAEoG,YAAY,EAAEC,QAAQ,EAAK;EAChDrG,EAAAA,GAAG,GAAGsG,MAAM,CAACtG,GAAG,CAAC,CAAA;IACjB,IAAIqG,QAAQ,KAAK9C,SAAS,IAAI8C,QAAQ,GAAGrG,GAAG,CAAC6B,MAAM,EAAE;MACnDwE,QAAQ,GAAGrG,GAAG,CAAC6B,MAAM,CAAA;EACvB,GAAA;IACAwE,QAAQ,IAAID,YAAY,CAACvE,MAAM,CAAA;IAC/B,IAAM0E,SAAS,GAAGvG,GAAG,CAACwG,OAAO,CAACJ,YAAY,EAAEC,QAAQ,CAAC,CAAA;EACrD,EAAA,OAAOE,SAAS,KAAK,CAAC,CAAC,IAAIA,SAAS,KAAKF,QAAQ,CAAA;EACnD,CAAC,CAAA;;EAGD;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMI,OAAO,GAAG,SAAVA,OAAOA,CAAI1G,KAAK,EAAK;EACzB,EAAA,IAAI,CAACA,KAAK,EAAE,OAAO,IAAI,CAAA;EACvB,EAAA,IAAIU,OAAO,CAACV,KAAK,CAAC,EAAE,OAAOA,KAAK,CAAA;EAChC,EAAA,IAAI2D,CAAC,GAAG3D,KAAK,CAAC8B,MAAM,CAAA;EACpB,EAAA,IAAI,CAACN,QAAQ,CAACmC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAA;EAC7B,EAAA,IAAMgD,GAAG,GAAG,IAAIhG,KAAK,CAACgD,CAAC,CAAC,CAAA;EACxB,EAAA,OAAOA,CAAC,EAAE,GAAG,CAAC,EAAE;EACdgD,IAAAA,GAAG,CAAChD,CAAC,CAAC,GAAG3D,KAAK,CAAC2D,CAAC,CAAC,CAAA;EACnB,GAAA;EACA,EAAA,OAAOgD,GAAG,CAAA;EACZ,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMC,YAAY,GAAI,UAAAC,UAAU,EAAI;EAClC;IACA,OAAO,UAAA7G,KAAK,EAAI;EACd,IAAA,OAAO6G,UAAU,IAAI7G,KAAK,YAAY6G,UAAU,CAAA;KACjD,CAAA;EACH,CAAC,CAAE,OAAOC,UAAU,KAAK,WAAW,IAAIpH,cAAc,CAACoH,UAAU,CAAC,CAAC,CAAA;;EAEnE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMC,YAAY,GAAG,SAAfA,YAAYA,CAAIzD,GAAG,EAAEpE,EAAE,EAAK;EAChC,EAAA,IAAM8H,SAAS,GAAG1D,GAAG,IAAIA,GAAG,CAAC3D,QAAQ,CAAC,CAAA;EAEtC,EAAA,IAAMsH,SAAS,GAAGD,SAAS,CAAC9G,IAAI,CAACoD,GAAG,CAAC,CAAA;EAErC,EAAA,IAAInC,MAAM,CAAA;EAEV,EAAA,OAAO,CAACA,MAAM,GAAG8F,SAAS,CAACC,IAAI,EAAE,KAAK,CAAC/F,MAAM,CAACgG,IAAI,EAAE;EAClD,IAAA,IAAMC,IAAI,GAAGjG,MAAM,CAACwE,KAAK,CAAA;EACzBzG,IAAAA,EAAE,CAACgB,IAAI,CAACoD,GAAG,EAAE8D,IAAI,CAAC,CAAC,CAAC,EAAEA,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;EAChC,GAAA;EACF,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMC,QAAQ,GAAG,SAAXA,QAAQA,CAAIC,MAAM,EAAErH,GAAG,EAAK;EAChC,EAAA,IAAIsH,OAAO,CAAA;IACX,IAAMZ,GAAG,GAAG,EAAE,CAAA;IAEd,OAAO,CAACY,OAAO,GAAGD,MAAM,CAACE,IAAI,CAACvH,GAAG,CAAC,MAAM,IAAI,EAAE;EAC5C0G,IAAAA,GAAG,CAACc,IAAI,CAACF,OAAO,CAAC,CAAA;EACnB,GAAA;EAEA,EAAA,OAAOZ,GAAG,CAAA;EACZ,CAAC,CAAA;;EAED;EACA,IAAMe,UAAU,GAAGpH,UAAU,CAAC,iBAAiB,CAAC,CAAA;EAEhD,IAAMqH,WAAW,GAAG,SAAdA,WAAWA,CAAG1H,GAAG,EAAI;EACzB,EAAA,OAAOA,GAAG,CAACG,WAAW,EAAE,CAACgD,OAAO,CAAC,uBAAuB,EACtD,SAASwE,QAAQA,CAACC,CAAC,EAAEC,EAAE,EAAEC,EAAE,EAAE;EAC3B,IAAA,OAAOD,EAAE,CAACE,WAAW,EAAE,GAAGD,EAAE,CAAA;EAC9B,GACF,CAAC,CAAA;EACH,CAAC,CAAA;;EAED;EACA,IAAME,cAAc,GAAI,UAAAC,KAAA,EAAA;EAAA,EAAA,IAAED,cAAc,GAAAC,KAAA,CAAdD,cAAc,CAAA;IAAA,OAAM,UAAC3E,GAAG,EAAE4C,IAAI,EAAA;EAAA,IAAA,OAAK+B,cAAc,CAAC/H,IAAI,CAACoD,GAAG,EAAE4C,IAAI,CAAC,CAAA;EAAA,GAAA,CAAA;EAAA,CAAE1G,CAAAA,MAAM,CAACC,SAAS,CAAC,CAAA;;EAE9G;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAM0I,QAAQ,GAAG7H,UAAU,CAAC,QAAQ,CAAC,CAAA;EAErC,IAAM8H,iBAAiB,GAAG,SAApBA,iBAAiBA,CAAI9E,GAAG,EAAE+E,OAAO,EAAK;EAC1C,EAAA,IAAM5C,WAAW,GAAGjG,MAAM,CAAC8I,yBAAyB,CAAChF,GAAG,CAAC,CAAA;IACzD,IAAMiF,kBAAkB,GAAG,EAAE,CAAA;EAE7BlF,EAAAA,OAAO,CAACoC,WAAW,EAAE,UAAC+C,UAAU,EAAEC,IAAI,EAAK;EACzC,IAAA,IAAIC,GAAG,CAAA;EACP,IAAA,IAAI,CAACA,GAAG,GAAGL,OAAO,CAACG,UAAU,EAAEC,IAAI,EAAEnF,GAAG,CAAC,MAAM,KAAK,EAAE;EACpDiF,MAAAA,kBAAkB,CAACE,IAAI,CAAC,GAAGC,GAAG,IAAIF,UAAU,CAAA;EAC9C,KAAA;EACF,GAAC,CAAC,CAAA;EAEFhJ,EAAAA,MAAM,CAACmJ,gBAAgB,CAACrF,GAAG,EAAEiF,kBAAkB,CAAC,CAAA;EAClD,CAAC,CAAA;;EAED;EACA;EACA;EACA;;EAEA,IAAMK,aAAa,GAAG,SAAhBA,aAAaA,CAAItF,GAAG,EAAK;EAC7B8E,EAAAA,iBAAiB,CAAC9E,GAAG,EAAE,UAACkF,UAAU,EAAEC,IAAI,EAAK;EAC3C;MACA,IAAIzH,YAAU,CAACsC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAACmD,OAAO,CAACgC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE;EAC7E,MAAA,OAAO,KAAK,CAAA;EACd,KAAA;EAEA,IAAA,IAAM9C,KAAK,GAAGrC,GAAG,CAACmF,IAAI,CAAC,CAAA;EAEvB,IAAA,IAAI,CAACzH,YAAU,CAAC2E,KAAK,CAAC,EAAE,OAAA;MAExB6C,UAAU,CAACK,UAAU,GAAG,KAAK,CAAA;MAE7B,IAAI,UAAU,IAAIL,UAAU,EAAE;QAC5BA,UAAU,CAACM,QAAQ,GAAG,KAAK,CAAA;EAC3B,MAAA,OAAA;EACF,KAAA;EAEA,IAAA,IAAI,CAACN,UAAU,CAACO,GAAG,EAAE;QACnBP,UAAU,CAACO,GAAG,GAAG,YAAM;EACrB,QAAA,MAAMC,KAAK,CAAC,qCAAqC,GAAGP,IAAI,GAAG,IAAI,CAAC,CAAA;SACjE,CAAA;EACH,KAAA;EACF,GAAC,CAAC,CAAA;EACJ,CAAC,CAAA;EAED,IAAMQ,WAAW,GAAG,SAAdA,WAAWA,CAAIC,aAAa,EAAEC,SAAS,EAAK;IAChD,IAAM7F,GAAG,GAAG,EAAE,CAAA;EAEd,EAAA,IAAM8F,MAAM,GAAG,SAATA,MAAMA,CAAIzC,GAAG,EAAK;EACtBA,IAAAA,GAAG,CAACtD,OAAO,CAAC,UAAAsC,KAAK,EAAI;EACnBrC,MAAAA,GAAG,CAACqC,KAAK,CAAC,GAAG,IAAI,CAAA;EACnB,KAAC,CAAC,CAAA;KACH,CAAA;IAEDjF,OAAO,CAACwI,aAAa,CAAC,GAAGE,MAAM,CAACF,aAAa,CAAC,GAAGE,MAAM,CAAC7C,MAAM,CAAC2C,aAAa,CAAC,CAACG,KAAK,CAACF,SAAS,CAAC,CAAC,CAAA;EAE/F,EAAA,OAAO7F,GAAG,CAAA;EACZ,CAAC,CAAA;EAED,IAAMgG,IAAI,GAAG,SAAPA,IAAIA,GAAS,EAAE,CAAA;EAErB,IAAMC,cAAc,GAAG,SAAjBA,cAAcA,CAAI5D,KAAK,EAAE6D,YAAY,EAAK;EAC9C,EAAA,OAAO7D,KAAK,IAAI,IAAI,IAAI8D,MAAM,CAACC,QAAQ,CAAC/D,KAAK,GAAG,CAACA,KAAK,CAAC,GAAGA,KAAK,GAAG6D,YAAY,CAAA;EAChF,CAAC,CAAA;;EAID;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASG,mBAAmBA,CAAC3J,KAAK,EAAE;IAClC,OAAO,CAAC,EAAEA,KAAK,IAAIgB,YAAU,CAAChB,KAAK,CAACyC,MAAM,CAAC,IAAIzC,KAAK,CAACH,WAAW,CAAC,KAAK,UAAU,IAAIG,KAAK,CAACL,QAAQ,CAAC,CAAC,CAAA;EACtG,CAAA;EAEA,IAAMiK,YAAY,GAAG,SAAfA,YAAYA,CAAItG,GAAG,EAAK;EAC5B,EAAA,IAAMuG,KAAK,GAAG,IAAIlJ,KAAK,CAAC,EAAE,CAAC,CAAA;IAE3B,IAAMmJ,KAAK,GAAG,SAARA,KAAKA,CAAIC,MAAM,EAAEpG,CAAC,EAAK;EAE3B,IAAA,IAAIlC,QAAQ,CAACsI,MAAM,CAAC,EAAE;QACpB,IAAIF,KAAK,CAACpD,OAAO,CAACsD,MAAM,CAAC,IAAI,CAAC,EAAE;EAC9B,QAAA,OAAA;EACF,OAAA;;EAEA;EACA,MAAA,IAAIlJ,QAAQ,CAACkJ,MAAM,CAAC,EAAE;EACpB,QAAA,OAAOA,MAAM,CAAA;EACf,OAAA;EAEA,MAAA,IAAG,EAAE,QAAQ,IAAIA,MAAM,CAAC,EAAE;EACxBF,QAAAA,KAAK,CAAClG,CAAC,CAAC,GAAGoG,MAAM,CAAA;UACjB,IAAMC,MAAM,GAAGtJ,OAAO,CAACqJ,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAA;EAExC1G,QAAAA,OAAO,CAAC0G,MAAM,EAAE,UAACpE,KAAK,EAAE5B,GAAG,EAAK;YAC9B,IAAMkG,YAAY,GAAGH,KAAK,CAACnE,KAAK,EAAEhC,CAAC,GAAG,CAAC,CAAC,CAAA;YACxC,CAAC/C,WAAW,CAACqJ,YAAY,CAAC,KAAKD,MAAM,CAACjG,GAAG,CAAC,GAAGkG,YAAY,CAAC,CAAA;EAC5D,SAAC,CAAC,CAAA;EAEFJ,QAAAA,KAAK,CAAClG,CAAC,CAAC,GAAGH,SAAS,CAAA;EAEpB,QAAA,OAAOwG,MAAM,CAAA;EACf,OAAA;EACF,KAAA;EAEA,IAAA,OAAOD,MAAM,CAAA;KACd,CAAA;EAED,EAAA,OAAOD,KAAK,CAACxG,GAAG,EAAE,CAAC,CAAC,CAAA;EACtB,CAAC,CAAA;EAED,IAAM4G,SAAS,GAAG5J,UAAU,CAAC,eAAe,CAAC,CAAA;EAE7C,IAAM6J,UAAU,GAAG,SAAbA,UAAUA,CAAInK,KAAK,EAAA;IAAA,OACvBA,KAAK,KAAKyB,QAAQ,CAACzB,KAAK,CAAC,IAAIgB,YAAU,CAAChB,KAAK,CAAC,CAAC,IAAIgB,YAAU,CAAChB,KAAK,CAACoK,IAAI,CAAC,IAAIpJ,YAAU,CAAChB,KAAK,CAAA,OAAA,CAAM,CAAC,CAAA;EAAA,CAAA,CAAA;;EAEtG;EACA;;EAEA,IAAMqK,aAAa,GAAI,UAACC,qBAAqB,EAAEC,oBAAoB,EAAK;EACtE,EAAA,IAAID,qBAAqB,EAAE;EACzB,IAAA,OAAOE,YAAY,CAAA;EACrB,GAAA;EAEA,EAAA,OAAOD,oBAAoB,GAAI,UAACE,KAAK,EAAEC,SAAS,EAAK;EACnDxG,IAAAA,OAAO,CAACyG,gBAAgB,CAAC,SAAS,EAAE,UAAAC,KAAA,EAAoB;EAAA,MAAA,IAAlBb,MAAM,GAAAa,KAAA,CAANb,MAAM;UAAEc,IAAI,GAAAD,KAAA,CAAJC,IAAI,CAAA;EAChD,MAAA,IAAId,MAAM,KAAK7F,OAAO,IAAI2G,IAAI,KAAKJ,KAAK,EAAE;UACxCC,SAAS,CAAC5I,MAAM,IAAI4I,SAAS,CAACI,KAAK,EAAE,EAAE,CAAA;EACzC,OAAA;OACD,EAAE,KAAK,CAAC,CAAA;MAET,OAAO,UAACC,EAAE,EAAK;EACbL,MAAAA,SAAS,CAACjD,IAAI,CAACsD,EAAE,CAAC,CAAA;EAClB7G,MAAAA,OAAO,CAAC8G,WAAW,CAACP,KAAK,EAAE,GAAG,CAAC,CAAA;OAChC,CAAA;EACH,GAAC,CAAAQ,QAAAA,CAAAA,MAAA,CAAWC,IAAI,CAACC,MAAM,EAAE,CAAI,EAAA,EAAE,CAAC,GAAG,UAACJ,EAAE,EAAA;MAAA,OAAKK,UAAU,CAACL,EAAE,CAAC,CAAA;EAAA,GAAA,CAAA;EAC3D,CAAC,CACC,OAAOP,YAAY,KAAK,UAAU,EAClCxJ,YAAU,CAACkD,OAAO,CAAC8G,WAAW,CAChC,CAAC,CAAA;EAED,IAAMK,IAAI,GAAG,OAAOC,cAAc,KAAK,WAAW,GAChDA,cAAc,CAACrM,IAAI,CAACiF,OAAO,CAAC,GAAK,OAAOqH,OAAO,KAAK,WAAW,IAAIA,OAAO,CAACC,QAAQ,IAAInB,aAAc,CAAA;;EAEvG;;EAGA,IAAMoB,UAAU,GAAG,SAAbA,UAAUA,CAAIzL,KAAK,EAAA;IAAA,OAAKA,KAAK,IAAI,IAAI,IAAIgB,YAAU,CAAChB,KAAK,CAACL,QAAQ,CAAC,CAAC,CAAA;EAAA,CAAA,CAAA;AAG1E,gBAAe;EACbe,EAAAA,OAAO,EAAPA,OAAO;EACPO,EAAAA,aAAa,EAAbA,aAAa;EACbJ,EAAAA,QAAQ,EAARA,QAAQ;EACRyB,EAAAA,UAAU,EAAVA,UAAU;EACVpB,EAAAA,iBAAiB,EAAjBA,iBAAiB;EACjBK,EAAAA,QAAQ,EAARA,QAAQ;EACRC,EAAAA,QAAQ,EAARA,QAAQ;EACRE,EAAAA,SAAS,EAATA,SAAS;EACTD,EAAAA,QAAQ,EAARA,QAAQ;EACRE,EAAAA,aAAa,EAAbA,aAAa;EACbC,EAAAA,aAAa,EAAbA,aAAa;EACbmB,EAAAA,gBAAgB,EAAhBA,gBAAgB;EAChBC,EAAAA,SAAS,EAATA,SAAS;EACTC,EAAAA,UAAU,EAAVA,UAAU;EACVC,EAAAA,SAAS,EAATA,SAAS;EACTtC,EAAAA,WAAW,EAAXA,WAAW;EACXoB,EAAAA,MAAM,EAANA,MAAM;EACNC,EAAAA,MAAM,EAANA,MAAM;EACNC,EAAAA,MAAM,EAANA,MAAM;EACNiG,EAAAA,QAAQ,EAARA,QAAQ;EACRnH,EAAAA,UAAU,EAAVA,YAAU;EACVoB,EAAAA,QAAQ,EAARA,QAAQ;EACRM,EAAAA,iBAAiB,EAAjBA,iBAAiB;EACjBkE,EAAAA,YAAY,EAAZA,YAAY;EACZzE,EAAAA,UAAU,EAAVA,UAAU;EACVkB,EAAAA,OAAO,EAAPA,OAAO;EACPoB,EAAAA,KAAK,EAALA,KAAK;EACLM,EAAAA,MAAM,EAANA,MAAM;EACN5B,EAAAA,IAAI,EAAJA,IAAI;EACJgC,EAAAA,QAAQ,EAARA,QAAQ;EACRG,EAAAA,QAAQ,EAARA,QAAQ;EACRO,EAAAA,YAAY,EAAZA,YAAY;EACZ/F,EAAAA,MAAM,EAANA,MAAM;EACNQ,EAAAA,UAAU,EAAVA,UAAU;EACV8F,EAAAA,QAAQ,EAARA,QAAQ;EACRM,EAAAA,OAAO,EAAPA,OAAO;EACPK,EAAAA,YAAY,EAAZA,YAAY;EACZM,EAAAA,QAAQ,EAARA,QAAQ;EACRK,EAAAA,UAAU,EAAVA,UAAU;EACVO,EAAAA,cAAc,EAAdA,cAAc;EACdyD,EAAAA,UAAU,EAAEzD,cAAc;EAAE;EAC5BG,EAAAA,iBAAiB,EAAjBA,iBAAiB;EACjBQ,EAAAA,aAAa,EAAbA,aAAa;EACbK,EAAAA,WAAW,EAAXA,WAAW;EACXtB,EAAAA,WAAW,EAAXA,WAAW;EACX2B,EAAAA,IAAI,EAAJA,IAAI;EACJC,EAAAA,cAAc,EAAdA,cAAc;EACdvF,EAAAA,OAAO,EAAPA,OAAO;EACPM,EAAAA,MAAM,EAAEJ,OAAO;EACfK,EAAAA,gBAAgB,EAAhBA,gBAAgB;EAChBoF,EAAAA,mBAAmB,EAAnBA,mBAAmB;EACnBC,EAAAA,YAAY,EAAZA,YAAY;EACZM,EAAAA,SAAS,EAATA,SAAS;EACTC,EAAAA,UAAU,EAAVA,UAAU;EACVK,EAAAA,YAAY,EAAEH,aAAa;EAC3BgB,EAAAA,IAAI,EAAJA,IAAI;EACJI,EAAAA,UAAU,EAAVA,UAAAA;EACF,CAAC;;ECzwBD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASE,UAAUA,CAACC,OAAO,EAAEC,IAAI,EAAEC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE;EAC5DhD,EAAAA,KAAK,CAAC9I,IAAI,CAAC,IAAI,CAAC,CAAA;IAEhB,IAAI8I,KAAK,CAACiD,iBAAiB,EAAE;MAC3BjD,KAAK,CAACiD,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAClL,WAAW,CAAC,CAAA;EACjD,GAAC,MAAM;MACL,IAAI,CAAC8I,KAAK,GAAI,IAAIb,KAAK,EAAE,CAAEa,KAAK,CAAA;EAClC,GAAA;IAEA,IAAI,CAAC+B,OAAO,GAAGA,OAAO,CAAA;IACtB,IAAI,CAACnD,IAAI,GAAG,YAAY,CAAA;EACxBoD,EAAAA,IAAI,KAAK,IAAI,CAACA,IAAI,GAAGA,IAAI,CAAC,CAAA;EAC1BC,EAAAA,MAAM,KAAK,IAAI,CAACA,MAAM,GAAGA,MAAM,CAAC,CAAA;EAChCC,EAAAA,OAAO,KAAK,IAAI,CAACA,OAAO,GAAGA,OAAO,CAAC,CAAA;EACnC,EAAA,IAAIC,QAAQ,EAAE;MACZ,IAAI,CAACA,QAAQ,GAAGA,QAAQ,CAAA;MACxB,IAAI,CAACE,MAAM,GAAGF,QAAQ,CAACE,MAAM,GAAGF,QAAQ,CAACE,MAAM,GAAG,IAAI,CAAA;EACxD,GAAA;EACF,CAAA;AAEAC,SAAK,CAAC7G,QAAQ,CAACqG,UAAU,EAAE3C,KAAK,EAAE;EAChCoD,EAAAA,MAAM,EAAE,SAASA,MAAMA,GAAG;MACxB,OAAO;EACL;QACAR,OAAO,EAAE,IAAI,CAACA,OAAO;QACrBnD,IAAI,EAAE,IAAI,CAACA,IAAI;EACf;QACA4D,WAAW,EAAE,IAAI,CAACA,WAAW;QAC7BC,MAAM,EAAE,IAAI,CAACA,MAAM;EACnB;QACAC,QAAQ,EAAE,IAAI,CAACA,QAAQ;QACvBC,UAAU,EAAE,IAAI,CAACA,UAAU;QAC3BC,YAAY,EAAE,IAAI,CAACA,YAAY;QAC/B5C,KAAK,EAAE,IAAI,CAACA,KAAK;EACjB;QACAiC,MAAM,EAAEK,OAAK,CAACvC,YAAY,CAAC,IAAI,CAACkC,MAAM,CAAC;QACvCD,IAAI,EAAE,IAAI,CAACA,IAAI;QACfK,MAAM,EAAE,IAAI,CAACA,MAAAA;OACd,CAAA;EACH,GAAA;EACF,CAAC,CAAC,CAAA;EAEF,IAAMzM,WAAS,GAAGkM,UAAU,CAAClM,SAAS,CAAA;EACtC,IAAMgG,WAAW,GAAG,EAAE,CAAA;EAEtB,CACE,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,aAAa,EACb,2BAA2B,EAC3B,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,iBAAA;EACF;EAAA,CACC,CAACpC,OAAO,CAAC,UAAAwI,IAAI,EAAI;IAChBpG,WAAW,CAACoG,IAAI,CAAC,GAAG;EAAClG,IAAAA,KAAK,EAAEkG,IAAAA;KAAK,CAAA;EACnC,CAAC,CAAC,CAAA;EAEFrM,MAAM,CAACmJ,gBAAgB,CAACgD,UAAU,EAAElG,WAAW,CAAC,CAAA;EAChDjG,MAAM,CAACkG,cAAc,CAACjG,WAAS,EAAE,cAAc,EAAE;EAACkG,EAAAA,KAAK,EAAE,IAAA;EAAI,CAAC,CAAC,CAAA;;EAE/D;EACAgG,UAAU,CAACe,IAAI,GAAG,UAACC,KAAK,EAAEd,IAAI,EAAEC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAEY,WAAW,EAAK;EACzE,EAAA,IAAMC,UAAU,GAAGrN,MAAM,CAACa,MAAM,CAACZ,WAAS,CAAC,CAAA;IAE3C0M,OAAK,CAACtG,YAAY,CAAC8G,KAAK,EAAEE,UAAU,EAAE,SAAS7G,MAAMA,CAAC1C,GAAG,EAAE;EACzD,IAAA,OAAOA,GAAG,KAAK0F,KAAK,CAACvJ,SAAS,CAAA;KAC/B,EAAE,UAAAyG,IAAI,EAAI;MACT,OAAOA,IAAI,KAAK,cAAc,CAAA;EAChC,GAAC,CAAC,CAAA;EAEF,EAAA,IAAM4G,GAAG,GAAGH,KAAK,IAAIA,KAAK,CAACf,OAAO,GAAGe,KAAK,CAACf,OAAO,GAAG,OAAO,CAAA;;EAE5D;EACA,EAAA,IAAMmB,OAAO,GAAGlB,IAAI,IAAI,IAAI,IAAIc,KAAK,GAAGA,KAAK,CAACd,IAAI,GAAGA,IAAI,CAAA;EACzDF,EAAAA,UAAU,CAACzL,IAAI,CAAC2M,UAAU,EAAEC,GAAG,EAAEC,OAAO,EAAEjB,MAAM,EAAEC,OAAO,EAAEC,QAAQ,CAAC,CAAA;;EAEpE;EACA,EAAA,IAAIW,KAAK,IAAIE,UAAU,CAACG,KAAK,IAAI,IAAI,EAAE;EACrCxN,IAAAA,MAAM,CAACkG,cAAc,CAACmH,UAAU,EAAE,OAAO,EAAE;EAAElH,MAAAA,KAAK,EAAEgH,KAAK;EAAEM,MAAAA,YAAY,EAAE,IAAA;EAAK,KAAC,CAAC,CAAA;EAClF,GAAA;IAEAJ,UAAU,CAACpE,IAAI,GAAIkE,KAAK,IAAIA,KAAK,CAAClE,IAAI,IAAK,OAAO,CAAA;IAElDmE,WAAW,IAAIpN,MAAM,CAACoG,MAAM,CAACiH,UAAU,EAAED,WAAW,CAAC,CAAA;EAErD,EAAA,OAAOC,UAAU,CAAA;EACnB,CAAC;;EC3GD;AACA,oBAAe,IAAI;;ECMnB;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASK,WAAWA,CAAClN,KAAK,EAAE;EAC1B,EAAA,OAAOmM,OAAK,CAACxK,aAAa,CAAC3B,KAAK,CAAC,IAAImM,OAAK,CAACzL,OAAO,CAACV,KAAK,CAAC,CAAA;EAC3D,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASmN,cAAcA,CAACpJ,GAAG,EAAE;EAC3B,EAAA,OAAOoI,OAAK,CAAC/F,QAAQ,CAACrC,GAAG,EAAE,IAAI,CAAC,GAAGA,GAAG,CAAC5D,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG4D,GAAG,CAAA;EAC3D,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASqJ,SAASA,CAACC,IAAI,EAAEtJ,GAAG,EAAEuJ,IAAI,EAAE;EAClC,EAAA,IAAI,CAACD,IAAI,EAAE,OAAOtJ,GAAG,CAAA;EACrB,EAAA,OAAOsJ,IAAI,CAACpC,MAAM,CAAClH,GAAG,CAAC,CAACnB,GAAG,CAAC,SAAS2K,IAAIA,CAAC9C,KAAK,EAAE9G,CAAC,EAAE;EAClD;EACA8G,IAAAA,KAAK,GAAG0C,cAAc,CAAC1C,KAAK,CAAC,CAAA;MAC7B,OAAO,CAAC6C,IAAI,IAAI3J,CAAC,GAAG,GAAG,GAAG8G,KAAK,GAAG,GAAG,GAAGA,KAAK,CAAA;KAC9C,CAAC,CAAC+C,IAAI,CAACF,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC,CAAA;EAC1B,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASG,WAAWA,CAAC9G,GAAG,EAAE;EACxB,EAAA,OAAOwF,OAAK,CAACzL,OAAO,CAACiG,GAAG,CAAC,IAAI,CAACA,GAAG,CAAC+G,IAAI,CAACR,WAAW,CAAC,CAAA;EACrD,CAAA;EAEA,IAAMS,UAAU,GAAGxB,OAAK,CAACtG,YAAY,CAACsG,OAAK,EAAE,EAAE,EAAE,IAAI,EAAE,SAASnG,MAAMA,CAACE,IAAI,EAAE;EAC3E,EAAA,OAAO,UAAU,CAAC0H,IAAI,CAAC1H,IAAI,CAAC,CAAA;EAC9B,CAAC,CAAC,CAAA;;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS2H,UAAUA,CAACvK,GAAG,EAAEwK,QAAQ,EAAEC,OAAO,EAAE;EAC1C,EAAA,IAAI,CAAC5B,OAAK,CAAC1K,QAAQ,CAAC6B,GAAG,CAAC,EAAE;EACxB,IAAA,MAAM,IAAI0K,SAAS,CAAC,0BAA0B,CAAC,CAAA;EACjD,GAAA;;EAEA;IACAF,QAAQ,GAAGA,QAAQ,IAAI,KAAyBtL,QAAQ,GAAG,CAAA;;EAE3D;EACAuL,EAAAA,OAAO,GAAG5B,OAAK,CAACtG,YAAY,CAACkI,OAAO,EAAE;EACpCE,IAAAA,UAAU,EAAE,IAAI;EAChBX,IAAAA,IAAI,EAAE,KAAK;EACXY,IAAAA,OAAO,EAAE,KAAA;KACV,EAAE,KAAK,EAAE,SAASC,OAAOA,CAACC,MAAM,EAAErE,MAAM,EAAE;EACzC;MACA,OAAO,CAACoC,OAAK,CAACvL,WAAW,CAACmJ,MAAM,CAACqE,MAAM,CAAC,CAAC,CAAA;EAC3C,GAAC,CAAC,CAAA;EAEF,EAAA,IAAMH,UAAU,GAAGF,OAAO,CAACE,UAAU,CAAA;EACrC;EACA,EAAA,IAAMI,OAAO,GAAGN,OAAO,CAACM,OAAO,IAAIC,cAAc,CAAA;EACjD,EAAA,IAAMhB,IAAI,GAAGS,OAAO,CAACT,IAAI,CAAA;EACzB,EAAA,IAAMY,OAAO,GAAGH,OAAO,CAACG,OAAO,CAAA;IAC/B,IAAMK,KAAK,GAAGR,OAAO,CAACS,IAAI,IAAI,OAAOA,IAAI,KAAK,WAAW,IAAIA,IAAI,CAAA;IACjE,IAAMC,OAAO,GAAGF,KAAK,IAAIpC,OAAK,CAACxC,mBAAmB,CAACmE,QAAQ,CAAC,CAAA;EAE5D,EAAA,IAAI,CAAC3B,OAAK,CAACnL,UAAU,CAACqN,OAAO,CAAC,EAAE;EAC9B,IAAA,MAAM,IAAIL,SAAS,CAAC,4BAA4B,CAAC,CAAA;EACnD,GAAA;IAEA,SAASU,YAAYA,CAAC/I,KAAK,EAAE;EAC3B,IAAA,IAAIA,KAAK,KAAK,IAAI,EAAE,OAAO,EAAE,CAAA;EAE7B,IAAA,IAAIwG,OAAK,CAACnK,MAAM,CAAC2D,KAAK,CAAC,EAAE;EACvB,MAAA,OAAOA,KAAK,CAACgJ,WAAW,EAAE,CAAA;EAC5B,KAAA;EAEA,IAAA,IAAIxC,OAAK,CAACzK,SAAS,CAACiE,KAAK,CAAC,EAAE;EAC1B,MAAA,OAAOA,KAAK,CAACpG,QAAQ,EAAE,CAAA;EACzB,KAAA;MAEA,IAAI,CAACkP,OAAO,IAAItC,OAAK,CAACjK,MAAM,CAACyD,KAAK,CAAC,EAAE;EACnC,MAAA,MAAM,IAAIgG,UAAU,CAAC,8CAA8C,CAAC,CAAA;EACtE,KAAA;EAEA,IAAA,IAAIQ,OAAK,CAAClL,aAAa,CAAC0E,KAAK,CAAC,IAAIwG,OAAK,CAACvF,YAAY,CAACjB,KAAK,CAAC,EAAE;QAC3D,OAAO8I,OAAO,IAAI,OAAOD,IAAI,KAAK,UAAU,GAAG,IAAIA,IAAI,CAAC,CAAC7I,KAAK,CAAC,CAAC,GAAGiJ,MAAM,CAAClC,IAAI,CAAC/G,KAAK,CAAC,CAAA;EACvF,KAAA;EAEA,IAAA,OAAOA,KAAK,CAAA;EACd,GAAA;;EAEA;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACE,EAAA,SAAS2I,cAAcA,CAAC3I,KAAK,EAAE5B,GAAG,EAAEsJ,IAAI,EAAE;MACxC,IAAI1G,GAAG,GAAGhB,KAAK,CAAA;MAEf,IAAIA,KAAK,IAAI,CAAC0H,IAAI,IAAI5M,OAAA,CAAOkF,KAAK,CAAK,KAAA,QAAQ,EAAE;QAC/C,IAAIwG,OAAK,CAAC/F,QAAQ,CAACrC,GAAG,EAAE,IAAI,CAAC,EAAE;EAC7B;EACAA,QAAAA,GAAG,GAAGkK,UAAU,GAAGlK,GAAG,GAAGA,GAAG,CAAC5D,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;EACzC;EACAwF,QAAAA,KAAK,GAAGkJ,IAAI,CAACC,SAAS,CAACnJ,KAAK,CAAC,CAAA;EAC/B,OAAC,MAAM,IACJwG,OAAK,CAACzL,OAAO,CAACiF,KAAK,CAAC,IAAI8H,WAAW,CAAC9H,KAAK,CAAC,IAC1C,CAACwG,OAAK,CAAChK,UAAU,CAACwD,KAAK,CAAC,IAAIwG,OAAK,CAAC/F,QAAQ,CAACrC,GAAG,EAAE,IAAI,CAAC,MAAM4C,GAAG,GAAGwF,OAAK,CAACzF,OAAO,CAACf,KAAK,CAAC,CACrF,EAAE;EACH;EACA5B,QAAAA,GAAG,GAAGoJ,cAAc,CAACpJ,GAAG,CAAC,CAAA;UAEzB4C,GAAG,CAACtD,OAAO,CAAC,SAASkK,IAAIA,CAACwB,EAAE,EAAEC,KAAK,EAAE;EACnC,UAAA,EAAE7C,OAAK,CAACvL,WAAW,CAACmO,EAAE,CAAC,IAAIA,EAAE,KAAK,IAAI,CAAC,IAAIjB,QAAQ,CAACrL,MAAM;EACxD;EACAyL,UAAAA,OAAO,KAAK,IAAI,GAAGd,SAAS,CAAC,CAACrJ,GAAG,CAAC,EAAEiL,KAAK,EAAE1B,IAAI,CAAC,GAAIY,OAAO,KAAK,IAAI,GAAGnK,GAAG,GAAGA,GAAG,GAAG,IAAK,EACxF2K,YAAY,CAACK,EAAE,CACjB,CAAC,CAAA;EACH,SAAC,CAAC,CAAA;EACF,QAAA,OAAO,KAAK,CAAA;EACd,OAAA;EACF,KAAA;EAEA,IAAA,IAAI7B,WAAW,CAACvH,KAAK,CAAC,EAAE;EACtB,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;EAEAmI,IAAAA,QAAQ,CAACrL,MAAM,CAAC2K,SAAS,CAACC,IAAI,EAAEtJ,GAAG,EAAEuJ,IAAI,CAAC,EAAEoB,YAAY,CAAC/I,KAAK,CAAC,CAAC,CAAA;EAEhE,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;IAEA,IAAMkE,KAAK,GAAG,EAAE,CAAA;EAEhB,EAAA,IAAMoF,cAAc,GAAGzP,MAAM,CAACoG,MAAM,CAAC+H,UAAU,EAAE;EAC/CW,IAAAA,cAAc,EAAdA,cAAc;EACdI,IAAAA,YAAY,EAAZA,YAAY;EACZxB,IAAAA,WAAW,EAAXA,WAAAA;EACF,GAAC,CAAC,CAAA;EAEF,EAAA,SAASgC,KAAKA,CAACvJ,KAAK,EAAE0H,IAAI,EAAE;EAC1B,IAAA,IAAIlB,OAAK,CAACvL,WAAW,CAAC+E,KAAK,CAAC,EAAE,OAAA;MAE9B,IAAIkE,KAAK,CAACpD,OAAO,CAACd,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE;QAC/B,MAAMqD,KAAK,CAAC,iCAAiC,GAAGqE,IAAI,CAACG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;EACjE,KAAA;EAEA3D,IAAAA,KAAK,CAACpC,IAAI,CAAC9B,KAAK,CAAC,CAAA;MAEjBwG,OAAK,CAAC9I,OAAO,CAACsC,KAAK,EAAE,SAAS4H,IAAIA,CAACwB,EAAE,EAAEhL,GAAG,EAAE;EAC1C,MAAA,IAAM5C,MAAM,GAAG,EAAEgL,OAAK,CAACvL,WAAW,CAACmO,EAAE,CAAC,IAAIA,EAAE,KAAK,IAAI,CAAC,IAAIV,OAAO,CAACnO,IAAI,CACpE4N,QAAQ,EAAEiB,EAAE,EAAE5C,OAAK,CAAC5K,QAAQ,CAACwC,GAAG,CAAC,GAAGA,GAAG,CAACZ,IAAI,EAAE,GAAGY,GAAG,EAAEsJ,IAAI,EAAE4B,cAC9D,CAAC,CAAA;QAED,IAAI9N,MAAM,KAAK,IAAI,EAAE;EACnB+N,QAAAA,KAAK,CAACH,EAAE,EAAE1B,IAAI,GAAGA,IAAI,CAACpC,MAAM,CAAClH,GAAG,CAAC,GAAG,CAACA,GAAG,CAAC,CAAC,CAAA;EAC5C,OAAA;EACF,KAAC,CAAC,CAAA;MAEF8F,KAAK,CAACsF,GAAG,EAAE,CAAA;EACb,GAAA;EAEA,EAAA,IAAI,CAAChD,OAAK,CAAC1K,QAAQ,CAAC6B,GAAG,CAAC,EAAE;EACxB,IAAA,MAAM,IAAI0K,SAAS,CAAC,wBAAwB,CAAC,CAAA;EAC/C,GAAA;IAEAkB,KAAK,CAAC5L,GAAG,CAAC,CAAA;EAEV,EAAA,OAAOwK,QAAQ,CAAA;EACjB;;ECxNA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASsB,QAAMA,CAACnP,GAAG,EAAE;EACnB,EAAA,IAAMoP,OAAO,GAAG;EACd,IAAA,GAAG,EAAE,KAAK;EACV,IAAA,GAAG,EAAE,KAAK;EACV,IAAA,GAAG,EAAE,KAAK;EACV,IAAA,GAAG,EAAE,KAAK;EACV,IAAA,GAAG,EAAE,KAAK;EACV,IAAA,KAAK,EAAE,GAAG;EACV,IAAA,KAAK,EAAE,MAAA;KACR,CAAA;EACD,EAAA,OAAOC,kBAAkB,CAACrP,GAAG,CAAC,CAACmD,OAAO,CAAC,kBAAkB,EAAE,SAASwE,QAAQA,CAAC2H,KAAK,EAAE;MAClF,OAAOF,OAAO,CAACE,KAAK,CAAC,CAAA;EACvB,GAAC,CAAC,CAAA;EACJ,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASC,oBAAoBA,CAACC,MAAM,EAAE1B,OAAO,EAAE;IAC7C,IAAI,CAAC2B,MAAM,GAAG,EAAE,CAAA;IAEhBD,MAAM,IAAI5B,UAAU,CAAC4B,MAAM,EAAE,IAAI,EAAE1B,OAAO,CAAC,CAAA;EAC7C,CAAA;EAEA,IAAMtO,SAAS,GAAG+P,oBAAoB,CAAC/P,SAAS,CAAA;EAEhDA,SAAS,CAACgD,MAAM,GAAG,SAASA,MAAMA,CAACgG,IAAI,EAAE9C,KAAK,EAAE;IAC9C,IAAI,CAAC+J,MAAM,CAACjI,IAAI,CAAC,CAACgB,IAAI,EAAE9C,KAAK,CAAC,CAAC,CAAA;EACjC,CAAC,CAAA;EAEDlG,SAAS,CAACF,QAAQ,GAAG,SAASA,QAAQA,CAACoQ,OAAO,EAAE;EAC9C,EAAA,IAAMC,OAAO,GAAGD,OAAO,GAAG,UAAShK,KAAK,EAAE;MACxC,OAAOgK,OAAO,CAACzP,IAAI,CAAC,IAAI,EAAEyF,KAAK,EAAEyJ,QAAM,CAAC,CAAA;EAC1C,GAAC,GAAGA,QAAM,CAAA;IAEV,OAAO,IAAI,CAACM,MAAM,CAAC9M,GAAG,CAAC,SAAS2K,IAAIA,CAACnG,IAAI,EAAE;EACzC,IAAA,OAAOwI,OAAO,CAACxI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAGwI,OAAO,CAACxI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;EAClD,GAAC,EAAE,EAAE,CAAC,CAACoG,IAAI,CAAC,GAAG,CAAC,CAAA;EAClB,CAAC;;EClDD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS4B,MAAMA,CAACtO,GAAG,EAAE;EACnB,EAAA,OAAOwO,kBAAkB,CAACxO,GAAG,CAAC,CAC5BsC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CACrBA,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CACpBA,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CACrBA,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;EACxB,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASyM,QAAQA,CAACC,GAAG,EAAEL,MAAM,EAAE1B,OAAO,EAAE;EACrD;IACA,IAAI,CAAC0B,MAAM,EAAE;EACX,IAAA,OAAOK,GAAG,CAAA;EACZ,GAAA;IAEA,IAAMF,OAAO,GAAG7B,OAAO,IAAIA,OAAO,CAACqB,MAAM,IAAIA,MAAM,CAAA;EAEnD,EAAA,IAAIjD,OAAK,CAACnL,UAAU,CAAC+M,OAAO,CAAC,EAAE;EAC7BA,IAAAA,OAAO,GAAG;EACRgC,MAAAA,SAAS,EAAEhC,OAAAA;OACZ,CAAA;EACH,GAAA;EAEA,EAAA,IAAMiC,WAAW,GAAGjC,OAAO,IAAIA,OAAO,CAACgC,SAAS,CAAA;EAEhD,EAAA,IAAIE,gBAAgB,CAAA;EAEpB,EAAA,IAAID,WAAW,EAAE;EACfC,IAAAA,gBAAgB,GAAGD,WAAW,CAACP,MAAM,EAAE1B,OAAO,CAAC,CAAA;EACjD,GAAC,MAAM;MACLkC,gBAAgB,GAAG9D,OAAK,CAACzJ,iBAAiB,CAAC+M,MAAM,CAAC,GAChDA,MAAM,CAAClQ,QAAQ,EAAE,GACjB,IAAIiQ,oBAAoB,CAACC,MAAM,EAAE1B,OAAO,CAAC,CAACxO,QAAQ,CAACqQ,OAAO,CAAC,CAAA;EAC/D,GAAA;EAEA,EAAA,IAAIK,gBAAgB,EAAE;EACpB,IAAA,IAAMC,aAAa,GAAGJ,GAAG,CAACrJ,OAAO,CAAC,GAAG,CAAC,CAAA;EAEtC,IAAA,IAAIyJ,aAAa,KAAK,CAAC,CAAC,EAAE;QACxBJ,GAAG,GAAGA,GAAG,CAAC3P,KAAK,CAAC,CAAC,EAAE+P,aAAa,CAAC,CAAA;EACnC,KAAA;EACAJ,IAAAA,GAAG,IAAI,CAACA,GAAG,CAACrJ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,IAAIwJ,gBAAgB,CAAA;EACjE,GAAA;EAEA,EAAA,OAAOH,GAAG,CAAA;EACZ;;EChEkC,IAE5BK,kBAAkB,gBAAA,YAAA;EACtB,EAAA,SAAAA,qBAAc;EAAAC,IAAAA,eAAA,OAAAD,kBAAA,CAAA,CAAA;MACZ,IAAI,CAACE,QAAQ,GAAG,EAAE,CAAA;EACpB,GAAA;;EAEA;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EAPEC,EAAAA,YAAA,CAAAH,kBAAA,EAAA,CAAA;MAAApM,GAAA,EAAA,KAAA;MAAA4B,KAAA,EAQA,SAAA4K,GAAIC,CAAAA,SAAS,EAAEC,QAAQ,EAAE1C,OAAO,EAAE;EAChC,MAAA,IAAI,CAACsC,QAAQ,CAAC5I,IAAI,CAAC;EACjB+I,QAAAA,SAAS,EAATA,SAAS;EACTC,QAAAA,QAAQ,EAARA,QAAQ;EACRC,QAAAA,WAAW,EAAE3C,OAAO,GAAGA,OAAO,CAAC2C,WAAW,GAAG,KAAK;EAClDC,QAAAA,OAAO,EAAE5C,OAAO,GAAGA,OAAO,CAAC4C,OAAO,GAAG,IAAA;EACvC,OAAC,CAAC,CAAA;EACF,MAAA,OAAO,IAAI,CAACN,QAAQ,CAACvO,MAAM,GAAG,CAAC,CAAA;EACjC,KAAA;;EAEA;EACF;EACA;EACA;EACA;EACA;EACA;EANE,GAAA,EAAA;MAAAiC,GAAA,EAAA,OAAA;EAAA4B,IAAAA,KAAA,EAOA,SAAAiL,KAAMC,CAAAA,EAAE,EAAE;EACR,MAAA,IAAI,IAAI,CAACR,QAAQ,CAACQ,EAAE,CAAC,EAAE;EACrB,QAAA,IAAI,CAACR,QAAQ,CAACQ,EAAE,CAAC,GAAG,IAAI,CAAA;EAC1B,OAAA;EACF,KAAA;;EAEA;EACF;EACA;EACA;EACA;EAJE,GAAA,EAAA;MAAA9M,GAAA,EAAA,OAAA;MAAA4B,KAAA,EAKA,SAAAmL,KAAAA,GAAQ;QACN,IAAI,IAAI,CAACT,QAAQ,EAAE;UACjB,IAAI,CAACA,QAAQ,GAAG,EAAE,CAAA;EACpB,OAAA;EACF,KAAA;;EAEA;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EATE,GAAA,EAAA;MAAAtM,GAAA,EAAA,SAAA;EAAA4B,IAAAA,KAAA,EAUA,SAAAtC,OAAQnE,CAAAA,EAAE,EAAE;QACViN,OAAK,CAAC9I,OAAO,CAAC,IAAI,CAACgN,QAAQ,EAAE,SAASU,cAAcA,CAACC,CAAC,EAAE;UACtD,IAAIA,CAAC,KAAK,IAAI,EAAE;YACd9R,EAAE,CAAC8R,CAAC,CAAC,CAAA;EACP,SAAA;EACF,OAAC,CAAC,CAAA;EACJ,KAAA;EAAC,GAAA,CAAA,CAAA,CAAA;EAAA,EAAA,OAAAb,kBAAA,CAAA;EAAA,CAAA,EAAA,CAAA;AAGH,6BAAeA,kBAAkB;;ACpEjC,6BAAe;EACbc,EAAAA,iBAAiB,EAAE,IAAI;EACvBC,EAAAA,iBAAiB,EAAE,IAAI;EACvBC,EAAAA,mBAAmB,EAAE,KAAA;EACvB,CAAC;;ACHD,0BAAe,OAAOC,eAAe,KAAK,WAAW,GAAGA,eAAe,GAAG5B,oBAAoB;;ACD9F,mBAAe,OAAOhN,QAAQ,KAAK,WAAW,GAAGA,QAAQ,GAAG,IAAI;;ACAhE,eAAe,OAAOgM,IAAI,KAAK,WAAW,GAAGA,IAAI,GAAG,IAAI;;ACExD,mBAAe;EACb6C,EAAAA,SAAS,EAAE,IAAI;EACfC,EAAAA,OAAO,EAAE;EACPF,IAAAA,eAAe,EAAfA,iBAAe;EACf5O,IAAAA,QAAQ,EAARA,UAAQ;EACRgM,IAAAA,IAAI,EAAJA,MAAAA;KACD;EACD+C,EAAAA,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAA;EAC5D,CAAC;;ECZD,IAAMC,aAAa,GAAG,OAAOnN,MAAM,KAAK,WAAW,IAAI,OAAOoN,QAAQ,KAAK,WAAW,CAAA;EAEtF,IAAMC,UAAU,GAAG,CAAOC,OAAAA,SAAS,KAAAlR,WAAAA,GAAAA,WAAAA,GAAAA,OAAA,CAATkR,SAAS,CAAK,MAAA,QAAQ,IAAIA,SAAS,IAAInO,SAAS,CAAA;;EAE1E;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMoO,qBAAqB,GAAGJ,aAAa,KACxC,CAACE,UAAU,IAAI,CAAC,aAAa,EAAE,cAAc,EAAE,IAAI,CAAC,CAACjL,OAAO,CAACiL,UAAU,CAACG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAA;;EAExF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,IAAMC,8BAA8B,GAAI,YAAM;IAC5C,OACE,OAAOC,iBAAiB,KAAK,WAAW;EACxC;IACA3N,IAAI,YAAY2N,iBAAiB,IACjC,OAAO3N,IAAI,CAAC4N,aAAa,KAAK,UAAU,CAAA;EAE5C,CAAC,EAAG,CAAA;EAEJ,IAAMC,MAAM,GAAGT,aAAa,IAAInN,MAAM,CAAC6N,QAAQ,CAACC,IAAI,IAAI,kBAAkB;;;;;;;;;;;ACvC1E,iBAAAC,cAAA,CAAAA,cAAA,CACKjG,EAAAA,EAAAA,KAAK,GACLkG,UAAQ,CAAA;;ECCE,SAASC,gBAAgBA,CAACzH,IAAI,EAAEkD,OAAO,EAAE;EACtD,EAAA,OAAOF,UAAU,CAAChD,IAAI,EAAE,IAAIwH,QAAQ,CAACf,OAAO,CAACF,eAAe,EAAE,EAAAgB,cAAA,CAAA;MAC5D/D,OAAO,EAAE,SAAAA,OAAAA,CAAS1I,KAAK,EAAE5B,GAAG,EAAEsJ,IAAI,EAAEkF,OAAO,EAAE;QAC3C,IAAIF,QAAQ,CAACG,MAAM,IAAIrG,OAAK,CAACtL,QAAQ,CAAC8E,KAAK,CAAC,EAAE;UAC5C,IAAI,CAAClD,MAAM,CAACsB,GAAG,EAAE4B,KAAK,CAACpG,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAA;EAC1C,QAAA,OAAO,KAAK,CAAA;EACd,OAAA;QAEA,OAAOgT,OAAO,CAACjE,cAAc,CAACjP,KAAK,CAAC,IAAI,EAAEC,SAAS,CAAC,CAAA;EACtD,KAAA;KACGyO,EAAAA,OAAO,CACX,CAAC,CAAA;EACJ;;ECdA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS0E,aAAaA,CAAChK,IAAI,EAAE;EAC3B;EACA;EACA;EACA;EACA,EAAA,OAAO0D,OAAK,CAAC9E,QAAQ,CAAC,eAAe,EAAEoB,IAAI,CAAC,CAAC7F,GAAG,CAAC,UAAA2M,KAAK,EAAI;EACxD,IAAA,OAAOA,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,EAAE,GAAGA,KAAK,CAAC,CAAC,CAAC,IAAIA,KAAK,CAAC,CAAC,CAAC,CAAA;EACtD,GAAC,CAAC,CAAA;EACJ,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASmD,aAAaA,CAAC/L,GAAG,EAAE;IAC1B,IAAMrD,GAAG,GAAG,EAAE,CAAA;EACd,EAAA,IAAMzB,IAAI,GAAGrC,MAAM,CAACqC,IAAI,CAAC8E,GAAG,CAAC,CAAA;EAC7B,EAAA,IAAIhD,CAAC,CAAA;EACL,EAAA,IAAMG,GAAG,GAAGjC,IAAI,CAACC,MAAM,CAAA;EACvB,EAAA,IAAIiC,GAAG,CAAA;IACP,KAAKJ,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGG,GAAG,EAAEH,CAAC,EAAE,EAAE;EACxBI,IAAAA,GAAG,GAAGlC,IAAI,CAAC8B,CAAC,CAAC,CAAA;EACbL,IAAAA,GAAG,CAACS,GAAG,CAAC,GAAG4C,GAAG,CAAC5C,GAAG,CAAC,CAAA;EACrB,GAAA;EACA,EAAA,OAAOT,GAAG,CAAA;EACZ,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASqP,cAAcA,CAAC7E,QAAQ,EAAE;IAChC,SAAS8E,SAASA,CAACvF,IAAI,EAAE1H,KAAK,EAAEqE,MAAM,EAAEgF,KAAK,EAAE;EAC7C,IAAA,IAAIvG,IAAI,GAAG4E,IAAI,CAAC2B,KAAK,EAAE,CAAC,CAAA;EAExB,IAAA,IAAIvG,IAAI,KAAK,WAAW,EAAE,OAAO,IAAI,CAAA;MAErC,IAAMoK,YAAY,GAAGpJ,MAAM,CAACC,QAAQ,CAAC,CAACjB,IAAI,CAAC,CAAA;EAC3C,IAAA,IAAMqK,MAAM,GAAG9D,KAAK,IAAI3B,IAAI,CAACvL,MAAM,CAAA;EACnC2G,IAAAA,IAAI,GAAG,CAACA,IAAI,IAAI0D,OAAK,CAACzL,OAAO,CAACsJ,MAAM,CAAC,GAAGA,MAAM,CAAClI,MAAM,GAAG2G,IAAI,CAAA;EAE5D,IAAA,IAAIqK,MAAM,EAAE;QACV,IAAI3G,OAAK,CAACT,UAAU,CAAC1B,MAAM,EAAEvB,IAAI,CAAC,EAAE;UAClCuB,MAAM,CAACvB,IAAI,CAAC,GAAG,CAACuB,MAAM,CAACvB,IAAI,CAAC,EAAE9C,KAAK,CAAC,CAAA;EACtC,OAAC,MAAM;EACLqE,QAAAA,MAAM,CAACvB,IAAI,CAAC,GAAG9C,KAAK,CAAA;EACtB,OAAA;EAEA,MAAA,OAAO,CAACkN,YAAY,CAAA;EACtB,KAAA;EAEA,IAAA,IAAI,CAAC7I,MAAM,CAACvB,IAAI,CAAC,IAAI,CAAC0D,OAAK,CAAC1K,QAAQ,CAACuI,MAAM,CAACvB,IAAI,CAAC,CAAC,EAAE;EAClDuB,MAAAA,MAAM,CAACvB,IAAI,CAAC,GAAG,EAAE,CAAA;EACnB,KAAA;EAEA,IAAA,IAAMtH,MAAM,GAAGyR,SAAS,CAACvF,IAAI,EAAE1H,KAAK,EAAEqE,MAAM,CAACvB,IAAI,CAAC,EAAEuG,KAAK,CAAC,CAAA;MAE1D,IAAI7N,MAAM,IAAIgL,OAAK,CAACzL,OAAO,CAACsJ,MAAM,CAACvB,IAAI,CAAC,CAAC,EAAE;QACzCuB,MAAM,CAACvB,IAAI,CAAC,GAAGiK,aAAa,CAAC1I,MAAM,CAACvB,IAAI,CAAC,CAAC,CAAA;EAC5C,KAAA;EAEA,IAAA,OAAO,CAACoK,YAAY,CAAA;EACtB,GAAA;EAEA,EAAA,IAAI1G,OAAK,CAAC7J,UAAU,CAACwL,QAAQ,CAAC,IAAI3B,OAAK,CAACnL,UAAU,CAAC8M,QAAQ,CAACiF,OAAO,CAAC,EAAE;MACpE,IAAMzP,GAAG,GAAG,EAAE,CAAA;MAEd6I,OAAK,CAACpF,YAAY,CAAC+G,QAAQ,EAAE,UAACrF,IAAI,EAAE9C,KAAK,EAAK;QAC5CiN,SAAS,CAACH,aAAa,CAAChK,IAAI,CAAC,EAAE9C,KAAK,EAAErC,GAAG,EAAE,CAAC,CAAC,CAAA;EAC/C,KAAC,CAAC,CAAA;EAEF,IAAA,OAAOA,GAAG,CAAA;EACZ,GAAA;EAEA,EAAA,OAAO,IAAI,CAAA;EACb;;EClFA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS0P,eAAeA,CAACC,QAAQ,EAAEC,MAAM,EAAEvD,OAAO,EAAE;EAClD,EAAA,IAAIxD,OAAK,CAAC5K,QAAQ,CAAC0R,QAAQ,CAAC,EAAE;MAC5B,IAAI;EACF,MAAA,CAACC,MAAM,IAAIrE,IAAI,CAACsE,KAAK,EAAEF,QAAQ,CAAC,CAAA;EAChC,MAAA,OAAO9G,OAAK,CAAChJ,IAAI,CAAC8P,QAAQ,CAAC,CAAA;OAC5B,CAAC,OAAOlR,CAAC,EAAE;EACV,MAAA,IAAIA,CAAC,CAAC0G,IAAI,KAAK,aAAa,EAAE;EAC5B,QAAA,MAAM1G,CAAC,CAAA;EACT,OAAA;EACF,KAAA;EACF,GAAA;IAEA,OAAO,CAAC4N,OAAO,IAAId,IAAI,CAACC,SAAS,EAAEmE,QAAQ,CAAC,CAAA;EAC9C,CAAA;EAEA,IAAMG,QAAQ,GAAG;EAEfC,EAAAA,YAAY,EAAEC,oBAAoB;EAElCC,EAAAA,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC;IAEjCC,gBAAgB,EAAE,CAAC,SAASA,gBAAgBA,CAAC3I,IAAI,EAAE4I,OAAO,EAAE;MAC1D,IAAMC,WAAW,GAAGD,OAAO,CAACE,cAAc,EAAE,IAAI,EAAE,CAAA;MAClD,IAAMC,kBAAkB,GAAGF,WAAW,CAACjN,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;EACvE,IAAA,IAAMoN,eAAe,GAAG1H,OAAK,CAAC1K,QAAQ,CAACoJ,IAAI,CAAC,CAAA;MAE5C,IAAIgJ,eAAe,IAAI1H,OAAK,CAACzE,UAAU,CAACmD,IAAI,CAAC,EAAE;EAC7CA,MAAAA,IAAI,GAAG,IAAIrI,QAAQ,CAACqI,IAAI,CAAC,CAAA;EAC3B,KAAA;EAEA,IAAA,IAAMvI,UAAU,GAAG6J,OAAK,CAAC7J,UAAU,CAACuI,IAAI,CAAC,CAAA;EAEzC,IAAA,IAAIvI,UAAU,EAAE;EACd,MAAA,OAAOsR,kBAAkB,GAAG/E,IAAI,CAACC,SAAS,CAAC6D,cAAc,CAAC9H,IAAI,CAAC,CAAC,GAAGA,IAAI,CAAA;EACzE,KAAA;EAEA,IAAA,IAAIsB,OAAK,CAAClL,aAAa,CAAC4J,IAAI,CAAC,IAC3BsB,OAAK,CAACtL,QAAQ,CAACgK,IAAI,CAAC,IACpBsB,OAAK,CAAC/J,QAAQ,CAACyI,IAAI,CAAC,IACpBsB,OAAK,CAAClK,MAAM,CAAC4I,IAAI,CAAC,IAClBsB,OAAK,CAACjK,MAAM,CAAC2I,IAAI,CAAC,IAClBsB,OAAK,CAACpJ,gBAAgB,CAAC8H,IAAI,CAAC,EAC5B;EACA,MAAA,OAAOA,IAAI,CAAA;EACb,KAAA;EACA,IAAA,IAAIsB,OAAK,CAACjL,iBAAiB,CAAC2J,IAAI,CAAC,EAAE;QACjC,OAAOA,IAAI,CAACvJ,MAAM,CAAA;EACpB,KAAA;EACA,IAAA,IAAI6K,OAAK,CAACzJ,iBAAiB,CAACmI,IAAI,CAAC,EAAE;EACjC4I,MAAAA,OAAO,CAACK,cAAc,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAA;EAChF,MAAA,OAAOjJ,IAAI,CAACtL,QAAQ,EAAE,CAAA;EACxB,KAAA;EAEA,IAAA,IAAI4C,UAAU,CAAA;EAEd,IAAA,IAAI0R,eAAe,EAAE;QACnB,IAAIH,WAAW,CAACjN,OAAO,CAAC,mCAAmC,CAAC,GAAG,CAAC,CAAC,EAAE;UACjE,OAAO6L,gBAAgB,CAACzH,IAAI,EAAE,IAAI,CAACkJ,cAAc,CAAC,CAACxU,QAAQ,EAAE,CAAA;EAC/D,OAAA;EAEA,MAAA,IAAI,CAAC4C,UAAU,GAAGgK,OAAK,CAAChK,UAAU,CAAC0I,IAAI,CAAC,KAAK6I,WAAW,CAACjN,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,EAAE;UAC5F,IAAMuN,SAAS,GAAG,IAAI,CAACC,GAAG,IAAI,IAAI,CAACA,GAAG,CAACzR,QAAQ,CAAA;UAE/C,OAAOqL,UAAU,CACf1L,UAAU,GAAG;EAAC,UAAA,SAAS,EAAE0I,IAAAA;EAAI,SAAC,GAAGA,IAAI,EACrCmJ,SAAS,IAAI,IAAIA,SAAS,EAAE,EAC5B,IAAI,CAACD,cACP,CAAC,CAAA;EACH,OAAA;EACF,KAAA;MAEA,IAAIF,eAAe,IAAID,kBAAkB,EAAG;EAC1CH,MAAAA,OAAO,CAACK,cAAc,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAA;QACjD,OAAOd,eAAe,CAACnI,IAAI,CAAC,CAAA;EAC9B,KAAA;EAEA,IAAA,OAAOA,IAAI,CAAA;EACb,GAAC,CAAC;EAEFqJ,EAAAA,iBAAiB,EAAE,CAAC,SAASA,iBAAiBA,CAACrJ,IAAI,EAAE;MACnD,IAAMwI,YAAY,GAAG,IAAI,CAACA,YAAY,IAAID,QAAQ,CAACC,YAAY,CAAA;EAC/D,IAAA,IAAMnC,iBAAiB,GAAGmC,YAAY,IAAIA,YAAY,CAACnC,iBAAiB,CAAA;EACxE,IAAA,IAAMiD,aAAa,GAAG,IAAI,CAACC,YAAY,KAAK,MAAM,CAAA;EAElD,IAAA,IAAIjI,OAAK,CAAClJ,UAAU,CAAC4H,IAAI,CAAC,IAAIsB,OAAK,CAACpJ,gBAAgB,CAAC8H,IAAI,CAAC,EAAE;EAC1D,MAAA,OAAOA,IAAI,CAAA;EACb,KAAA;EAEA,IAAA,IAAIA,IAAI,IAAIsB,OAAK,CAAC5K,QAAQ,CAACsJ,IAAI,CAAC,KAAMqG,iBAAiB,IAAI,CAAC,IAAI,CAACkD,YAAY,IAAKD,aAAa,CAAC,EAAE;EAChG,MAAA,IAAMlD,iBAAiB,GAAGoC,YAAY,IAAIA,YAAY,CAACpC,iBAAiB,CAAA;EACxE,MAAA,IAAMoD,iBAAiB,GAAG,CAACpD,iBAAiB,IAAIkD,aAAa,CAAA;QAE7D,IAAI;UACF,OAAOtF,IAAI,CAACsE,KAAK,CAACtI,IAAI,EAAE,IAAI,CAACyJ,YAAY,CAAC,CAAA;SAC3C,CAAC,OAAOvS,CAAC,EAAE;EACV,QAAA,IAAIsS,iBAAiB,EAAE;EACrB,UAAA,IAAItS,CAAC,CAAC0G,IAAI,KAAK,aAAa,EAAE;EAC5B,YAAA,MAAMkD,UAAU,CAACe,IAAI,CAAC3K,CAAC,EAAE4J,UAAU,CAAC4I,gBAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAACvI,QAAQ,CAAC,CAAA;EAClF,WAAA;EACA,UAAA,MAAMjK,CAAC,CAAA;EACT,SAAA;EACF,OAAA;EACF,KAAA;EAEA,IAAA,OAAO8I,IAAI,CAAA;EACb,GAAC,CAAC;EAEF;EACF;EACA;EACA;EACE2J,EAAAA,OAAO,EAAE,CAAC;EAEVC,EAAAA,cAAc,EAAE,YAAY;EAC5BC,EAAAA,cAAc,EAAE,cAAc;IAE9BC,gBAAgB,EAAE,CAAC,CAAC;IACpBC,aAAa,EAAE,CAAC,CAAC;EAEjBX,EAAAA,GAAG,EAAE;EACHzR,IAAAA,QAAQ,EAAE6P,QAAQ,CAACf,OAAO,CAAC9O,QAAQ;EACnCgM,IAAAA,IAAI,EAAE6D,QAAQ,CAACf,OAAO,CAAC9C,IAAAA;KACxB;EAEDqG,EAAAA,cAAc,EAAE,SAASA,cAAcA,CAAC3I,MAAM,EAAE;EAC9C,IAAA,OAAOA,MAAM,IAAI,GAAG,IAAIA,MAAM,GAAG,GAAG,CAAA;KACrC;EAEDuH,EAAAA,OAAO,EAAE;EACPqB,IAAAA,MAAM,EAAE;EACN,MAAA,QAAQ,EAAE,mCAAmC;EAC7C,MAAA,cAAc,EAAEtR,SAAAA;EAClB,KAAA;EACF,GAAA;EACF,CAAC,CAAA;AAED2I,SAAK,CAAC9I,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,UAAC0R,MAAM,EAAK;EAC3E3B,EAAAA,QAAQ,CAACK,OAAO,CAACsB,MAAM,CAAC,GAAG,EAAE,CAAA;EAC/B,CAAC,CAAC,CAAA;AAEF,mBAAe3B,QAAQ;;EC5JvB;EACA;EACA,IAAM4B,iBAAiB,GAAG7I,OAAK,CAAClD,WAAW,CAAC,CAC1C,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,EAChE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,qBAAqB,EACrE,eAAe,EAAE,UAAU,EAAE,cAAc,EAAE,qBAAqB,EAClE,SAAS,EAAE,aAAa,EAAE,YAAY,CACvC,CAAC,CAAA;;EAEF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACA,qBAAe,CAAA,UAAAgM,UAAU,EAAI;IAC3B,IAAMC,MAAM,GAAG,EAAE,CAAA;EACjB,EAAA,IAAInR,GAAG,CAAA;EACP,EAAA,IAAIjD,GAAG,CAAA;EACP,EAAA,IAAI6C,CAAC,CAAA;EAELsR,EAAAA,UAAU,IAAIA,UAAU,CAAC5L,KAAK,CAAC,IAAI,CAAC,CAAChG,OAAO,CAAC,SAAS6P,MAAMA,CAACiC,IAAI,EAAE;EACjExR,IAAAA,CAAC,GAAGwR,IAAI,CAAC1O,OAAO,CAAC,GAAG,CAAC,CAAA;EACrB1C,IAAAA,GAAG,GAAGoR,IAAI,CAACC,SAAS,CAAC,CAAC,EAAEzR,CAAC,CAAC,CAACR,IAAI,EAAE,CAAC/C,WAAW,EAAE,CAAA;EAC/CU,IAAAA,GAAG,GAAGqU,IAAI,CAACC,SAAS,CAACzR,CAAC,GAAG,CAAC,CAAC,CAACR,IAAI,EAAE,CAAA;EAElC,IAAA,IAAI,CAACY,GAAG,IAAKmR,MAAM,CAACnR,GAAG,CAAC,IAAIiR,iBAAiB,CAACjR,GAAG,CAAE,EAAE;EACnD,MAAA,OAAA;EACF,KAAA;MAEA,IAAIA,GAAG,KAAK,YAAY,EAAE;EACxB,MAAA,IAAImR,MAAM,CAACnR,GAAG,CAAC,EAAE;EACfmR,QAAAA,MAAM,CAACnR,GAAG,CAAC,CAAC0D,IAAI,CAAC3G,GAAG,CAAC,CAAA;EACvB,OAAC,MAAM;EACLoU,QAAAA,MAAM,CAACnR,GAAG,CAAC,GAAG,CAACjD,GAAG,CAAC,CAAA;EACrB,OAAA;EACF,KAAC,MAAM;EACLoU,MAAAA,MAAM,CAACnR,GAAG,CAAC,GAAGmR,MAAM,CAACnR,GAAG,CAAC,GAAGmR,MAAM,CAACnR,GAAG,CAAC,GAAG,IAAI,GAAGjD,GAAG,GAAGA,GAAG,CAAA;EAC5D,KAAA;EACF,GAAC,CAAC,CAAA;EAEF,EAAA,OAAOoU,MAAM,CAAA;EACf,CAAC;;ECjDD,IAAMG,UAAU,GAAGzV,MAAM,CAAC,WAAW,CAAC,CAAA;EAEtC,SAAS0V,eAAeA,CAACC,MAAM,EAAE;EAC/B,EAAA,OAAOA,MAAM,IAAIhP,MAAM,CAACgP,MAAM,CAAC,CAACpS,IAAI,EAAE,CAAC/C,WAAW,EAAE,CAAA;EACtD,CAAA;EAEA,SAASoV,cAAcA,CAAC7P,KAAK,EAAE;EAC7B,EAAA,IAAIA,KAAK,KAAK,KAAK,IAAIA,KAAK,IAAI,IAAI,EAAE;EACpC,IAAA,OAAOA,KAAK,CAAA;EACd,GAAA;EAEA,EAAA,OAAOwG,OAAK,CAACzL,OAAO,CAACiF,KAAK,CAAC,GAAGA,KAAK,CAAC/C,GAAG,CAAC4S,cAAc,CAAC,GAAGjP,MAAM,CAACZ,KAAK,CAAC,CAAA;EACzE,CAAA;EAEA,SAAS8P,WAAWA,CAACxV,GAAG,EAAE;EACxB,EAAA,IAAMyV,MAAM,GAAGlW,MAAM,CAACa,MAAM,CAAC,IAAI,CAAC,CAAA;IAClC,IAAMsV,QAAQ,GAAG,kCAAkC,CAAA;EACnD,EAAA,IAAIpG,KAAK,CAAA;IAET,OAAQA,KAAK,GAAGoG,QAAQ,CAACnO,IAAI,CAACvH,GAAG,CAAC,EAAG;MACnCyV,MAAM,CAACnG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAGA,KAAK,CAAC,CAAC,CAAC,CAAA;EAC7B,GAAA;EAEA,EAAA,OAAOmG,MAAM,CAAA;EACf,CAAA;EAEA,IAAME,iBAAiB,GAAG,SAApBA,iBAAiBA,CAAI3V,GAAG,EAAA;IAAA,OAAK,gCAAgC,CAAC2N,IAAI,CAAC3N,GAAG,CAACkD,IAAI,EAAE,CAAC,CAAA;EAAA,CAAA,CAAA;EAEpF,SAAS0S,gBAAgBA,CAACrR,OAAO,EAAEmB,KAAK,EAAE4P,MAAM,EAAEvP,MAAM,EAAE8P,kBAAkB,EAAE;EAC5E,EAAA,IAAI3J,OAAK,CAACnL,UAAU,CAACgF,MAAM,CAAC,EAAE;MAC5B,OAAOA,MAAM,CAAC9F,IAAI,CAAC,IAAI,EAAEyF,KAAK,EAAE4P,MAAM,CAAC,CAAA;EACzC,GAAA;EAEA,EAAA,IAAIO,kBAAkB,EAAE;EACtBnQ,IAAAA,KAAK,GAAG4P,MAAM,CAAA;EAChB,GAAA;EAEA,EAAA,IAAI,CAACpJ,OAAK,CAAC5K,QAAQ,CAACoE,KAAK,CAAC,EAAE,OAAA;EAE5B,EAAA,IAAIwG,OAAK,CAAC5K,QAAQ,CAACyE,MAAM,CAAC,EAAE;MAC1B,OAAOL,KAAK,CAACc,OAAO,CAACT,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;EACrC,GAAA;EAEA,EAAA,IAAImG,OAAK,CAAChE,QAAQ,CAACnC,MAAM,CAAC,EAAE;EAC1B,IAAA,OAAOA,MAAM,CAAC4H,IAAI,CAACjI,KAAK,CAAC,CAAA;EAC3B,GAAA;EACF,CAAA;EAEA,SAASoQ,YAAYA,CAACR,MAAM,EAAE;IAC5B,OAAOA,MAAM,CAACpS,IAAI,EAAE,CACjB/C,WAAW,EAAE,CAACgD,OAAO,CAAC,iBAAiB,EAAE,UAAC4S,CAAC,EAAEC,KAAI,EAAEhW,GAAG,EAAK;EAC1D,IAAA,OAAOgW,KAAI,CAACjO,WAAW,EAAE,GAAG/H,GAAG,CAAA;EACjC,GAAC,CAAC,CAAA;EACN,CAAA;EAEA,SAASiW,cAAcA,CAAC5S,GAAG,EAAEiS,MAAM,EAAE;IACnC,IAAMY,YAAY,GAAGhK,OAAK,CAACxE,WAAW,CAAC,GAAG,GAAG4N,MAAM,CAAC,CAAA;IAEpD,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAClS,OAAO,CAAC,UAAA+S,UAAU,EAAI;MAC1C5W,MAAM,CAACkG,cAAc,CAACpC,GAAG,EAAE8S,UAAU,GAAGD,YAAY,EAAE;QACpDxQ,KAAK,EAAE,SAAAA,KAAS0Q,CAAAA,IAAI,EAAEC,IAAI,EAAEC,IAAI,EAAE;EAChC,QAAA,OAAO,IAAI,CAACH,UAAU,CAAC,CAAClW,IAAI,CAAC,IAAI,EAAEqV,MAAM,EAAEc,IAAI,EAAEC,IAAI,EAAEC,IAAI,CAAC,CAAA;SAC7D;EACDtJ,MAAAA,YAAY,EAAE,IAAA;EAChB,KAAC,CAAC,CAAA;EACJ,GAAC,CAAC,CAAA;EACJ,CAAA;EAAC,IAEKuJ,YAAY,gBAAA,UAAAC,gBAAA,EAAAC,mBAAA,EAAA;IAChB,SAAAF,YAAAA,CAAY/C,OAAO,EAAE;EAAArD,IAAAA,eAAA,OAAAoG,YAAA,CAAA,CAAA;EACnB/C,IAAAA,OAAO,IAAI,IAAI,CAAC1K,GAAG,CAAC0K,OAAO,CAAC,CAAA;EAC9B,GAAA;EAACnD,EAAAA,YAAA,CAAAkG,YAAA,EAAA,CAAA;MAAAzS,GAAA,EAAA,KAAA;MAAA4B,KAAA,EAED,SAAAoD,GAAIwM,CAAAA,MAAM,EAAEoB,cAAc,EAAEC,OAAO,EAAE;QACnC,IAAMxS,IAAI,GAAG,IAAI,CAAA;EAEjB,MAAA,SAASyS,SAASA,CAACC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,EAAE;EAC5C,QAAA,IAAMC,OAAO,GAAG3B,eAAe,CAACyB,OAAO,CAAC,CAAA;UAExC,IAAI,CAACE,OAAO,EAAE;EACZ,UAAA,MAAM,IAAIjO,KAAK,CAAC,wCAAwC,CAAC,CAAA;EAC3D,SAAA;UAEA,IAAMjF,GAAG,GAAGoI,OAAK,CAACnI,OAAO,CAACI,IAAI,EAAE6S,OAAO,CAAC,CAAA;UAExC,IAAG,CAAClT,GAAG,IAAIK,IAAI,CAACL,GAAG,CAAC,KAAKP,SAAS,IAAIwT,QAAQ,KAAK,IAAI,IAAKA,QAAQ,KAAKxT,SAAS,IAAIY,IAAI,CAACL,GAAG,CAAC,KAAK,KAAM,EAAE;YAC1GK,IAAI,CAACL,GAAG,IAAIgT,OAAO,CAAC,GAAGvB,cAAc,CAACsB,MAAM,CAAC,CAAA;EAC/C,SAAA;EACF,OAAA;EAEA,MAAA,IAAMI,UAAU,GAAG,SAAbA,UAAUA,CAAIzD,OAAO,EAAEuD,QAAQ,EAAA;UAAA,OACnC7K,OAAK,CAAC9I,OAAO,CAACoQ,OAAO,EAAE,UAACqD,MAAM,EAAEC,OAAO,EAAA;EAAA,UAAA,OAAKF,SAAS,CAACC,MAAM,EAAEC,OAAO,EAAEC,QAAQ,CAAC,CAAA;WAAC,CAAA,CAAA;EAAA,OAAA,CAAA;EAEnF,MAAA,IAAI7K,OAAK,CAACxK,aAAa,CAAC4T,MAAM,CAAC,IAAIA,MAAM,YAAY,IAAI,CAACxU,WAAW,EAAE;EACrEmW,QAAAA,UAAU,CAAC3B,MAAM,EAAEoB,cAAc,CAAC,CAAA;SACnC,MAAM,IAAGxK,OAAK,CAAC5K,QAAQ,CAACgU,MAAM,CAAC,KAAKA,MAAM,GAAGA,MAAM,CAACpS,IAAI,EAAE,CAAC,IAAI,CAACyS,iBAAiB,CAACL,MAAM,CAAC,EAAE;EAC1F2B,QAAAA,UAAU,CAACC,YAAY,CAAC5B,MAAM,CAAC,EAAEoB,cAAc,CAAC,CAAA;EAClD,OAAC,MAAM,IAAIxK,OAAK,CAAC1K,QAAQ,CAAC8T,MAAM,CAAC,IAAIpJ,OAAK,CAACV,UAAU,CAAC8J,MAAM,CAAC,EAAE;UAC7D,IAAIjS,GAAG,GAAG,EAAE;YAAE8T,IAAI;YAAErT,GAAG,CAAA;EAAC,QAAA,IAAAkD,SAAA,GAAAoQ,0BAAA,CACJ9B,MAAM,CAAA;YAAA+B,KAAA,CAAA;EAAA,QAAA,IAAA;YAA1B,KAAArQ,SAAA,CAAAsQ,CAAA,EAAAD,EAAAA,CAAAA,CAAAA,KAAA,GAAArQ,SAAA,CAAAuQ,CAAA,EAAArQ,EAAAA,IAAA,GAA4B;EAAA,YAAA,IAAjBsQ,KAAK,GAAAH,KAAA,CAAA3R,KAAA,CAAA;EACd,YAAA,IAAI,CAACwG,OAAK,CAACzL,OAAO,CAAC+W,KAAK,CAAC,EAAE;gBACzB,MAAMzJ,SAAS,CAAC,8CAA8C,CAAC,CAAA;EACjE,aAAA;cAEA1K,GAAG,CAACS,GAAG,GAAG0T,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAACL,IAAI,GAAG9T,GAAG,CAACS,GAAG,CAAC,IACnCoI,OAAK,CAACzL,OAAO,CAAC0W,IAAI,CAAC,MAAAnM,MAAA,CAAAyM,kBAAA,CAAON,IAAI,IAAEK,KAAK,CAAC,CAAC,CAAC,CAAI,CAAA,GAAA,CAACL,IAAI,EAAEK,KAAK,CAAC,CAAC,CAAC,CAAC,GAAIA,KAAK,CAAC,CAAC,CAAC,CAAA;EAC7E,WAAA;EAAC,SAAA,CAAA,OAAAE,GAAA,EAAA;YAAA1Q,SAAA,CAAAlF,CAAA,CAAA4V,GAAA,CAAA,CAAA;EAAA,SAAA,SAAA;EAAA1Q,UAAAA,SAAA,CAAA2Q,CAAA,EAAA,CAAA;EAAA,SAAA;EAEDV,QAAAA,UAAU,CAAC5T,GAAG,EAAEqT,cAAc,CAAC,CAAA;EACjC,OAAC,MAAM;UACLpB,MAAM,IAAI,IAAI,IAAIsB,SAAS,CAACF,cAAc,EAAEpB,MAAM,EAAEqB,OAAO,CAAC,CAAA;EAC9D,OAAA;EAEA,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;EAAC,GAAA,EAAA;MAAA7S,GAAA,EAAA,KAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAkS,GAAAA,CAAItC,MAAM,EAAErC,MAAM,EAAE;EAClBqC,MAAAA,MAAM,GAAGD,eAAe,CAACC,MAAM,CAAC,CAAA;EAEhC,MAAA,IAAIA,MAAM,EAAE;UACV,IAAMxR,GAAG,GAAGoI,OAAK,CAACnI,OAAO,CAAC,IAAI,EAAEuR,MAAM,CAAC,CAAA;EAEvC,QAAA,IAAIxR,GAAG,EAAE;EACP,UAAA,IAAM4B,KAAK,GAAG,IAAI,CAAC5B,GAAG,CAAC,CAAA;YAEvB,IAAI,CAACmP,MAAM,EAAE;EACX,YAAA,OAAOvN,KAAK,CAAA;EACd,WAAA;YAEA,IAAIuN,MAAM,KAAK,IAAI,EAAE;cACnB,OAAOuC,WAAW,CAAC9P,KAAK,CAAC,CAAA;EAC3B,WAAA;EAEA,UAAA,IAAIwG,OAAK,CAACnL,UAAU,CAACkS,MAAM,CAAC,EAAE;cAC5B,OAAOA,MAAM,CAAChT,IAAI,CAAC,IAAI,EAAEyF,KAAK,EAAE5B,GAAG,CAAC,CAAA;EACtC,WAAA;EAEA,UAAA,IAAIoI,OAAK,CAAChE,QAAQ,CAAC+K,MAAM,CAAC,EAAE;EAC1B,YAAA,OAAOA,MAAM,CAAC1L,IAAI,CAAC7B,KAAK,CAAC,CAAA;EAC3B,WAAA;EAEA,UAAA,MAAM,IAAIqI,SAAS,CAAC,wCAAwC,CAAC,CAAA;EAC/D,SAAA;EACF,OAAA;EACF,KAAA;EAAC,GAAA,EAAA;MAAAjK,GAAA,EAAA,KAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAmS,GAAAA,CAAIvC,MAAM,EAAEwC,OAAO,EAAE;EACnBxC,MAAAA,MAAM,GAAGD,eAAe,CAACC,MAAM,CAAC,CAAA;EAEhC,MAAA,IAAIA,MAAM,EAAE;UACV,IAAMxR,GAAG,GAAGoI,OAAK,CAACnI,OAAO,CAAC,IAAI,EAAEuR,MAAM,CAAC,CAAA;EAEvC,QAAA,OAAO,CAAC,EAAExR,GAAG,IAAI,IAAI,CAACA,GAAG,CAAC,KAAKP,SAAS,KAAK,CAACuU,OAAO,IAAIlC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC9R,GAAG,CAAC,EAAEA,GAAG,EAAEgU,OAAO,CAAC,CAAC,CAAC,CAAA;EAC5G,OAAA;EAEA,MAAA,OAAO,KAAK,CAAA;EACd,KAAA;EAAC,GAAA,EAAA;MAAAhU,GAAA,EAAA,QAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAqS,OAAAA,CAAOzC,MAAM,EAAEwC,OAAO,EAAE;QACtB,IAAM3T,IAAI,GAAG,IAAI,CAAA;QACjB,IAAI6T,OAAO,GAAG,KAAK,CAAA;QAEnB,SAASC,YAAYA,CAACnB,OAAO,EAAE;EAC7BA,QAAAA,OAAO,GAAGzB,eAAe,CAACyB,OAAO,CAAC,CAAA;EAElC,QAAA,IAAIA,OAAO,EAAE;YACX,IAAMhT,GAAG,GAAGoI,OAAK,CAACnI,OAAO,CAACI,IAAI,EAAE2S,OAAO,CAAC,CAAA;EAExC,UAAA,IAAIhT,GAAG,KAAK,CAACgU,OAAO,IAAIlC,gBAAgB,CAACzR,IAAI,EAAEA,IAAI,CAACL,GAAG,CAAC,EAAEA,GAAG,EAAEgU,OAAO,CAAC,CAAC,EAAE;cACxE,OAAO3T,IAAI,CAACL,GAAG,CAAC,CAAA;EAEhBkU,YAAAA,OAAO,GAAG,IAAI,CAAA;EAChB,WAAA;EACF,SAAA;EACF,OAAA;EAEA,MAAA,IAAI9L,OAAK,CAACzL,OAAO,CAAC6U,MAAM,CAAC,EAAE;EACzBA,QAAAA,MAAM,CAAClS,OAAO,CAAC6U,YAAY,CAAC,CAAA;EAC9B,OAAC,MAAM;UACLA,YAAY,CAAC3C,MAAM,CAAC,CAAA;EACtB,OAAA;EAEA,MAAA,OAAO0C,OAAO,CAAA;EAChB,KAAA;EAAC,GAAA,EAAA;MAAAlU,GAAA,EAAA,OAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAmL,KAAMiH,CAAAA,OAAO,EAAE;EACb,MAAA,IAAMlW,IAAI,GAAGrC,MAAM,CAACqC,IAAI,CAAC,IAAI,CAAC,CAAA;EAC9B,MAAA,IAAI8B,CAAC,GAAG9B,IAAI,CAACC,MAAM,CAAA;QACnB,IAAImW,OAAO,GAAG,KAAK,CAAA;QAEnB,OAAOtU,CAAC,EAAE,EAAE;EACV,QAAA,IAAMI,GAAG,GAAGlC,IAAI,CAAC8B,CAAC,CAAC,CAAA;EACnB,QAAA,IAAG,CAACoU,OAAO,IAAIlC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC9R,GAAG,CAAC,EAAEA,GAAG,EAAEgU,OAAO,EAAE,IAAI,CAAC,EAAE;YACpE,OAAO,IAAI,CAAChU,GAAG,CAAC,CAAA;EAChBkU,UAAAA,OAAO,GAAG,IAAI,CAAA;EAChB,SAAA;EACF,OAAA;EAEA,MAAA,OAAOA,OAAO,CAAA;EAChB,KAAA;EAAC,GAAA,EAAA;MAAAlU,GAAA,EAAA,WAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAwS,SAAUC,CAAAA,MAAM,EAAE;QAChB,IAAMhU,IAAI,GAAG,IAAI,CAAA;QACjB,IAAMqP,OAAO,GAAG,EAAE,CAAA;QAElBtH,OAAK,CAAC9I,OAAO,CAAC,IAAI,EAAE,UAACsC,KAAK,EAAE4P,MAAM,EAAK;UACrC,IAAMxR,GAAG,GAAGoI,OAAK,CAACnI,OAAO,CAACyP,OAAO,EAAE8B,MAAM,CAAC,CAAA;EAE1C,QAAA,IAAIxR,GAAG,EAAE;EACPK,UAAAA,IAAI,CAACL,GAAG,CAAC,GAAGyR,cAAc,CAAC7P,KAAK,CAAC,CAAA;YACjC,OAAOvB,IAAI,CAACmR,MAAM,CAAC,CAAA;EACnB,UAAA,OAAA;EACF,SAAA;EAEA,QAAA,IAAM8C,UAAU,GAAGD,MAAM,GAAGrC,YAAY,CAACR,MAAM,CAAC,GAAGhP,MAAM,CAACgP,MAAM,CAAC,CAACpS,IAAI,EAAE,CAAA;UAExE,IAAIkV,UAAU,KAAK9C,MAAM,EAAE;YACzB,OAAOnR,IAAI,CAACmR,MAAM,CAAC,CAAA;EACrB,SAAA;EAEAnR,QAAAA,IAAI,CAACiU,UAAU,CAAC,GAAG7C,cAAc,CAAC7P,KAAK,CAAC,CAAA;EAExC8N,QAAAA,OAAO,CAAC4E,UAAU,CAAC,GAAG,IAAI,CAAA;EAC5B,OAAC,CAAC,CAAA;EAEF,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;EAAC,GAAA,EAAA;MAAAtU,GAAA,EAAA,QAAA;MAAA4B,KAAA,EAED,SAAAsF,MAAAA,GAAmB;EAAA,MAAA,IAAAqN,iBAAA,CAAA;EAAA,MAAA,KAAA,IAAAC,IAAA,GAAAjZ,SAAA,CAAAwC,MAAA,EAAT0W,OAAO,GAAA7X,IAAAA,KAAA,CAAA4X,IAAA,GAAAtU,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAsU,IAAA,EAAAtU,IAAA,EAAA,EAAA;EAAPuU,QAAAA,OAAO,CAAAvU,IAAA,CAAA3E,GAAAA,SAAA,CAAA2E,IAAA,CAAA,CAAA;EAAA,OAAA;EACf,MAAA,OAAO,CAAAqU,iBAAA,GAAA,IAAI,CAACvX,WAAW,EAACkK,MAAM,CAAA5L,KAAA,CAAAiZ,iBAAA,EAAC,CAAA,IAAI,EAAArN,MAAA,CAAKuN,OAAO,CAAC,CAAA,CAAA;EAClD,KAAA;EAAC,GAAA,EAAA;MAAAzU,GAAA,EAAA,QAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAyG,MAAOqM,CAAAA,SAAS,EAAE;EAChB,MAAA,IAAMnV,GAAG,GAAG9D,MAAM,CAACa,MAAM,CAAC,IAAI,CAAC,CAAA;QAE/B8L,OAAK,CAAC9I,OAAO,CAAC,IAAI,EAAE,UAACsC,KAAK,EAAE4P,MAAM,EAAK;EACrC5P,QAAAA,KAAK,IAAI,IAAI,IAAIA,KAAK,KAAK,KAAK,KAAKrC,GAAG,CAACiS,MAAM,CAAC,GAAGkD,SAAS,IAAItM,OAAK,CAACzL,OAAO,CAACiF,KAAK,CAAC,GAAGA,KAAK,CAAC6H,IAAI,CAAC,IAAI,CAAC,GAAG7H,KAAK,CAAC,CAAA;EAClH,OAAC,CAAC,CAAA;EAEF,MAAA,OAAOrC,GAAG,CAAA;EACZ,KAAA;EAAC,GAAA,EAAA;EAAAS,IAAAA,GAAA,EAAA0S,gBAAA;MAAA9Q,KAAA,EAED,SAAAA,KAAAA,GAAoB;EAClB,MAAA,OAAOnG,MAAM,CAACuT,OAAO,CAAC,IAAI,CAAC3G,MAAM,EAAE,CAAC,CAACxM,MAAM,CAACD,QAAQ,CAAC,EAAE,CAAA;EACzD,KAAA;EAAC,GAAA,EAAA;MAAAoE,GAAA,EAAA,UAAA;MAAA4B,KAAA,EAED,SAAApG,QAAAA,GAAW;EACT,MAAA,OAAOC,MAAM,CAACuT,OAAO,CAAC,IAAI,CAAC3G,MAAM,EAAE,CAAC,CAACxJ,GAAG,CAAC,UAAAW,IAAA,EAAA;EAAA,QAAA,IAAAmB,KAAA,GAAA5B,cAAA,CAAAS,IAAA,EAAA,CAAA,CAAA;EAAEgS,UAAAA,MAAM,GAAA7Q,KAAA,CAAA,CAAA,CAAA;EAAEiB,UAAAA,KAAK,GAAAjB,KAAA,CAAA,CAAA,CAAA,CAAA;EAAA,QAAA,OAAM6Q,MAAM,GAAG,IAAI,GAAG5P,KAAK,CAAA;EAAA,OAAA,CAAC,CAAC6H,IAAI,CAAC,IAAI,CAAC,CAAA;EACjG,KAAA;EAAC,GAAA,EAAA;MAAAzJ,GAAA,EAAA,cAAA;MAAA4B,KAAA,EAED,SAAA+S,YAAAA,GAAe;EACb,MAAA,OAAO,IAAI,CAACb,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAA;EACrC,KAAA;EAAC,GAAA,EAAA;EAAA9T,IAAAA,GAAA,EAAA2S,mBAAA;MAAAmB,GAAA,EAED,SAAAA,GAAAA,GAA2B;EACzB,MAAA,OAAO,cAAc,CAAA;EACvB,KAAA;EAAC,GAAA,CAAA,EAAA,CAAA;MAAA9T,GAAA,EAAA,MAAA;EAAA4B,IAAAA,KAAA,EAED,SAAA+G,IAAY1M,CAAAA,KAAK,EAAE;QACjB,OAAOA,KAAK,YAAY,IAAI,GAAGA,KAAK,GAAG,IAAI,IAAI,CAACA,KAAK,CAAC,CAAA;EACxD,KAAA;EAAC,GAAA,EAAA;MAAA+D,GAAA,EAAA,QAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAsF,MAAc0N,CAAAA,KAAK,EAAc;EAC/B,MAAA,IAAMC,QAAQ,GAAG,IAAI,IAAI,CAACD,KAAK,CAAC,CAAA;QAAC,KAAAE,IAAAA,KAAA,GAAAvZ,SAAA,CAAAwC,MAAA,EADX0W,OAAO,OAAA7X,KAAA,CAAAkY,KAAA,GAAAA,CAAAA,GAAAA,KAAA,WAAAC,KAAA,GAAA,CAAA,EAAAA,KAAA,GAAAD,KAAA,EAAAC,KAAA,EAAA,EAAA;EAAPN,QAAAA,OAAO,CAAAM,KAAA,GAAAxZ,CAAAA,CAAAA,GAAAA,SAAA,CAAAwZ,KAAA,CAAA,CAAA;EAAA,OAAA;EAG7BN,MAAAA,OAAO,CAACnV,OAAO,CAAC,UAAC2G,MAAM,EAAA;EAAA,QAAA,OAAK4O,QAAQ,CAAC7P,GAAG,CAACiB,MAAM,CAAC,CAAA;SAAC,CAAA,CAAA;EAEjD,MAAA,OAAO4O,QAAQ,CAAA;EACjB,KAAA;EAAC,GAAA,EAAA;MAAA7U,GAAA,EAAA,UAAA;EAAA4B,IAAAA,KAAA,EAED,SAAAoT,QAAgBxD,CAAAA,MAAM,EAAE;QACtB,IAAMyD,SAAS,GAAG,IAAI,CAAC3D,UAAU,CAAC,GAAI,IAAI,CAACA,UAAU,CAAC,GAAG;EACvD4D,QAAAA,SAAS,EAAE,EAAC;SACZ,CAAA;EAEF,MAAA,IAAMA,SAAS,GAAGD,SAAS,CAACC,SAAS,CAAA;EACrC,MAAA,IAAMxZ,SAAS,GAAG,IAAI,CAACA,SAAS,CAAA;QAEhC,SAASyZ,cAAcA,CAACnC,OAAO,EAAE;EAC/B,QAAA,IAAME,OAAO,GAAG3B,eAAe,CAACyB,OAAO,CAAC,CAAA;EAExC,QAAA,IAAI,CAACkC,SAAS,CAAChC,OAAO,CAAC,EAAE;EACvBf,UAAAA,cAAc,CAACzW,SAAS,EAAEsX,OAAO,CAAC,CAAA;EAClCkC,UAAAA,SAAS,CAAChC,OAAO,CAAC,GAAG,IAAI,CAAA;EAC3B,SAAA;EACF,OAAA;EAEA9K,MAAAA,OAAK,CAACzL,OAAO,CAAC6U,MAAM,CAAC,GAAGA,MAAM,CAAClS,OAAO,CAAC6V,cAAc,CAAC,GAAGA,cAAc,CAAC3D,MAAM,CAAC,CAAA;EAE/E,MAAA,OAAO,IAAI,CAAA;EACb,KAAA;EAAC,GAAA,CAAA,CAAA,CAAA;EAAA,EAAA,OAAAiB,YAAA,CAAA;EAAA,CAAA,CAhDA5W,MAAM,CAACD,QAAQ,EAYXC,MAAM,CAACC,WAAW,CAAA,CAAA;EAuCzB2W,YAAY,CAACuC,QAAQ,CAAC,CAAC,cAAc,EAAE,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAA;;EAErH;AACA5M,SAAK,CAAC/D,iBAAiB,CAACoO,YAAY,CAAC/W,SAAS,EAAE,UAAAyF,KAAA,EAAUnB,GAAG,EAAK;EAAA,EAAA,IAAhB4B,KAAK,GAAAT,KAAA,CAALS,KAAK,CAAA;EACrD,EAAA,IAAIwT,MAAM,GAAGpV,GAAG,CAAC,CAAC,CAAC,CAACiE,WAAW,EAAE,GAAGjE,GAAG,CAAC5D,KAAK,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO;MACL0X,GAAG,EAAE,SAAAA,GAAA,GAAA;EAAA,MAAA,OAAMlS,KAAK,CAAA;EAAA,KAAA;MAChBoD,GAAG,EAAA,SAAAA,GAACqQ,CAAAA,WAAW,EAAE;EACf,MAAA,IAAI,CAACD,MAAM,CAAC,GAAGC,WAAW,CAAA;EAC5B,KAAA;KACD,CAAA;EACH,CAAC,CAAC,CAAA;AAEFjN,SAAK,CAACvD,aAAa,CAAC4N,YAAY,CAAC,CAAA;AAEjC,uBAAeA,YAAY;;ECnT3B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAAS6C,aAAaA,CAACC,GAAG,EAAEtN,QAAQ,EAAE;EACnD,EAAA,IAAMF,MAAM,GAAG,IAAI,IAAIsH,UAAQ,CAAA;EAC/B,EAAA,IAAM5O,OAAO,GAAGwH,QAAQ,IAAIF,MAAM,CAAA;IAClC,IAAM2H,OAAO,GAAG+C,cAAY,CAAC9J,IAAI,CAAClI,OAAO,CAACiP,OAAO,CAAC,CAAA;EAClD,EAAA,IAAI5I,IAAI,GAAGrG,OAAO,CAACqG,IAAI,CAAA;IAEvBsB,OAAK,CAAC9I,OAAO,CAACiW,GAAG,EAAE,SAASC,SAASA,CAACra,EAAE,EAAE;MACxC2L,IAAI,GAAG3L,EAAE,CAACgB,IAAI,CAAC4L,MAAM,EAAEjB,IAAI,EAAE4I,OAAO,CAAC0E,SAAS,EAAE,EAAEnM,QAAQ,GAAGA,QAAQ,CAACE,MAAM,GAAG1I,SAAS,CAAC,CAAA;EAC3F,GAAC,CAAC,CAAA;IAEFiQ,OAAO,CAAC0E,SAAS,EAAE,CAAA;EAEnB,EAAA,OAAOtN,IAAI,CAAA;EACb;;ECzBe,SAAS2O,QAAQA,CAAC7T,KAAK,EAAE;EACtC,EAAA,OAAO,CAAC,EAAEA,KAAK,IAAIA,KAAK,CAAC8T,UAAU,CAAC,CAAA;EACtC;;ECCA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASC,aAAaA,CAAC9N,OAAO,EAAEE,MAAM,EAAEC,OAAO,EAAE;EAC/C;IACAJ,UAAU,CAACzL,IAAI,CAAC,IAAI,EAAE0L,OAAO,IAAI,IAAI,GAAG,UAAU,GAAGA,OAAO,EAAED,UAAU,CAACgO,YAAY,EAAE7N,MAAM,EAAEC,OAAO,CAAC,CAAA;IACvG,IAAI,CAACtD,IAAI,GAAG,eAAe,CAAA;EAC7B,CAAA;AAEA0D,SAAK,CAAC7G,QAAQ,CAACoU,aAAa,EAAE/N,UAAU,EAAE;EACxC8N,EAAAA,UAAU,EAAE,IAAA;EACd,CAAC,CAAC;;EClBF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASG,MAAMA,CAACC,OAAO,EAAEC,MAAM,EAAE9N,QAAQ,EAAE;EACxD,EAAA,IAAM6I,cAAc,GAAG7I,QAAQ,CAACF,MAAM,CAAC+I,cAAc,CAAA;EACrD,EAAA,IAAI,CAAC7I,QAAQ,CAACE,MAAM,IAAI,CAAC2I,cAAc,IAAIA,cAAc,CAAC7I,QAAQ,CAACE,MAAM,CAAC,EAAE;MAC1E2N,OAAO,CAAC7N,QAAQ,CAAC,CAAA;EACnB,GAAC,MAAM;MACL8N,MAAM,CAAC,IAAInO,UAAU,CACnB,kCAAkC,GAAGK,QAAQ,CAACE,MAAM,EACpD,CAACP,UAAU,CAACoO,eAAe,EAAEpO,UAAU,CAAC4I,gBAAgB,CAAC,CAACrJ,IAAI,CAAC8O,KAAK,CAAChO,QAAQ,CAACE,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAChGF,QAAQ,CAACF,MAAM,EACfE,QAAQ,CAACD,OAAO,EAChBC,QACF,CAAC,CAAC,CAAA;EACJ,GAAA;EACF;;ECxBe,SAASiO,aAAaA,CAACnK,GAAG,EAAE;EACzC,EAAA,IAAMP,KAAK,GAAG,2BAA2B,CAAC/H,IAAI,CAACsI,GAAG,CAAC,CAAA;EACnD,EAAA,OAAOP,KAAK,IAAIA,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;EAChC;;ECHA;EACA;EACA;EACA;EACA;EACA;EACA,SAAS2K,WAAWA,CAACC,YAAY,EAAEC,GAAG,EAAE;IACtCD,YAAY,GAAGA,YAAY,IAAI,EAAE,CAAA;EACjC,EAAA,IAAME,KAAK,GAAG,IAAI1Z,KAAK,CAACwZ,YAAY,CAAC,CAAA;EACrC,EAAA,IAAMG,UAAU,GAAG,IAAI3Z,KAAK,CAACwZ,YAAY,CAAC,CAAA;IAC1C,IAAII,IAAI,GAAG,CAAC,CAAA;IACZ,IAAIC,IAAI,GAAG,CAAC,CAAA;EACZ,EAAA,IAAIC,aAAa,CAAA;EAEjBL,EAAAA,GAAG,GAAGA,GAAG,KAAK5W,SAAS,GAAG4W,GAAG,GAAG,IAAI,CAAA;EAEpC,EAAA,OAAO,SAAS3S,IAAIA,CAACiT,WAAW,EAAE;EAChC,IAAA,IAAMC,GAAG,GAAGC,IAAI,CAACD,GAAG,EAAE,CAAA;EAEtB,IAAA,IAAME,SAAS,GAAGP,UAAU,CAACE,IAAI,CAAC,CAAA;MAElC,IAAI,CAACC,aAAa,EAAE;EAClBA,MAAAA,aAAa,GAAGE,GAAG,CAAA;EACrB,KAAA;EAEAN,IAAAA,KAAK,CAACE,IAAI,CAAC,GAAGG,WAAW,CAAA;EACzBJ,IAAAA,UAAU,CAACC,IAAI,CAAC,GAAGI,GAAG,CAAA;MAEtB,IAAIhX,CAAC,GAAG6W,IAAI,CAAA;MACZ,IAAIM,UAAU,GAAG,CAAC,CAAA;MAElB,OAAOnX,CAAC,KAAK4W,IAAI,EAAE;EACjBO,MAAAA,UAAU,IAAIT,KAAK,CAAC1W,CAAC,EAAE,CAAC,CAAA;QACxBA,CAAC,GAAGA,CAAC,GAAGwW,YAAY,CAAA;EACtB,KAAA;EAEAI,IAAAA,IAAI,GAAG,CAACA,IAAI,GAAG,CAAC,IAAIJ,YAAY,CAAA;MAEhC,IAAII,IAAI,KAAKC,IAAI,EAAE;EACjBA,MAAAA,IAAI,GAAG,CAACA,IAAI,GAAG,CAAC,IAAIL,YAAY,CAAA;EAClC,KAAA;EAEA,IAAA,IAAIQ,GAAG,GAAGF,aAAa,GAAGL,GAAG,EAAE;EAC7B,MAAA,OAAA;EACF,KAAA;EAEA,IAAA,IAAMW,MAAM,GAAGF,SAAS,IAAIF,GAAG,GAAGE,SAAS,CAAA;EAE3C,IAAA,OAAOE,MAAM,GAAG7P,IAAI,CAAC8P,KAAK,CAACF,UAAU,GAAG,IAAI,GAAGC,MAAM,CAAC,GAAGvX,SAAS,CAAA;KACnE,CAAA;EACH;;ECpDA;EACA;EACA;EACA;EACA;EACA;EACA,SAASyX,QAAQA,CAAC/b,EAAE,EAAEgc,IAAI,EAAE;IAC1B,IAAIC,SAAS,GAAG,CAAC,CAAA;EACjB,EAAA,IAAIC,SAAS,GAAG,IAAI,GAAGF,IAAI,CAAA;EAC3B,EAAA,IAAIG,QAAQ,CAAA;EACZ,EAAA,IAAIC,KAAK,CAAA;EAET,EAAA,IAAMC,MAAM,GAAG,SAATA,MAAMA,CAAIC,IAAI,EAAuB;EAAA,IAAA,IAArBb,GAAG,GAAArb,SAAA,CAAAwC,MAAA,QAAAxC,SAAA,CAAA,CAAA,CAAA,KAAAkE,SAAA,GAAAlE,SAAA,CAAGsb,CAAAA,CAAAA,GAAAA,IAAI,CAACD,GAAG,EAAE,CAAA;EACpCQ,IAAAA,SAAS,GAAGR,GAAG,CAAA;EACfU,IAAAA,QAAQ,GAAG,IAAI,CAAA;EACf,IAAA,IAAIC,KAAK,EAAE;QACTG,YAAY,CAACH,KAAK,CAAC,CAAA;EACnBA,MAAAA,KAAK,GAAG,IAAI,CAAA;EACd,KAAA;EACApc,IAAAA,EAAE,CAAAG,KAAA,CAAA,KAAA,CAAA,EAAAqY,kBAAA,CAAI8D,IAAI,CAAC,CAAA,CAAA;KACZ,CAAA;EAED,EAAA,IAAME,SAAS,GAAG,SAAZA,SAASA,GAAgB;EAC7B,IAAA,IAAMf,GAAG,GAAGC,IAAI,CAACD,GAAG,EAAE,CAAA;EACtB,IAAA,IAAMI,MAAM,GAAGJ,GAAG,GAAGQ,SAAS,CAAA;EAAC,IAAA,KAAA,IAAA5C,IAAA,GAAAjZ,SAAA,CAAAwC,MAAA,EAFX0Z,IAAI,GAAA7a,IAAAA,KAAA,CAAA4X,IAAA,GAAAtU,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAsU,IAAA,EAAAtU,IAAA,EAAA,EAAA;EAAJuX,MAAAA,IAAI,CAAAvX,IAAA,CAAA3E,GAAAA,SAAA,CAAA2E,IAAA,CAAA,CAAA;EAAA,KAAA;MAGxB,IAAK8W,MAAM,IAAIK,SAAS,EAAE;EACxBG,MAAAA,MAAM,CAACC,IAAI,EAAEb,GAAG,CAAC,CAAA;EACnB,KAAC,MAAM;EACLU,MAAAA,QAAQ,GAAGG,IAAI,CAAA;QACf,IAAI,CAACF,KAAK,EAAE;UACVA,KAAK,GAAGlQ,UAAU,CAAC,YAAM;EACvBkQ,UAAAA,KAAK,GAAG,IAAI,CAAA;YACZC,MAAM,CAACF,QAAQ,CAAC,CAAA;EAClB,SAAC,EAAED,SAAS,GAAGL,MAAM,CAAC,CAAA;EACxB,OAAA;EACF,KAAA;KACD,CAAA;EAED,EAAA,IAAMY,KAAK,GAAG,SAARA,KAAKA,GAAA;EAAA,IAAA,OAASN,QAAQ,IAAIE,MAAM,CAACF,QAAQ,CAAC,CAAA;EAAA,GAAA,CAAA;EAEhD,EAAA,OAAO,CAACK,SAAS,EAAEC,KAAK,CAAC,CAAA;EAC3B;;ECrCO,IAAMC,oBAAoB,GAAG,SAAvBA,oBAAoBA,CAAIC,QAAQ,EAAEC,gBAAgB,EAAe;EAAA,EAAA,IAAbZ,IAAI,GAAA5b,SAAA,CAAAwC,MAAA,GAAA,CAAA,IAAAxC,SAAA,CAAA,CAAA,CAAA,KAAAkE,SAAA,GAAAlE,SAAA,CAAA,CAAA,CAAA,GAAG,CAAC,CAAA;IACvE,IAAIyc,aAAa,GAAG,CAAC,CAAA;EACrB,EAAA,IAAMC,YAAY,GAAG9B,WAAW,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;EAEzC,EAAA,OAAOe,QAAQ,CAAC,UAAAlZ,CAAC,EAAI;EACnB,IAAA,IAAMka,MAAM,GAAGla,CAAC,CAACka,MAAM,CAAA;MACvB,IAAMC,KAAK,GAAGna,CAAC,CAACoa,gBAAgB,GAAGpa,CAAC,CAACma,KAAK,GAAG1Y,SAAS,CAAA;EACtD,IAAA,IAAM4Y,aAAa,GAAGH,MAAM,GAAGF,aAAa,CAAA;EAC5C,IAAA,IAAMM,IAAI,GAAGL,YAAY,CAACI,aAAa,CAAC,CAAA;EACxC,IAAA,IAAME,OAAO,GAAGL,MAAM,IAAIC,KAAK,CAAA;EAE/BH,IAAAA,aAAa,GAAGE,MAAM,CAAA;MAEtB,IAAMpR,IAAI,GAAA0R,eAAA,CAAA;EACRN,MAAAA,MAAM,EAANA,MAAM;EACNC,MAAAA,KAAK,EAALA,KAAK;EACLM,MAAAA,QAAQ,EAAEN,KAAK,GAAID,MAAM,GAAGC,KAAK,GAAI1Y,SAAS;EAC9C6W,MAAAA,KAAK,EAAE+B,aAAa;EACpBC,MAAAA,IAAI,EAAEA,IAAI,GAAGA,IAAI,GAAG7Y,SAAS;EAC7BiZ,MAAAA,SAAS,EAAEJ,IAAI,IAAIH,KAAK,IAAII,OAAO,GAAG,CAACJ,KAAK,GAAGD,MAAM,IAAII,IAAI,GAAG7Y,SAAS;EACzEkZ,MAAAA,KAAK,EAAE3a,CAAC;QACRoa,gBAAgB,EAAED,KAAK,IAAI,IAAA;EAAI,KAAA,EAC9BJ,gBAAgB,GAAG,UAAU,GAAG,QAAQ,EAAG,IAAI,CACjD,CAAA;MAEDD,QAAQ,CAAChR,IAAI,CAAC,CAAA;KACf,EAAEqQ,IAAI,CAAC,CAAA;EACV,CAAC,CAAA;EAEM,IAAMyB,sBAAsB,GAAG,SAAzBA,sBAAsBA,CAAIT,KAAK,EAAER,SAAS,EAAK;EAC1D,EAAA,IAAMS,gBAAgB,GAAGD,KAAK,IAAI,IAAI,CAAA;IAEtC,OAAO,CAAC,UAACD,MAAM,EAAA;EAAA,IAAA,OAAKP,SAAS,CAAC,CAAC,CAAC,CAAC;EAC/BS,MAAAA,gBAAgB,EAAhBA,gBAAgB;EAChBD,MAAAA,KAAK,EAALA,KAAK;EACLD,MAAAA,MAAM,EAANA,MAAAA;EACF,KAAC,CAAC,CAAA;EAAA,GAAA,EAAEP,SAAS,CAAC,CAAC,CAAC,CAAC,CAAA;EACnB,CAAC,CAAA;EAEM,IAAMkB,cAAc,GAAG,SAAjBA,cAAcA,CAAI1d,EAAE,EAAA;IAAA,OAAK,YAAA;EAAA,IAAA,KAAA,IAAAqZ,IAAA,GAAAjZ,SAAA,CAAAwC,MAAA,EAAI0Z,IAAI,GAAA7a,IAAAA,KAAA,CAAA4X,IAAA,GAAAtU,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAsU,IAAA,EAAAtU,IAAA,EAAA,EAAA;EAAJuX,MAAAA,IAAI,CAAAvX,IAAA,CAAA3E,GAAAA,SAAA,CAAA2E,IAAA,CAAA,CAAA;EAAA,KAAA;MAAA,OAAKkI,OAAK,CAACd,IAAI,CAAC,YAAA;EAAA,MAAA,OAAMnM,EAAE,CAAAG,KAAA,CAAA,KAAA,CAAA,EAAImc,IAAI,CAAC,CAAA;OAAC,CAAA,CAAA;EAAA,GAAA,CAAA;EAAA,CAAA;;ACzChF,wBAAenJ,QAAQ,CAACT,qBAAqB,GAAI,UAACK,MAAM,EAAE4K,MAAM,EAAA;IAAA,OAAK,UAAC/M,GAAG,EAAK;MAC5EA,GAAG,GAAG,IAAIgN,GAAG,CAAChN,GAAG,EAAEuC,QAAQ,CAACJ,MAAM,CAAC,CAAA;MAEnC,OACEA,MAAM,CAAC8K,QAAQ,KAAKjN,GAAG,CAACiN,QAAQ,IAChC9K,MAAM,CAAC+K,IAAI,KAAKlN,GAAG,CAACkN,IAAI,KACvBH,MAAM,IAAI5K,MAAM,CAACgL,IAAI,KAAKnN,GAAG,CAACmN,IAAI,CAAC,CAAA;KAEvC,CAAA;EAAA,CACC,CAAA,IAAIH,GAAG,CAACzK,QAAQ,CAACJ,MAAM,CAAC,EACxBI,QAAQ,CAACV,SAAS,IAAI,iBAAiB,CAAC/D,IAAI,CAACyE,QAAQ,CAACV,SAAS,CAACuL,SAAS,CAC3E,CAAC,GAAG,YAAA;EAAA,EAAA,OAAM,IAAI,CAAA;EAAA,CAAA;;ACVd,gBAAe7K,QAAQ,CAACT,qBAAqB;EAE3C;EACA;EACEuL,EAAAA,KAAK,EAAAA,SAAAA,KAAAA,CAAC1U,IAAI,EAAE9C,KAAK,EAAEyX,OAAO,EAAE/P,IAAI,EAAEgQ,MAAM,EAAEC,MAAM,EAAE;MAChD,IAAMC,MAAM,GAAG,CAAC9U,IAAI,GAAG,GAAG,GAAG6G,kBAAkB,CAAC3J,KAAK,CAAC,CAAC,CAAA;MAEvDwG,OAAK,CAAC3K,QAAQ,CAAC4b,OAAO,CAAC,IAAIG,MAAM,CAAC9V,IAAI,CAAC,UAAU,GAAG,IAAImT,IAAI,CAACwC,OAAO,CAAC,CAACI,WAAW,EAAE,CAAC,CAAA;EAEpFrR,IAAAA,OAAK,CAAC5K,QAAQ,CAAC8L,IAAI,CAAC,IAAIkQ,MAAM,CAAC9V,IAAI,CAAC,OAAO,GAAG4F,IAAI,CAAC,CAAA;EAEnDlB,IAAAA,OAAK,CAAC5K,QAAQ,CAAC8b,MAAM,CAAC,IAAIE,MAAM,CAAC9V,IAAI,CAAC,SAAS,GAAG4V,MAAM,CAAC,CAAA;MAEzDC,MAAM,KAAK,IAAI,IAAIC,MAAM,CAAC9V,IAAI,CAAC,QAAQ,CAAC,CAAA;MAExCgK,QAAQ,CAAC8L,MAAM,GAAGA,MAAM,CAAC/P,IAAI,CAAC,IAAI,CAAC,CAAA;KACpC;IAEDiQ,IAAI,EAAA,SAAAA,IAAChV,CAAAA,IAAI,EAAE;EACT,IAAA,IAAM8G,KAAK,GAAGkC,QAAQ,CAAC8L,MAAM,CAAChO,KAAK,CAAC,IAAImO,MAAM,CAAC,YAAY,GAAGjV,IAAI,GAAG,WAAW,CAAC,CAAC,CAAA;MAClF,OAAQ8G,KAAK,GAAGoO,kBAAkB,CAACpO,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;KACpD;IAEDqO,MAAM,EAAA,SAAAA,MAACnV,CAAAA,IAAI,EAAE;EACX,IAAA,IAAI,CAAC0U,KAAK,CAAC1U,IAAI,EAAE,EAAE,EAAEmS,IAAI,CAACD,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAA;EAC7C,GAAA;EACF,CAAC;EAID;EACA;EACEwC,EAAAA,KAAK,EAAAA,SAAAA,KAAAA,GAAG,EAAE;IACVM,IAAI,EAAA,SAAAA,OAAG;EACL,IAAA,OAAO,IAAI,CAAA;KACZ;IACDG,MAAM,EAAA,SAAAA,MAAA,GAAG,EAAC;EACZ,CAAC;;ECtCH;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASC,aAAaA,CAAC/N,GAAG,EAAE;EACzC;EACA;EACA;EACA,EAAA,OAAO,6BAA6B,CAAClC,IAAI,CAACkC,GAAG,CAAC,CAAA;EAChD;;ECZA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASgO,WAAWA,CAACC,OAAO,EAAEC,WAAW,EAAE;IACxD,OAAOA,WAAW,GACdD,OAAO,CAAC3a,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG4a,WAAW,CAAC5a,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GACrE2a,OAAO,CAAA;EACb;;ECTA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASE,aAAaA,CAACF,OAAO,EAAEG,YAAY,EAAEC,iBAAiB,EAAE;EAC9E,EAAA,IAAIC,aAAa,GAAG,CAACP,aAAa,CAACK,YAAY,CAAC,CAAA;IAChD,IAAIH,OAAO,KAAKK,aAAa,IAAID,iBAAiB,IAAI,KAAK,CAAC,EAAE;EAC5D,IAAA,OAAOL,WAAW,CAACC,OAAO,EAAEG,YAAY,CAAC,CAAA;EAC3C,GAAA;EACA,EAAA,OAAOA,YAAY,CAAA;EACrB;;EChBA,IAAMG,eAAe,GAAG,SAAlBA,eAAeA,CAAIre,KAAK,EAAA;IAAA,OAAKA,KAAK,YAAYwW,cAAY,GAAApE,cAAA,CAAQpS,EAAAA,EAAAA,KAAK,IAAKA,KAAK,CAAA;EAAA,CAAA,CAAA;;EAEvF;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASse,WAAWA,CAACC,OAAO,EAAEC,OAAO,EAAE;EACpD;EACAA,EAAAA,OAAO,GAAGA,OAAO,IAAI,EAAE,CAAA;IACvB,IAAM1S,MAAM,GAAG,EAAE,CAAA;IAEjB,SAAS2S,cAAcA,CAACzU,MAAM,EAAED,MAAM,EAAE7D,IAAI,EAAEvB,QAAQ,EAAE;EACtD,IAAA,IAAIwH,OAAK,CAACxK,aAAa,CAACqI,MAAM,CAAC,IAAImC,OAAK,CAACxK,aAAa,CAACoI,MAAM,CAAC,EAAE;EAC9D,MAAA,OAAOoC,OAAK,CAAC1H,KAAK,CAACvE,IAAI,CAAC;EAACyE,QAAAA,QAAQ,EAARA,QAAAA;EAAQ,OAAC,EAAEqF,MAAM,EAAED,MAAM,CAAC,CAAA;OACpD,MAAM,IAAIoC,OAAK,CAACxK,aAAa,CAACoI,MAAM,CAAC,EAAE;QACtC,OAAOoC,OAAK,CAAC1H,KAAK,CAAC,EAAE,EAAEsF,MAAM,CAAC,CAAA;OAC/B,MAAM,IAAIoC,OAAK,CAACzL,OAAO,CAACqJ,MAAM,CAAC,EAAE;EAChC,MAAA,OAAOA,MAAM,CAAC5J,KAAK,EAAE,CAAA;EACvB,KAAA;EACA,IAAA,OAAO4J,MAAM,CAAA;EACf,GAAA;;EAEA;IACA,SAAS2U,mBAAmBA,CAAC1Z,CAAC,EAAEC,CAAC,EAAEiB,IAAI,EAAGvB,QAAQ,EAAE;EAClD,IAAA,IAAI,CAACwH,OAAK,CAACvL,WAAW,CAACqE,CAAC,CAAC,EAAE;QACzB,OAAOwZ,cAAc,CAACzZ,CAAC,EAAEC,CAAC,EAAEiB,IAAI,EAAGvB,QAAQ,CAAC,CAAA;OAC7C,MAAM,IAAI,CAACwH,OAAK,CAACvL,WAAW,CAACoE,CAAC,CAAC,EAAE;QAChC,OAAOyZ,cAAc,CAACjb,SAAS,EAAEwB,CAAC,EAAEkB,IAAI,EAAGvB,QAAQ,CAAC,CAAA;EACtD,KAAA;EACF,GAAA;;EAEA;EACA,EAAA,SAASga,gBAAgBA,CAAC3Z,CAAC,EAAEC,CAAC,EAAE;EAC9B,IAAA,IAAI,CAACkH,OAAK,CAACvL,WAAW,CAACqE,CAAC,CAAC,EAAE;EACzB,MAAA,OAAOwZ,cAAc,CAACjb,SAAS,EAAEyB,CAAC,CAAC,CAAA;EACrC,KAAA;EACF,GAAA;;EAEA;EACA,EAAA,SAAS2Z,gBAAgBA,CAAC5Z,CAAC,EAAEC,CAAC,EAAE;EAC9B,IAAA,IAAI,CAACkH,OAAK,CAACvL,WAAW,CAACqE,CAAC,CAAC,EAAE;EACzB,MAAA,OAAOwZ,cAAc,CAACjb,SAAS,EAAEyB,CAAC,CAAC,CAAA;OACpC,MAAM,IAAI,CAACkH,OAAK,CAACvL,WAAW,CAACoE,CAAC,CAAC,EAAE;EAChC,MAAA,OAAOyZ,cAAc,CAACjb,SAAS,EAAEwB,CAAC,CAAC,CAAA;EACrC,KAAA;EACF,GAAA;;EAEA;EACA,EAAA,SAAS6Z,eAAeA,CAAC7Z,CAAC,EAAEC,CAAC,EAAEiB,IAAI,EAAE;MACnC,IAAIA,IAAI,IAAIsY,OAAO,EAAE;EACnB,MAAA,OAAOC,cAAc,CAACzZ,CAAC,EAAEC,CAAC,CAAC,CAAA;EAC7B,KAAC,MAAM,IAAIiB,IAAI,IAAIqY,OAAO,EAAE;EAC1B,MAAA,OAAOE,cAAc,CAACjb,SAAS,EAAEwB,CAAC,CAAC,CAAA;EACrC,KAAA;EACF,GAAA;EAEA,EAAA,IAAM8Z,QAAQ,GAAG;EACfhP,IAAAA,GAAG,EAAE6O,gBAAgB;EACrB5J,IAAAA,MAAM,EAAE4J,gBAAgB;EACxB9T,IAAAA,IAAI,EAAE8T,gBAAgB;EACtBZ,IAAAA,OAAO,EAAEa,gBAAgB;EACzBpL,IAAAA,gBAAgB,EAAEoL,gBAAgB;EAClC1K,IAAAA,iBAAiB,EAAE0K,gBAAgB;EACnCG,IAAAA,gBAAgB,EAAEH,gBAAgB;EAClCpK,IAAAA,OAAO,EAAEoK,gBAAgB;EACzBI,IAAAA,cAAc,EAAEJ,gBAAgB;EAChCK,IAAAA,eAAe,EAAEL,gBAAgB;EACjCM,IAAAA,aAAa,EAAEN,gBAAgB;EAC/BrL,IAAAA,OAAO,EAAEqL,gBAAgB;EACzBxK,IAAAA,YAAY,EAAEwK,gBAAgB;EAC9BnK,IAAAA,cAAc,EAAEmK,gBAAgB;EAChClK,IAAAA,cAAc,EAAEkK,gBAAgB;EAChCO,IAAAA,gBAAgB,EAAEP,gBAAgB;EAClCQ,IAAAA,kBAAkB,EAAER,gBAAgB;EACpCS,IAAAA,UAAU,EAAET,gBAAgB;EAC5BjK,IAAAA,gBAAgB,EAAEiK,gBAAgB;EAClChK,IAAAA,aAAa,EAAEgK,gBAAgB;EAC/BU,IAAAA,cAAc,EAAEV,gBAAgB;EAChCW,IAAAA,SAAS,EAAEX,gBAAgB;EAC3BY,IAAAA,SAAS,EAAEZ,gBAAgB;EAC3Ba,IAAAA,UAAU,EAAEb,gBAAgB;EAC5Bc,IAAAA,WAAW,EAAEd,gBAAgB;EAC7Be,IAAAA,UAAU,EAAEf,gBAAgB;EAC5BgB,IAAAA,gBAAgB,EAAEhB,gBAAgB;EAClC/J,IAAAA,cAAc,EAAEgK,eAAe;EAC/BpL,IAAAA,OAAO,EAAE,SAAAA,OAAAA,CAACzO,CAAC,EAAEC,CAAC,EAAGiB,IAAI,EAAA;EAAA,MAAA,OAAKwY,mBAAmB,CAACL,eAAe,CAACrZ,CAAC,CAAC,EAAEqZ,eAAe,CAACpZ,CAAC,CAAC,EAACiB,IAAI,EAAE,IAAI,CAAC,CAAA;EAAA,KAAA;KACjG,CAAA;IAEDiG,OAAK,CAAC9I,OAAO,CAAC7D,MAAM,CAACqC,IAAI,CAAAuQ,cAAA,CAAAA,cAAA,KAAKmM,OAAO,CAAA,EAAKC,OAAO,CAAC,CAAC,EAAE,SAASqB,kBAAkBA,CAAC3Z,IAAI,EAAE;EACrF,IAAA,IAAMzB,KAAK,GAAGqa,QAAQ,CAAC5Y,IAAI,CAAC,IAAIwY,mBAAmB,CAAA;EACnD,IAAA,IAAMoB,WAAW,GAAGrb,KAAK,CAAC8Z,OAAO,CAACrY,IAAI,CAAC,EAAEsY,OAAO,CAACtY,IAAI,CAAC,EAAEA,IAAI,CAAC,CAAA;EAC5DiG,IAAAA,OAAK,CAACvL,WAAW,CAACkf,WAAW,CAAC,IAAIrb,KAAK,KAAKoa,eAAe,KAAM/S,MAAM,CAAC5F,IAAI,CAAC,GAAG4Z,WAAW,CAAC,CAAA;EAC/F,GAAC,CAAC,CAAA;EAEF,EAAA,OAAOhU,MAAM,CAAA;EACf;;AChGA,sBAAe,CAAA,UAACA,MAAM,EAAK;IACzB,IAAMiU,SAAS,GAAGzB,WAAW,CAAC,EAAE,EAAExS,MAAM,CAAC,CAAA;EAEzC,EAAA,IAAMjB,IAAI,GAAmEkV,SAAS,CAAhFlV,IAAI;MAAEqU,aAAa,GAAoDa,SAAS,CAA1Eb,aAAa;MAAExK,cAAc,GAAoCqL,SAAS,CAA3DrL,cAAc;MAAED,cAAc,GAAoBsL,SAAS,CAA3CtL,cAAc;MAAEhB,OAAO,GAAWsM,SAAS,CAA3BtM,OAAO;MAAEuM,IAAI,GAAKD,SAAS,CAAlBC,IAAI,CAAA;IAExED,SAAS,CAACtM,OAAO,GAAGA,OAAO,GAAG+C,cAAY,CAAC9J,IAAI,CAAC+G,OAAO,CAAC,CAAA;IAExDsM,SAAS,CAACjQ,GAAG,GAAGD,QAAQ,CAACoO,aAAa,CAAC8B,SAAS,CAAChC,OAAO,EAAEgC,SAAS,CAACjQ,GAAG,EAAEiQ,SAAS,CAAC5B,iBAAiB,CAAC,EAAErS,MAAM,CAAC2D,MAAM,EAAE3D,MAAM,CAACiT,gBAAgB,CAAC,CAAA;;EAE9I;EACA,EAAA,IAAIiB,IAAI,EAAE;EACRvM,IAAAA,OAAO,CAAC1K,GAAG,CAAC,eAAe,EAAE,QAAQ,GACnCkX,IAAI,CAAC,CAACD,IAAI,CAACE,QAAQ,IAAI,EAAE,IAAI,GAAG,IAAIF,IAAI,CAACG,QAAQ,GAAGC,QAAQ,CAAC9Q,kBAAkB,CAAC0Q,IAAI,CAACG,QAAQ,CAAC,CAAC,GAAG,EAAE,CAAC,CACvG,CAAC,CAAA;EACH,GAAA;EAEA,EAAA,IAAIhU,OAAK,CAAC7J,UAAU,CAACuI,IAAI,CAAC,EAAE;EAC1B,IAAA,IAAIwH,QAAQ,CAACT,qBAAqB,IAAIS,QAAQ,CAACP,8BAA8B,EAAE;EAC7E2B,MAAAA,OAAO,CAACK,cAAc,CAACtQ,SAAS,CAAC,CAAC;OACnC,MAAM,IAAI2I,OAAK,CAACnL,UAAU,CAAC6J,IAAI,CAACwV,UAAU,CAAC,EAAE;EAC5C;EACA,MAAA,IAAMC,WAAW,GAAGzV,IAAI,CAACwV,UAAU,EAAE,CAAA;EACrC;EACA,MAAA,IAAME,cAAc,GAAG,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAA;QACzD/gB,MAAM,CAACuT,OAAO,CAACuN,WAAW,CAAC,CAACjd,OAAO,CAAC,UAAAE,IAAA,EAAgB;EAAA,QAAA,IAAAmB,KAAA,GAAA5B,cAAA,CAAAS,IAAA,EAAA,CAAA,CAAA;EAAdQ,UAAAA,GAAG,GAAAW,KAAA,CAAA,CAAA,CAAA;EAAE5D,UAAAA,GAAG,GAAA4D,KAAA,CAAA,CAAA,CAAA,CAAA;UAC5C,IAAI6b,cAAc,CAACC,QAAQ,CAACzc,GAAG,CAAC3D,WAAW,EAAE,CAAC,EAAE;EAC9CqT,UAAAA,OAAO,CAAC1K,GAAG,CAAChF,GAAG,EAAEjD,GAAG,CAAC,CAAA;EACvB,SAAA;EACF,OAAC,CAAC,CAAA;EACJ,KAAA;EACF,GAAA;;EAEA;EACA;EACA;;IAEA,IAAIuR,QAAQ,CAACT,qBAAqB,EAAE;EAClCsN,IAAAA,aAAa,IAAI/S,OAAK,CAACnL,UAAU,CAACke,aAAa,CAAC,KAAKA,aAAa,GAAGA,aAAa,CAACa,SAAS,CAAC,CAAC,CAAA;EAE9F,IAAA,IAAIb,aAAa,IAAKA,aAAa,KAAK,KAAK,IAAIuB,eAAe,CAACV,SAAS,CAACjQ,GAAG,CAAE,EAAE;EAChF;QACA,IAAM4Q,SAAS,GAAGhM,cAAc,IAAID,cAAc,IAAIkM,OAAO,CAAClD,IAAI,CAAChJ,cAAc,CAAC,CAAA;EAElF,MAAA,IAAIiM,SAAS,EAAE;EACbjN,QAAAA,OAAO,CAAC1K,GAAG,CAAC2L,cAAc,EAAEgM,SAAS,CAAC,CAAA;EACxC,OAAA;EACF,KAAA;EACF,GAAA;EAEA,EAAA,OAAOX,SAAS,CAAA;EAClB,CAAC;;EChDD,IAAMa,qBAAqB,GAAG,OAAOC,cAAc,KAAK,WAAW,CAAA;AAEnE,mBAAeD,qBAAqB,IAAI,UAAU9U,MAAM,EAAE;IACxD,OAAO,IAAIgV,OAAO,CAAC,SAASC,kBAAkBA,CAAClH,OAAO,EAAEC,MAAM,EAAE;EAC9D,IAAA,IAAMkH,OAAO,GAAGC,aAAa,CAACnV,MAAM,CAAC,CAAA;EACrC,IAAA,IAAIoV,WAAW,GAAGF,OAAO,CAACnW,IAAI,CAAA;EAC9B,IAAA,IAAMsW,cAAc,GAAG3K,cAAY,CAAC9J,IAAI,CAACsU,OAAO,CAACvN,OAAO,CAAC,CAAC0E,SAAS,EAAE,CAAA;EACrE,IAAA,IAAK/D,YAAY,GAA0C4M,OAAO,CAA7D5M,YAAY;QAAE+K,gBAAgB,GAAwB6B,OAAO,CAA/C7B,gBAAgB;QAAEC,kBAAkB,GAAI4B,OAAO,CAA7B5B,kBAAkB,CAAA;EACvD,IAAA,IAAIgC,UAAU,CAAA;MACd,IAAIC,eAAe,EAAEC,iBAAiB,CAAA;MACtC,IAAIC,WAAW,EAAEC,aAAa,CAAA;MAE9B,SAASra,IAAIA,GAAG;EACdoa,MAAAA,WAAW,IAAIA,WAAW,EAAE,CAAC;EAC7BC,MAAAA,aAAa,IAAIA,aAAa,EAAE,CAAC;;QAEjCR,OAAO,CAACtB,WAAW,IAAIsB,OAAO,CAACtB,WAAW,CAAC+B,WAAW,CAACL,UAAU,CAAC,CAAA;EAElEJ,MAAAA,OAAO,CAACU,MAAM,IAAIV,OAAO,CAACU,MAAM,CAACC,mBAAmB,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAA;EAC3E,KAAA;EAEA,IAAA,IAAIrV,OAAO,GAAG,IAAI8U,cAAc,EAAE,CAAA;EAElC9U,IAAAA,OAAO,CAAC6V,IAAI,CAACZ,OAAO,CAACjM,MAAM,CAAC/M,WAAW,EAAE,EAAEgZ,OAAO,CAAClR,GAAG,EAAE,IAAI,CAAC,CAAA;;EAE7D;EACA/D,IAAAA,OAAO,CAACyI,OAAO,GAAGwM,OAAO,CAACxM,OAAO,CAAA;MAEjC,SAASqN,SAASA,GAAG;QACnB,IAAI,CAAC9V,OAAO,EAAE;EACZ,QAAA,OAAA;EACF,OAAA;EACA;EACA,MAAA,IAAM+V,eAAe,GAAGtL,cAAY,CAAC9J,IAAI,CACvC,uBAAuB,IAAIX,OAAO,IAAIA,OAAO,CAACgW,qBAAqB,EACrE,CAAC,CAAA;EACD,MAAA,IAAMC,YAAY,GAAG,CAAC5N,YAAY,IAAIA,YAAY,KAAK,MAAM,IAAIA,YAAY,KAAK,MAAM,GACtFrI,OAAO,CAACkW,YAAY,GAAGlW,OAAO,CAACC,QAAQ,CAAA;EACzC,MAAA,IAAMA,QAAQ,GAAG;EACfnB,QAAAA,IAAI,EAAEmX,YAAY;UAClB9V,MAAM,EAAEH,OAAO,CAACG,MAAM;UACtBgW,UAAU,EAAEnW,OAAO,CAACmW,UAAU;EAC9BzO,QAAAA,OAAO,EAAEqO,eAAe;EACxBhW,QAAAA,MAAM,EAANA,MAAM;EACNC,QAAAA,OAAO,EAAPA,OAAAA;SACD,CAAA;EAED6N,MAAAA,MAAM,CAAC,SAASuI,QAAQA,CAACxc,KAAK,EAAE;UAC9BkU,OAAO,CAAClU,KAAK,CAAC,CAAA;EACdwB,QAAAA,IAAI,EAAE,CAAA;EACR,OAAC,EAAE,SAASib,OAAOA,CAACzK,GAAG,EAAE;UACvBmC,MAAM,CAACnC,GAAG,CAAC,CAAA;EACXxQ,QAAAA,IAAI,EAAE,CAAA;SACP,EAAE6E,QAAQ,CAAC,CAAA;;EAEZ;EACAD,MAAAA,OAAO,GAAG,IAAI,CAAA;EAChB,KAAA;MAEA,IAAI,WAAW,IAAIA,OAAO,EAAE;EAC1B;QACAA,OAAO,CAAC8V,SAAS,GAAGA,SAAS,CAAA;EAC/B,KAAC,MAAM;EACL;EACA9V,MAAAA,OAAO,CAACsW,kBAAkB,GAAG,SAASC,UAAUA,GAAG;UACjD,IAAI,CAACvW,OAAO,IAAIA,OAAO,CAACwW,UAAU,KAAK,CAAC,EAAE;EACxC,UAAA,OAAA;EACF,SAAA;;EAEA;EACA;EACA;EACA;UACA,IAAIxW,OAAO,CAACG,MAAM,KAAK,CAAC,IAAI,EAAEH,OAAO,CAACyW,WAAW,IAAIzW,OAAO,CAACyW,WAAW,CAAC/b,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE;EAChG,UAAA,OAAA;EACF,SAAA;EACA;EACA;UACA2E,UAAU,CAACyW,SAAS,CAAC,CAAA;SACtB,CAAA;EACH,KAAA;;EAEA;EACA9V,IAAAA,OAAO,CAAC0W,OAAO,GAAG,SAASC,WAAWA,GAAG;QACvC,IAAI,CAAC3W,OAAO,EAAE;EACZ,QAAA,OAAA;EACF,OAAA;EAEA+N,MAAAA,MAAM,CAAC,IAAInO,UAAU,CAAC,iBAAiB,EAAEA,UAAU,CAACgX,YAAY,EAAE7W,MAAM,EAAEC,OAAO,CAAC,CAAC,CAAA;;EAEnF;EACAA,MAAAA,OAAO,GAAG,IAAI,CAAA;OACf,CAAA;;EAED;EACFA,IAAAA,OAAO,CAAC6W,OAAO,GAAG,SAASC,WAAWA,CAACnG,KAAK,EAAE;EACzC;EACA;EACA;EACA,MAAA,IAAM5P,GAAG,GAAG4P,KAAK,IAAIA,KAAK,CAAC9Q,OAAO,GAAG8Q,KAAK,CAAC9Q,OAAO,GAAG,eAAe,CAAA;EACpE,MAAA,IAAM+L,GAAG,GAAG,IAAIhM,UAAU,CAACmB,GAAG,EAAEnB,UAAU,CAACmX,WAAW,EAAEhX,MAAM,EAAEC,OAAO,CAAC,CAAA;EACxE;EACA4L,MAAAA,GAAG,CAAC+E,KAAK,GAAGA,KAAK,IAAI,IAAI,CAAA;QACzB5C,MAAM,CAACnC,GAAG,CAAC,CAAA;EACX5L,MAAAA,OAAO,GAAG,IAAI,CAAA;OAChB,CAAA;;EAED;EACAA,IAAAA,OAAO,CAACgX,SAAS,GAAG,SAASC,aAAaA,GAAG;EAC3C,MAAA,IAAIC,mBAAmB,GAAGjC,OAAO,CAACxM,OAAO,GAAG,aAAa,GAAGwM,OAAO,CAACxM,OAAO,GAAG,aAAa,GAAG,kBAAkB,CAAA;EAChH,MAAA,IAAMnB,YAAY,GAAG2N,OAAO,CAAC3N,YAAY,IAAIC,oBAAoB,CAAA;QACjE,IAAI0N,OAAO,CAACiC,mBAAmB,EAAE;UAC/BA,mBAAmB,GAAGjC,OAAO,CAACiC,mBAAmB,CAAA;EACnD,OAAA;QACAnJ,MAAM,CAAC,IAAInO,UAAU,CACnBsX,mBAAmB,EACnB5P,YAAY,CAAClC,mBAAmB,GAAGxF,UAAU,CAACuX,SAAS,GAAGvX,UAAU,CAACgX,YAAY,EACjF7W,MAAM,EACNC,OAAO,CAAC,CAAC,CAAA;;EAEX;EACAA,MAAAA,OAAO,GAAG,IAAI,CAAA;OACf,CAAA;;EAED;MACAmV,WAAW,KAAK1d,SAAS,IAAI2d,cAAc,CAACrN,cAAc,CAAC,IAAI,CAAC,CAAA;;EAEhE;MACA,IAAI,kBAAkB,IAAI/H,OAAO,EAAE;EACjCI,MAAAA,OAAK,CAAC9I,OAAO,CAAC8d,cAAc,CAAC/U,MAAM,EAAE,EAAE,SAAS+W,gBAAgBA,CAACriB,GAAG,EAAEiD,GAAG,EAAE;EACzEgI,QAAAA,OAAO,CAACoX,gBAAgB,CAACpf,GAAG,EAAEjD,GAAG,CAAC,CAAA;EACpC,OAAC,CAAC,CAAA;EACJ,KAAA;;EAEA;MACA,IAAI,CAACqL,OAAK,CAACvL,WAAW,CAACogB,OAAO,CAAC/B,eAAe,CAAC,EAAE;EAC/ClT,MAAAA,OAAO,CAACkT,eAAe,GAAG,CAAC,CAAC+B,OAAO,CAAC/B,eAAe,CAAA;EACrD,KAAA;;EAEA;EACA,IAAA,IAAI7K,YAAY,IAAIA,YAAY,KAAK,MAAM,EAAE;EAC3CrI,MAAAA,OAAO,CAACqI,YAAY,GAAG4M,OAAO,CAAC5M,YAAY,CAAA;EAC7C,KAAA;;EAEA;EACA,IAAA,IAAIgL,kBAAkB,EAAE;EAAA,MAAA,IAAAgE,qBAAA,GACgBxH,oBAAoB,CAACwD,kBAAkB,EAAE,IAAI,CAAC,CAAA;EAAA,MAAA,IAAAiE,sBAAA,GAAAvgB,cAAA,CAAAsgB,qBAAA,EAAA,CAAA,CAAA,CAAA;EAAlF9B,MAAAA,iBAAiB,GAAA+B,sBAAA,CAAA,CAAA,CAAA,CAAA;EAAE7B,MAAAA,aAAa,GAAA6B,sBAAA,CAAA,CAAA,CAAA,CAAA;EAClCtX,MAAAA,OAAO,CAACpB,gBAAgB,CAAC,UAAU,EAAE2W,iBAAiB,CAAC,CAAA;EACzD,KAAA;;EAEA;EACA,IAAA,IAAInC,gBAAgB,IAAIpT,OAAO,CAACuX,MAAM,EAAE;EAAA,MAAA,IAAAC,sBAAA,GACJ3H,oBAAoB,CAACuD,gBAAgB,CAAC,CAAA;EAAA,MAAA,IAAAqE,sBAAA,GAAA1gB,cAAA,CAAAygB,sBAAA,EAAA,CAAA,CAAA,CAAA;EAAtElC,MAAAA,eAAe,GAAAmC,sBAAA,CAAA,CAAA,CAAA,CAAA;EAAEjC,MAAAA,WAAW,GAAAiC,sBAAA,CAAA,CAAA,CAAA,CAAA;QAE9BzX,OAAO,CAACuX,MAAM,CAAC3Y,gBAAgB,CAAC,UAAU,EAAE0W,eAAe,CAAC,CAAA;QAE5DtV,OAAO,CAACuX,MAAM,CAAC3Y,gBAAgB,CAAC,SAAS,EAAE4W,WAAW,CAAC,CAAA;EACzD,KAAA;EAEA,IAAA,IAAIP,OAAO,CAACtB,WAAW,IAAIsB,OAAO,CAACU,MAAM,EAAE;EACzC;EACA;EACAN,MAAAA,UAAU,GAAG,SAAAA,UAAAqC,CAAAA,MAAM,EAAI;UACrB,IAAI,CAAC1X,OAAO,EAAE;EACZ,UAAA,OAAA;EACF,SAAA;EACA+N,QAAAA,MAAM,CAAC,CAAC2J,MAAM,IAAIA,MAAM,CAACljB,IAAI,GAAG,IAAImZ,aAAa,CAAC,IAAI,EAAE5N,MAAM,EAAEC,OAAO,CAAC,GAAG0X,MAAM,CAAC,CAAA;UAClF1X,OAAO,CAAC2X,KAAK,EAAE,CAAA;EACf3X,QAAAA,OAAO,GAAG,IAAI,CAAA;SACf,CAAA;QAEDiV,OAAO,CAACtB,WAAW,IAAIsB,OAAO,CAACtB,WAAW,CAACiE,SAAS,CAACvC,UAAU,CAAC,CAAA;QAChE,IAAIJ,OAAO,CAACU,MAAM,EAAE;EAClBV,QAAAA,OAAO,CAACU,MAAM,CAACkC,OAAO,GAAGxC,UAAU,EAAE,GAAGJ,OAAO,CAACU,MAAM,CAAC/W,gBAAgB,CAAC,OAAO,EAAEyW,UAAU,CAAC,CAAA;EAC9F,OAAA;EACF,KAAA;EAEA,IAAA,IAAMrE,QAAQ,GAAG9C,aAAa,CAAC+G,OAAO,CAAClR,GAAG,CAAC,CAAA;EAE3C,IAAA,IAAIiN,QAAQ,IAAI1K,QAAQ,CAACd,SAAS,CAAC9K,OAAO,CAACsW,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE;EAC3DjD,MAAAA,MAAM,CAAC,IAAInO,UAAU,CAAC,uBAAuB,GAAGoR,QAAQ,GAAG,GAAG,EAAEpR,UAAU,CAACoO,eAAe,EAAEjO,MAAM,CAAC,CAAC,CAAA;EACpG,MAAA,OAAA;EACF,KAAA;;EAGA;EACAC,IAAAA,OAAO,CAAC8X,IAAI,CAAC3C,WAAW,IAAI,IAAI,CAAC,CAAA;EACnC,GAAC,CAAC,CAAA;EACJ,CAAC;;ECnMD,IAAM4C,cAAc,GAAG,SAAjBA,cAAcA,CAAIC,OAAO,EAAEvP,OAAO,EAAK;EAC3C,EAAA,IAAAwP,QAAA,GAAkBD,OAAO,GAAGA,OAAO,GAAGA,OAAO,CAAC/d,MAAM,CAACie,OAAO,CAAC,GAAG,EAAE;MAA3DniB,MAAM,GAAAkiB,QAAA,CAANliB,MAAM,CAAA;IAEb,IAAI0S,OAAO,IAAI1S,MAAM,EAAE;EACrB,IAAA,IAAIoiB,UAAU,GAAG,IAAIC,eAAe,EAAE,CAAA;EAEtC,IAAA,IAAIP,OAAO,CAAA;EAEX,IAAA,IAAMnB,OAAO,GAAG,SAAVA,OAAOA,CAAa2B,MAAM,EAAE;QAChC,IAAI,CAACR,OAAO,EAAE;EACZA,QAAAA,OAAO,GAAG,IAAI,CAAA;EACdnC,QAAAA,WAAW,EAAE,CAAA;UACb,IAAM9J,GAAG,GAAGyM,MAAM,YAAYpb,KAAK,GAAGob,MAAM,GAAG,IAAI,CAACA,MAAM,CAAA;UAC1DF,UAAU,CAACR,KAAK,CAAC/L,GAAG,YAAYhM,UAAU,GAAGgM,GAAG,GAAG,IAAI+B,aAAa,CAAC/B,GAAG,YAAY3O,KAAK,GAAG2O,GAAG,CAAC/L,OAAO,GAAG+L,GAAG,CAAC,CAAC,CAAA;EACjH,OAAA;OACD,CAAA;EAED,IAAA,IAAI2D,KAAK,GAAG9G,OAAO,IAAIpJ,UAAU,CAAC,YAAM;EACtCkQ,MAAAA,KAAK,GAAG,IAAI,CAAA;EACZmH,MAAAA,OAAO,CAAC,IAAI9W,UAAU,CAAA,UAAA,CAAAV,MAAA,CAAYuJ,OAAO,EAAA,iBAAA,CAAA,EAAmB7I,UAAU,CAACuX,SAAS,CAAC,CAAC,CAAA;OACnF,EAAE1O,OAAO,CAAC,CAAA;EAEX,IAAA,IAAMiN,WAAW,GAAG,SAAdA,WAAWA,GAAS;EACxB,MAAA,IAAIsC,OAAO,EAAE;EACXzI,QAAAA,KAAK,IAAIG,YAAY,CAACH,KAAK,CAAC,CAAA;EAC5BA,QAAAA,KAAK,GAAG,IAAI,CAAA;EACZyI,QAAAA,OAAO,CAAC1gB,OAAO,CAAC,UAAAqe,MAAM,EAAI;EACxBA,UAAAA,MAAM,CAACD,WAAW,GAAGC,MAAM,CAACD,WAAW,CAACgB,OAAO,CAAC,GAAGf,MAAM,CAACC,mBAAmB,CAAC,OAAO,EAAEc,OAAO,CAAC,CAAA;EACjG,SAAC,CAAC,CAAA;EACFsB,QAAAA,OAAO,GAAG,IAAI,CAAA;EAChB,OAAA;OACD,CAAA;EAEDA,IAAAA,OAAO,CAAC1gB,OAAO,CAAC,UAACqe,MAAM,EAAA;EAAA,MAAA,OAAKA,MAAM,CAAC/W,gBAAgB,CAAC,OAAO,EAAE8X,OAAO,CAAC,CAAA;OAAC,CAAA,CAAA;EAEtE,IAAA,IAAOf,MAAM,GAAIwC,UAAU,CAApBxC,MAAM,CAAA;MAEbA,MAAM,CAACD,WAAW,GAAG,YAAA;EAAA,MAAA,OAAMtV,OAAK,CAACd,IAAI,CAACoW,WAAW,CAAC,CAAA;EAAA,KAAA,CAAA;EAElD,IAAA,OAAOC,MAAM,CAAA;EACf,GAAA;EACF,CAAC,CAAA;AAED,yBAAeoC,cAAc;;EC9CtB,IAAMO,WAAW,gBAAAC,mBAAA,EAAAC,CAAAA,IAAA,CAAG,SAAdF,WAAWA,CAAcG,KAAK,EAAEC,SAAS,EAAA;EAAA,EAAA,IAAA3gB,GAAA,EAAA4gB,GAAA,EAAAC,GAAA,CAAA;EAAA,EAAA,OAAAL,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAwlB,aAAAC,QAAA,EAAA;EAAA,IAAA,OAAA,CAAA,EAAA,QAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAA3d,IAAA;EAAA,MAAA,KAAA,CAAA;UAChDpD,GAAG,GAAG0gB,KAAK,CAACO,UAAU,CAAA;EAAA,QAAA,IAAA,EAEtB,CAACN,SAAS,IAAI3gB,GAAG,GAAG2gB,SAAS,CAAA,EAAA;EAAAI,UAAAA,QAAA,CAAA3d,IAAA,GAAA,CAAA,CAAA;EAAA,UAAA,MAAA;EAAA,SAAA;EAAA2d,QAAAA,QAAA,CAAA3d,IAAA,GAAA,CAAA,CAAA;EAC/B,QAAA,OAAMsd,KAAK,CAAA;EAAA,MAAA,KAAA,CAAA;UAAA,OAAAK,QAAA,CAAAG,MAAA,CAAA,QAAA,CAAA,CAAA;EAAA,MAAA,KAAA,CAAA;EAITN,QAAAA,GAAG,GAAG,CAAC,CAAA;EAAA,MAAA,KAAA,CAAA;UAAA,IAGJA,EAAAA,GAAG,GAAG5gB,GAAG,CAAA,EAAA;EAAA+gB,UAAAA,QAAA,CAAA3d,IAAA,GAAA,EAAA,CAAA;EAAA,UAAA,MAAA;EAAA,SAAA;UACdyd,GAAG,GAAGD,GAAG,GAAGD,SAAS,CAAA;EAACI,QAAAA,QAAA,CAAA3d,IAAA,GAAA,EAAA,CAAA;EACtB,QAAA,OAAMsd,KAAK,CAACrkB,KAAK,CAACukB,GAAG,EAAEC,GAAG,CAAC,CAAA;EAAA,MAAA,KAAA,EAAA;EAC3BD,QAAAA,GAAG,GAAGC,GAAG,CAAA;EAACE,QAAAA,QAAA,CAAA3d,IAAA,GAAA,CAAA,CAAA;EAAA,QAAA,MAAA;EAAA,MAAA,KAAA,EAAA,CAAA;EAAA,MAAA,KAAA,KAAA;UAAA,OAAA2d,QAAA,CAAAI,IAAA,EAAA,CAAA;EAAA,KAAA;EAAA,GAAA,EAdDZ,WAAW,CAAA,CAAA;EAAA,CAgBvB,CAAA,CAAA;EAEM,IAAMa,SAAS,gBAAA,YAAA;EAAA,EAAA,IAAA3hB,IAAA,GAAA4hB,mBAAA,eAAAb,mBAAA,EAAA,CAAAC,IAAA,CAAG,SAAAa,OAAAA,CAAiBC,QAAQ,EAAEZ,SAAS,EAAA;MAAA,IAAAa,yBAAA,EAAAC,iBAAA,EAAAC,cAAA,EAAAve,SAAA,EAAAqQ,KAAA,EAAAkN,KAAA,CAAA;EAAA,IAAA,OAAAF,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqmB,SAAAC,SAAA,EAAA;EAAA,MAAA,OAAA,CAAA,EAAA,QAAAA,SAAA,CAAAZ,IAAA,GAAAY,SAAA,CAAAxe,IAAA;EAAA,QAAA,KAAA,CAAA;YAAAoe,yBAAA,GAAA,KAAA,CAAA;YAAAC,iBAAA,GAAA,KAAA,CAAA;EAAAG,UAAAA,SAAA,CAAAZ,IAAA,GAAA,CAAA,CAAA;EAAA7d,UAAAA,SAAA,GAAA0e,cAAA,CACjCC,UAAU,CAACP,QAAQ,CAAC,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;EAAAK,UAAAA,SAAA,CAAAxe,IAAA,GAAA,CAAA,CAAA;EAAA,UAAA,OAAA2e,oBAAA,CAAA5e,SAAA,CAAAC,IAAA,EAAA,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;YAAA,IAAAoe,EAAAA,yBAAA,KAAAhO,KAAA,GAAAoO,SAAA,CAAAI,IAAA,EAAA3e,IAAA,CAAA,EAAA;EAAAue,YAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,MAAA;EAAA,WAAA;YAA7Bsd,KAAK,GAAAlN,KAAA,CAAA3R,KAAA,CAAA;EACpB,UAAA,OAAA+f,SAAA,CAAAK,aAAA,CAAAC,uBAAA,CAAAL,cAAA,CAAOtB,WAAW,CAACG,KAAK,EAAEC,SAAS,CAAC,CAAA,CAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;YAAAa,yBAAA,GAAA,KAAA,CAAA;EAAAI,UAAAA,SAAA,CAAAxe,IAAA,GAAA,CAAA,CAAA;EAAA,UAAA,MAAA;EAAA,QAAA,KAAA,EAAA;EAAAwe,UAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;EAAA,UAAA,MAAA;EAAA,QAAA,KAAA,EAAA;EAAAwe,UAAAA,SAAA,CAAAZ,IAAA,GAAA,EAAA,CAAA;YAAAY,SAAA,CAAAO,EAAA,GAAAP,SAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA;YAAAH,iBAAA,GAAA,IAAA,CAAA;YAAAC,cAAA,GAAAE,SAAA,CAAAO,EAAA,CAAA;EAAA,QAAA,KAAA,EAAA;EAAAP,UAAAA,SAAA,CAAAZ,IAAA,GAAA,EAAA,CAAA;EAAAY,UAAAA,SAAA,CAAAZ,IAAA,GAAA,EAAA,CAAA;YAAA,IAAAQ,EAAAA,yBAAA,IAAAre,SAAA,CAAA,QAAA,CAAA,IAAA,IAAA,CAAA,EAAA;EAAAye,YAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,MAAA;EAAA,WAAA;EAAAwe,UAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;YAAA,OAAA2e,oBAAA,CAAA5e,SAAA,CAAA,QAAA,CAAA,EAAA,CAAA,CAAA;EAAA,QAAA,KAAA,EAAA;EAAAye,UAAAA,SAAA,CAAAZ,IAAA,GAAA,EAAA,CAAA;EAAA,UAAA,IAAA,CAAAS,iBAAA,EAAA;EAAAG,YAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,MAAA;EAAA,WAAA;EAAA,UAAA,MAAAse,cAAA,CAAA;EAAA,QAAA,KAAA,EAAA;YAAA,OAAAE,SAAA,CAAAQ,MAAA,CAAA,EAAA,CAAA,CAAA;EAAA,QAAA,KAAA,EAAA;YAAA,OAAAR,SAAA,CAAAQ,MAAA,CAAA,EAAA,CAAA,CAAA;EAAA,QAAA,KAAA,EAAA,CAAA;EAAA,QAAA,KAAA,KAAA;YAAA,OAAAR,SAAA,CAAAT,IAAA,EAAA,CAAA;EAAA,OAAA;EAAA,KAAA,EAAAG,OAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,CAAA,EAAA,CAAA,EAAA,GAAA,EAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;KAEvC,CAAA,CAAA,CAAA;EAAA,EAAA,OAAA,SAJYF,SAASA,CAAAiB,EAAA,EAAAC,GAAA,EAAA;EAAA,IAAA,OAAA7iB,IAAA,CAAAlE,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,GAAA,CAAA;EAAA,CAIrB,EAAA,CAAA;EAED,IAAMsmB,UAAU,gBAAA,YAAA;IAAA,IAAAlhB,KAAA,GAAAygB,mBAAA,eAAAb,mBAAA,GAAAC,IAAA,CAAG,SAAA8B,QAAAA,CAAiBC,MAAM,EAAA;EAAA,IAAA,IAAAC,MAAA,EAAAC,qBAAA,EAAArf,IAAA,EAAAxB,KAAA,CAAA;EAAA,IAAA,OAAA2e,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqnB,UAAAC,SAAA,EAAA;EAAA,MAAA,OAAA,CAAA,EAAA,QAAAA,SAAA,CAAA5B,IAAA,GAAA4B,SAAA,CAAAxf,IAAA;EAAA,QAAA,KAAA,CAAA;EAAA,UAAA,IAAA,CACpCof,MAAM,CAAC1mB,MAAM,CAAC+mB,aAAa,CAAC,EAAA;EAAAD,YAAAA,SAAA,CAAAxf,IAAA,GAAA,CAAA,CAAA;EAAA,YAAA,MAAA;EAAA,WAAA;YAC9B,OAAAwf,SAAA,CAAAX,aAAA,CAAAC,uBAAA,CAAAL,cAAA,CAAOW,MAAM,CAAA,CAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;YAAA,OAAAI,SAAA,CAAA1B,MAAA,CAAA,QAAA,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;EAITuB,UAAAA,MAAM,GAAGD,MAAM,CAACM,SAAS,EAAE,CAAA;EAAAF,UAAAA,SAAA,CAAA5B,IAAA,GAAA,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;EAAA4B,UAAAA,SAAA,CAAAxf,IAAA,GAAA,CAAA,CAAA;EAAA,UAAA,OAAA2e,oBAAA,CAGDU,MAAM,CAAC9I,IAAI,EAAE,CAAA,CAAA;EAAA,QAAA,KAAA,CAAA;YAAA+I,qBAAA,GAAAE,SAAA,CAAAZ,IAAA,CAAA;YAAlC3e,IAAI,GAAAqf,qBAAA,CAAJrf,IAAI,CAAA;YAAExB,KAAK,GAAA6gB,qBAAA,CAAL7gB,KAAK,CAAA;EAAA,UAAA,IAAA,CACdwB,IAAI,EAAA;EAAAuf,YAAAA,SAAA,CAAAxf,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,MAAA;EAAA,WAAA;YAAA,OAAAwf,SAAA,CAAA1B,MAAA,CAAA,OAAA,EAAA,EAAA,CAAA,CAAA;EAAA,QAAA,KAAA,EAAA;EAAA0B,UAAAA,SAAA,CAAAxf,IAAA,GAAA,EAAA,CAAA;EAGR,UAAA,OAAMvB,KAAK,CAAA;EAAA,QAAA,KAAA,EAAA;EAAA+gB,UAAAA,SAAA,CAAAxf,IAAA,GAAA,CAAA,CAAA;EAAA,UAAA,MAAA;EAAA,QAAA,KAAA,EAAA;EAAAwf,UAAAA,SAAA,CAAA5B,IAAA,GAAA,EAAA,CAAA;EAAA4B,UAAAA,SAAA,CAAAxf,IAAA,GAAA,EAAA,CAAA;EAAA,UAAA,OAAA2e,oBAAA,CAGPU,MAAM,CAAC9C,MAAM,EAAE,CAAA,CAAA;EAAA,QAAA,KAAA,EAAA;YAAA,OAAAiD,SAAA,CAAAR,MAAA,CAAA,EAAA,CAAA,CAAA;EAAA,QAAA,KAAA,EAAA,CAAA;EAAA,QAAA,KAAA,KAAA;YAAA,OAAAQ,SAAA,CAAAzB,IAAA,EAAA,CAAA;EAAA,OAAA;EAAA,KAAA,EAAAoB,QAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,GAAA,EAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;KAExB,CAAA,CAAA,CAAA;IAAA,OAlBKT,SAAAA,UAAUA,CAAAiB,GAAA,EAAA;EAAA,IAAA,OAAAniB,KAAA,CAAArF,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,GAAA,CAAA;EAAA,CAkBf,EAAA,CAAA;EAEM,IAAMwnB,WAAW,GAAG,SAAdA,WAAWA,CAAIR,MAAM,EAAE7B,SAAS,EAAEsC,UAAU,EAAEC,QAAQ,EAAK;EACtE,EAAA,IAAMrnB,QAAQ,GAAGulB,SAAS,CAACoB,MAAM,EAAE7B,SAAS,CAAC,CAAA;IAE7C,IAAIpK,KAAK,GAAG,CAAC,CAAA;EACb,EAAA,IAAIlT,IAAI,CAAA;EACR,EAAA,IAAI8f,SAAS,GAAG,SAAZA,SAASA,CAAIllB,CAAC,EAAK;MACrB,IAAI,CAACoF,IAAI,EAAE;EACTA,MAAAA,IAAI,GAAG,IAAI,CAAA;EACX6f,MAAAA,QAAQ,IAAIA,QAAQ,CAACjlB,CAAC,CAAC,CAAA;EACzB,KAAA;KACD,CAAA;IAED,OAAO,IAAImlB,cAAc,CAAC;MAClBC,IAAI,EAAA,SAAAA,IAACjD,CAAAA,UAAU,EAAE;EAAA,MAAA,OAAAkD,iBAAA,eAAA9C,mBAAA,EAAAC,CAAAA,IAAA,UAAA8C,QAAA,GAAA;UAAA,IAAAC,oBAAA,EAAAC,KAAA,EAAA5hB,KAAA,EAAA7B,GAAA,EAAA0jB,WAAA,CAAA;EAAA,QAAA,OAAAlD,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqoB,UAAAC,SAAA,EAAA;EAAA,UAAA,OAAA,CAAA,EAAA,QAAAA,SAAA,CAAA5C,IAAA,GAAA4C,SAAA,CAAAxgB,IAAA;EAAA,YAAA,KAAA,CAAA;EAAAwgB,cAAAA,SAAA,CAAA5C,IAAA,GAAA,CAAA,CAAA;EAAA4C,cAAAA,SAAA,CAAAxgB,IAAA,GAAA,CAAA,CAAA;EAAA,cAAA,OAESvH,QAAQ,CAACuH,IAAI,EAAE,CAAA;EAAA,YAAA,KAAA,CAAA;gBAAAogB,oBAAA,GAAAI,SAAA,CAAA5B,IAAA,CAAA;gBAApC3e,KAAI,GAAAmgB,oBAAA,CAAJngB,IAAI,CAAA;gBAAExB,KAAK,GAAA2hB,oBAAA,CAAL3hB,KAAK,CAAA;EAAA,cAAA,IAAA,CAEdwB,KAAI,EAAA;EAAAugB,gBAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,gBAAA,MAAA;EAAA,eAAA;EACP+f,cAAAA,SAAS,EAAE,CAAA;gBACV/C,UAAU,CAACyD,KAAK,EAAE,CAAA;gBAAC,OAAAD,SAAA,CAAA1C,MAAA,CAAA,QAAA,CAAA,CAAA;EAAA,YAAA,KAAA,EAAA;gBAIjBlhB,GAAG,GAAG6B,KAAK,CAACof,UAAU,CAAA;EAC1B,cAAA,IAAIgC,UAAU,EAAE;kBACVS,WAAW,GAAGnN,KAAK,IAAIvW,GAAG,CAAA;kBAC9BijB,UAAU,CAACS,WAAW,CAAC,CAAA;EACzB,eAAA;gBACAtD,UAAU,CAAC0D,OAAO,CAAC,IAAI9gB,UAAU,CAACnB,KAAK,CAAC,CAAC,CAAA;EAAC+hB,cAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,cAAA,MAAA;EAAA,YAAA,KAAA,EAAA;EAAAwgB,cAAAA,SAAA,CAAA5C,IAAA,GAAA,EAAA,CAAA;gBAAA4C,SAAA,CAAAG,EAAA,GAAAH,SAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAE1CT,cAAAA,SAAS,CAAAS,SAAA,CAAAG,EAAI,CAAC,CAAA;gBAAC,MAAAH,SAAA,CAAAG,EAAA,CAAA;EAAA,YAAA,KAAA,EAAA,CAAA;EAAA,YAAA,KAAA,KAAA;gBAAA,OAAAH,SAAA,CAAAzC,IAAA,EAAA,CAAA;EAAA,WAAA;EAAA,SAAA,EAAAoC,QAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;EAAA,OAAA,CAAA,CAAA,EAAA,CAAA;OAGlB;MACD5D,MAAM,EAAA,SAAAA,MAACW,CAAAA,MAAM,EAAE;QACb6C,SAAS,CAAC7C,MAAM,CAAC,CAAA;QACjB,OAAOzkB,QAAQ,CAAO,QAAA,CAAA,EAAE,CAAA;EAC1B,KAAA;EACF,GAAC,EAAE;EACDmoB,IAAAA,aAAa,EAAE,CAAA;EACjB,GAAC,CAAC,CAAA;EACJ,CAAC;;EC5ED,IAAMC,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAA;EAEpC,IAAO/mB,UAAU,GAAImL,OAAK,CAAnBnL,UAAU,CAAA;EAEjB,IAAMgnB,cAAc,GAAI,UAAAzkB,IAAA,EAAA;EAAA,EAAA,IAAE0kB,OAAO,GAAA1kB,IAAA,CAAP0kB,OAAO;MAAEC,QAAQ,GAAA3kB,IAAA,CAAR2kB,QAAQ,CAAA;IAAA,OAAO;EAChDD,IAAAA,OAAO,EAAPA,OAAO;EAAEC,IAAAA,QAAQ,EAARA,QAAAA;KACV,CAAA;EAAA,CAAC,CAAE/b,OAAK,CAAC7H,MAAM,CAAC,CAAA;EAEjB,IAAA6jB,aAAA,GAEIhc,OAAK,CAAC7H,MAAM;IADd4iB,gBAAc,GAAAiB,aAAA,CAAdjB,cAAc;IAAEkB,WAAW,GAAAD,aAAA,CAAXC,WAAW,CAAA;EAI7B,IAAMxa,IAAI,GAAG,SAAPA,IAAIA,CAAI1O,EAAE,EAAc;IAC5B,IAAI;MAAA,KAAAqZ,IAAAA,IAAA,GAAAjZ,SAAA,CAAAwC,MAAA,EADe0Z,IAAI,OAAA7a,KAAA,CAAA4X,IAAA,GAAAA,CAAAA,GAAAA,IAAA,WAAAtU,IAAA,GAAA,CAAA,EAAAA,IAAA,GAAAsU,IAAA,EAAAtU,IAAA,EAAA,EAAA;EAAJuX,MAAAA,IAAI,CAAAvX,IAAA,GAAA3E,CAAAA,CAAAA,GAAAA,SAAA,CAAA2E,IAAA,CAAA,CAAA;EAAA,KAAA;EAErB,IAAA,OAAO,CAAC,CAAC/E,EAAE,CAAAG,KAAA,CAAA,KAAA,CAAA,EAAImc,IAAI,CAAC,CAAA;KACrB,CAAC,OAAOzZ,CAAC,EAAE;EACV,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;EACF,CAAC,CAAA;EAED,IAAMsmB,OAAO,GAAG,SAAVA,OAAOA,CAAIpU,GAAG,EAAK;EACvBA,EAAAA,GAAG,GAAG9H,OAAK,CAAC1H,KAAK,CAACvE,IAAI,CAAC;EACrB0E,IAAAA,aAAa,EAAE,IAAA;EACjB,GAAC,EAAEojB,cAAc,EAAE/T,GAAG,CAAC,CAAA;IAEvB,IAAAqU,IAAA,GAA6CrU,GAAG;MAAlCsU,QAAQ,GAAAD,IAAA,CAAfE,KAAK;MAAYP,OAAO,GAAAK,IAAA,CAAPL,OAAO;MAAEC,QAAQ,GAAAI,IAAA,CAARJ,QAAQ,CAAA;EACzC,EAAA,IAAMO,gBAAgB,GAAGF,QAAQ,GAAGvnB,UAAU,CAACunB,QAAQ,CAAC,GAAG,OAAOC,KAAK,KAAK,UAAU,CAAA;EACtF,EAAA,IAAME,kBAAkB,GAAG1nB,UAAU,CAACinB,OAAO,CAAC,CAAA;EAC9C,EAAA,IAAMU,mBAAmB,GAAG3nB,UAAU,CAACknB,QAAQ,CAAC,CAAA;IAEhD,IAAI,CAACO,gBAAgB,EAAE;EACrB,IAAA,OAAO,KAAK,CAAA;EACd,GAAA;EAEA,EAAA,IAAMG,yBAAyB,GAAGH,gBAAgB,IAAIznB,UAAU,CAACkmB,gBAAc,CAAC,CAAA;IAEhF,IAAM2B,UAAU,GAAGJ,gBAAgB,KAAK,OAAOL,WAAW,KAAK,UAAU,GACpE,UAACzY,OAAO,EAAA;EAAA,IAAA,OAAK,UAAC1P,GAAG,EAAA;EAAA,MAAA,OAAK0P,OAAO,CAACP,MAAM,CAACnP,GAAG,CAAC,CAAA;EAAA,KAAA,CAAA;EAAA,GAAA,CAAE,IAAImoB,WAAW,EAAE,CAAC,kBAAA,YAAA;MAAA,IAAA1jB,KAAA,GAAA0iB,iBAAA,eAAA9C,mBAAA,GAAAC,IAAA,CAC9D,SAAAa,OAAAA,CAAOnlB,GAAG,EAAA;EAAA,MAAA,OAAAqkB,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqmB,SAAAZ,QAAA,EAAA;EAAA,QAAA,OAAA,CAAA,EAAA,QAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAA3d,IAAA;EAAA,UAAA,KAAA,CAAA;cAAA2d,QAAA,CAAAgD,EAAA,GAAS/gB,UAAU,CAAA;EAAA+d,YAAAA,QAAA,CAAA3d,IAAA,GAAA,CAAA,CAAA;cAAA,OAAO,IAAI+gB,OAAO,CAAChoB,GAAG,CAAC,CAAC6oB,WAAW,EAAE,CAAA;EAAA,UAAA,KAAA,CAAA;EAAAjE,YAAAA,QAAA,CAAAoB,EAAA,GAAApB,QAAA,CAAAiB,IAAA,CAAA;cAAA,OAAAjB,QAAA,CAAAG,MAAA,CAAAH,QAAAA,EAAAA,IAAAA,QAAA,CAAAgD,EAAA,CAAAhD,QAAA,CAAAoB,EAAA,CAAA,CAAA,CAAA;EAAA,UAAA,KAAA,CAAA,CAAA;EAAA,UAAA,KAAA,KAAA;cAAA,OAAApB,QAAA,CAAAI,IAAA,EAAA,CAAA;EAAA,SAAA;EAAA,OAAA,EAAAG,OAAA,CAAA,CAAA;OAAC,CAAA,CAAA,CAAA;EAAA,IAAA,OAAA,UAAAe,EAAA,EAAA;EAAA,MAAA,OAAAzhB,KAAA,CAAArF,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,KAAA,CAAA;KACtE,EAAA,CAAA,CAAA,CAAA;IAED,IAAMypB,qBAAqB,GAAGL,kBAAkB,IAAIE,yBAAyB,IAAIhb,IAAI,CAAC,YAAM;MAC1F,IAAIob,cAAc,GAAG,KAAK,CAAA;MAE1B,IAAMC,cAAc,GAAG,IAAIhB,OAAO,CAAC5V,QAAQ,CAACJ,MAAM,EAAE;EAClDiX,MAAAA,IAAI,EAAE,IAAIhC,gBAAc,EAAE;EAC1BnS,MAAAA,MAAM,EAAE,MAAM;QACd,IAAIoU,MAAMA,GAAG;EACXH,QAAAA,cAAc,GAAG,IAAI,CAAA;EACrB,QAAA,OAAO,MAAM,CAAA;EACf,OAAA;EACF,KAAC,CAAC,CAACvV,OAAO,CAACqE,GAAG,CAAC,cAAc,CAAC,CAAA;MAE9B,OAAOkR,cAAc,IAAI,CAACC,cAAc,CAAA;EAC1C,GAAC,CAAC,CAAA;EAEF,EAAA,IAAMG,sBAAsB,GAAGT,mBAAmB,IAAIC,yBAAyB,IAC7Ehb,IAAI,CAAC,YAAA;MAAA,OAAMzB,OAAK,CAACpJ,gBAAgB,CAAC,IAAImlB,QAAQ,CAAC,EAAE,CAAC,CAACgB,IAAI,CAAC,CAAA;KAAC,CAAA,CAAA;EAE3D,EAAA,IAAMG,SAAS,GAAG;EAChB/C,IAAAA,MAAM,EAAE8C,sBAAsB,IAAK,UAACE,GAAG,EAAA;QAAA,OAAKA,GAAG,CAACJ,IAAI,CAAA;EAAA,KAAA;KACrD,CAAA;EAEDT,EAAAA,gBAAgB,IAAM,YAAM;EAC1B,IAAA,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAACplB,OAAO,CAAC,UAAA9C,IAAI,EAAI;EACpE,MAAA,CAAC8oB,SAAS,CAAC9oB,IAAI,CAAC,KAAK8oB,SAAS,CAAC9oB,IAAI,CAAC,GAAG,UAAC+oB,GAAG,EAAExd,MAAM,EAAK;EACtD,QAAA,IAAIiJ,MAAM,GAAGuU,GAAG,IAAIA,GAAG,CAAC/oB,IAAI,CAAC,CAAA;EAE7B,QAAA,IAAIwU,MAAM,EAAE;EACV,UAAA,OAAOA,MAAM,CAAC7U,IAAI,CAACopB,GAAG,CAAC,CAAA;EACzB,SAAA;EAEA,QAAA,MAAM,IAAI3d,UAAU,CAAAV,iBAAAA,CAAAA,MAAA,CAAmB1K,IAAI,EAAsBoL,oBAAAA,CAAAA,EAAAA,UAAU,CAAC4d,eAAe,EAAEzd,MAAM,CAAC,CAAA;EACtG,OAAC,CAAC,CAAA;EACJ,KAAC,CAAC,CAAA;EACJ,GAAC,EAAI,CAAA;EAEL,EAAA,IAAM0d,aAAa,gBAAA,YAAA;MAAA,IAAAtkB,KAAA,GAAAkiB,iBAAA,eAAA9C,mBAAA,GAAAC,IAAA,CAAG,SAAA8B,QAAAA,CAAO6C,IAAI,EAAA;EAAA,MAAA,IAAAO,QAAA,CAAA;EAAA,MAAA,OAAAnF,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqnB,UAAAf,SAAA,EAAA;EAAA,QAAA,OAAA,CAAA,EAAA,QAAAA,SAAA,CAAAZ,IAAA,GAAAY,SAAA,CAAAxe,IAAA;EAAA,UAAA,KAAA,CAAA;cAAA,IAC3BgiB,EAAAA,IAAI,IAAI,IAAI,CAAA,EAAA;EAAAxD,cAAAA,SAAA,CAAAxe,IAAA,GAAA,CAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAAA,YAAA,OAAAwe,SAAA,CAAAV,MAAA,CAAA,QAAA,EACP,CAAC,CAAA,CAAA;EAAA,UAAA,KAAA,CAAA;EAAA,YAAA,IAAA,CAGN7Y,OAAK,CAACjK,MAAM,CAACgnB,IAAI,CAAC,EAAA;EAAAxD,cAAAA,SAAA,CAAAxe,IAAA,GAAA,CAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAAA,YAAA,OAAAwe,SAAA,CAAAV,MAAA,CACbkE,QAAAA,EAAAA,IAAI,CAACQ,IAAI,CAAA,CAAA;EAAA,UAAA,KAAA,CAAA;EAAA,YAAA,IAAA,CAGdvd,OAAK,CAACxC,mBAAmB,CAACuf,IAAI,CAAC,EAAA;EAAAxD,cAAAA,SAAA,CAAAxe,IAAA,GAAA,CAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAC3BuiB,YAAAA,QAAQ,GAAG,IAAIxB,OAAO,CAAC5V,QAAQ,CAACJ,MAAM,EAAE;EAC5C8C,cAAAA,MAAM,EAAE,MAAM;EACdmU,cAAAA,IAAI,EAAJA,IAAAA;EACF,aAAC,CAAC,CAAA;EAAAxD,YAAAA,SAAA,CAAAxe,IAAA,GAAA,CAAA,CAAA;EAAA,YAAA,OACYuiB,QAAQ,CAACX,WAAW,EAAE,CAAA;EAAA,UAAA,KAAA,CAAA;cAAA,OAAApD,SAAA,CAAAV,MAAA,CAAA,QAAA,EAAAU,SAAA,CAAAI,IAAA,CAAEf,UAAU,CAAA,CAAA;EAAA,UAAA,KAAA,CAAA;EAAA,YAAA,IAAA,EAG9C5Y,OAAK,CAACjL,iBAAiB,CAACgoB,IAAI,CAAC,IAAI/c,OAAK,CAAClL,aAAa,CAACioB,IAAI,CAAC,CAAA,EAAA;EAAAxD,cAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAAA,YAAA,OAAAwe,SAAA,CAAAV,MAAA,CACrDkE,QAAAA,EAAAA,IAAI,CAACnE,UAAU,CAAA,CAAA;EAAA,UAAA,KAAA,EAAA;EAGxB,YAAA,IAAI5Y,OAAK,CAACzJ,iBAAiB,CAACwmB,IAAI,CAAC,EAAE;gBACjCA,IAAI,GAAGA,IAAI,GAAG,EAAE,CAAA;EAClB,aAAA;EAAC,YAAA,IAAA,CAEG/c,OAAK,CAAC5K,QAAQ,CAAC2nB,IAAI,CAAC,EAAA;EAAAxD,cAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAAAwe,YAAAA,SAAA,CAAAxe,IAAA,GAAA,EAAA,CAAA;cAAA,OACR2hB,UAAU,CAACK,IAAI,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;cAAA,OAAAxD,SAAA,CAAAV,MAAA,CAAA,QAAA,EAAAU,SAAA,CAAAI,IAAA,CAAEf,UAAU,CAAA,CAAA;EAAA,UAAA,KAAA,EAAA,CAAA;EAAA,UAAA,KAAA,KAAA;cAAA,OAAAW,SAAA,CAAAT,IAAA,EAAA,CAAA;EAAA,SAAA;EAAA,OAAA,EAAAoB,QAAA,CAAA,CAAA;OAE7C,CAAA,CAAA,CAAA;MAAA,OA5BKmD,SAAAA,aAAaA,CAAApD,GAAA,EAAA;EAAA,MAAA,OAAAlhB,KAAA,CAAA7F,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,KAAA,CAAA;KA4BlB,EAAA,CAAA;EAED,EAAA,IAAMqqB,iBAAiB,gBAAA,YAAA;EAAA,IAAA,IAAAzhB,KAAA,GAAAkf,iBAAA,eAAA9C,mBAAA,EAAA,CAAAC,IAAA,CAAG,SAAA8C,QAAAA,CAAO5T,OAAO,EAAEyV,IAAI,EAAA;EAAA,MAAA,IAAApnB,MAAA,CAAA;EAAA,MAAA,OAAAwiB,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqoB,UAAAf,SAAA,EAAA;EAAA,QAAA,OAAA,CAAA,EAAA,QAAAA,SAAA,CAAA5B,IAAA,GAAA4B,SAAA,CAAAxf,IAAA;EAAA,UAAA,KAAA,CAAA;cACtCpF,MAAM,GAAGqK,OAAK,CAAC5C,cAAc,CAACkK,OAAO,CAACmW,gBAAgB,EAAE,CAAC,CAAA;EAAA,YAAA,OAAAlD,SAAA,CAAA1B,MAAA,CAAA,QAAA,EAExDljB,MAAM,IAAI,IAAI,GAAG0nB,aAAa,CAACN,IAAI,CAAC,GAAGpnB,MAAM,CAAA,CAAA;EAAA,UAAA,KAAA,CAAA,CAAA;EAAA,UAAA,KAAA,KAAA;cAAA,OAAA4kB,SAAA,CAAAzB,IAAA,EAAA,CAAA;EAAA,SAAA;EAAA,OAAA,EAAAoC,QAAA,CAAA,CAAA;OACrD,CAAA,CAAA,CAAA;EAAA,IAAA,OAAA,SAJKsC,iBAAiBA,CAAA9C,GAAA,EAAAgD,GAAA,EAAA;EAAA,MAAA,OAAA3hB,KAAA,CAAA7I,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,KAAA,CAAA;KAItB,EAAA,CAAA;EAED,EAAA,oBAAA,YAAA;MAAA,IAAAsL,KAAA,GAAAwc,iBAAA,eAAA9C,mBAAA,GAAAC,IAAA,CAAO,SAAAuF,QAAAA,CAAOhe,MAAM,EAAA;EAAA,MAAA,IAAAie,cAAA,EAAAja,GAAA,EAAAiF,MAAA,EAAAlK,IAAA,EAAA6W,MAAA,EAAAhC,WAAA,EAAAlL,OAAA,EAAA4K,kBAAA,EAAAD,gBAAA,EAAA/K,YAAA,EAAAX,OAAA,EAAAuW,qBAAA,EAAA/K,eAAA,EAAAgL,YAAA,EAAAC,MAAA,EAAAC,cAAA,EAAApe,OAAA,EAAA0V,WAAA,EAAA2I,oBAAA,EAAAX,QAAA,EAAAY,iBAAA,EAAAC,qBAAA,EAAAC,sBAAA,EAAAxD,UAAA,EAAApL,KAAA,EAAA6O,sBAAA,EAAAC,eAAA,EAAAze,QAAA,EAAA0e,gBAAA,EAAA3c,OAAA,EAAA4c,qBAAA,EAAAC,KAAA,EAAAC,KAAA,EAAAC,WAAA,EAAAC,MAAA,EAAA/I,YAAA,CAAA;EAAA,MAAA,OAAAsC,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAA4rB,UAAAtD,SAAA,EAAA;EAAA,QAAA,OAAA,CAAA,EAAA,QAAAA,SAAA,CAAA5C,IAAA,GAAA4C,SAAA,CAAAxgB,IAAA;EAAA,UAAA,KAAA,CAAA;EAAA6iB,YAAAA,cAAA,GAcd9I,aAAa,CAACnV,MAAM,CAAC,EAZvBgE,GAAG,GAAAia,cAAA,CAAHja,GAAG,EACHiF,MAAM,GAAAgV,cAAA,CAANhV,MAAM,EACNlK,IAAI,GAAAkf,cAAA,CAAJlf,IAAI,EACJ6W,MAAM,GAAAqI,cAAA,CAANrI,MAAM,EACNhC,WAAW,GAAAqK,cAAA,CAAXrK,WAAW,EACXlL,OAAO,GAAAuV,cAAA,CAAPvV,OAAO,EACP4K,kBAAkB,GAAA2K,cAAA,CAAlB3K,kBAAkB,EAClBD,gBAAgB,GAAA4K,cAAA,CAAhB5K,gBAAgB,EAChB/K,YAAY,GAAA2V,cAAA,CAAZ3V,YAAY,EACZX,OAAO,GAAAsW,cAAA,CAAPtW,OAAO,EAAAuW,qBAAA,GAAAD,cAAA,CACP9K,eAAe,EAAfA,eAAe,GAAA+K,qBAAA,KAAG,KAAA,CAAA,GAAA,aAAa,GAAAA,qBAAA,EAC/BC,YAAY,GAAAF,cAAA,CAAZE,YAAY,CAAA;cAGVC,MAAM,GAAG3B,QAAQ,IAAIC,KAAK,CAAA;EAE9BpU,YAAAA,YAAY,GAAGA,YAAY,GAAG,CAACA,YAAY,GAAG,EAAE,EAAEhU,WAAW,EAAE,GAAG,MAAM,CAAA;EAEpE+pB,YAAAA,cAAc,GAAGrG,gBAAc,CAAC,CAACpC,MAAM,EAAEhC,WAAW,IAAIA,WAAW,CAACuL,aAAa,EAAE,CAAC,EAAEzW,OAAO,CAAC,CAAA;EAE9FzI,YAAAA,OAAO,GAAG,IAAI,CAAA;EAEZ0V,YAAAA,WAAW,GAAG0I,cAAc,IAAIA,cAAc,CAAC1I,WAAW,IAAK,YAAM;gBACzE0I,cAAc,CAAC1I,WAAW,EAAE,CAAA;eAC5B,CAAA;EAAAiG,YAAAA,SAAA,CAAA5C,IAAA,GAAA,CAAA,CAAA;EAAA4C,YAAAA,SAAA,CAAAG,EAAA,GAME1I,gBAAgB,IAAI4J,qBAAqB,IAAIhU,MAAM,KAAK,KAAK,IAAIA,MAAM,KAAK,MAAM,CAAA;cAAA,IAAA2S,CAAAA,SAAA,CAAAG,EAAA,EAAA;EAAAH,cAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAAAwgB,YAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,OACpDyiB,iBAAiB,CAAClW,OAAO,EAAE5I,IAAI,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;EAAA6c,YAAAA,SAAA,CAAAzB,EAAA,GAA7DmE,oBAAoB,GAAA1C,SAAA,CAAA5B,IAAA,CAAA;EAAA4B,YAAAA,SAAA,CAAAG,EAAA,GAAAH,SAAA,CAAAzB,EAAA,KAA+C,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;cAAA,IAAAyB,CAAAA,SAAA,CAAAG,EAAA,EAAA;EAAAH,cAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAEjEuiB,YAAAA,QAAQ,GAAG,IAAIxB,OAAO,CAACnY,GAAG,EAAE;EAC9BiF,cAAAA,MAAM,EAAE,MAAM;EACdmU,cAAAA,IAAI,EAAEre,IAAI;EACVse,cAAAA,MAAM,EAAE,MAAA;EACV,aAAC,CAAC,CAAA;EAIF,YAAA,IAAIhd,OAAK,CAAC7J,UAAU,CAACuI,IAAI,CAAC,KAAKwf,iBAAiB,GAAGZ,QAAQ,CAAChW,OAAO,CAACoE,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE;EACxFpE,cAAAA,OAAO,CAACK,cAAc,CAACuW,iBAAiB,CAAC,CAAA;EAC3C,aAAA;cAEA,IAAIZ,QAAQ,CAACP,IAAI,EAAE;gBAAAoB,qBAAA,GACW3N,sBAAsB,CAChDyN,oBAAoB,EACpBxO,oBAAoB,CAACgB,cAAc,CAACuC,gBAAgB,CAAC,CACvD,CAAC,EAAAoL,sBAAA,GAAAznB,cAAA,CAAAwnB,qBAAA,EAAA,CAAA,CAAA,EAHMvD,UAAU,GAAAwD,sBAAA,CAAA,CAAA,CAAA,EAAE5O,KAAK,GAAA4O,sBAAA,CAAA,CAAA,CAAA,CAAA;EAKxB1f,cAAAA,IAAI,GAAGic,WAAW,CAAC2C,QAAQ,CAACP,IAAI,EAAEnB,kBAAkB,EAAEhB,UAAU,EAAEpL,KAAK,CAAC,CAAA;EAC1E,aAAA;EAAC,UAAA,KAAA,EAAA;EAGH,YAAA,IAAI,CAACxP,OAAK,CAAC5K,QAAQ,CAAC0d,eAAe,CAAC,EAAE;EACpCA,cAAAA,eAAe,GAAGA,eAAe,GAAG,SAAS,GAAG,MAAM,CAAA;EACxD,aAAA;;EAEA;EACA;EACMuL,YAAAA,sBAAsB,GAAG9B,kBAAkB,IAAI,aAAa,IAAIT,OAAO,CAACxoB,SAAS,CAAA;EAEjFgrB,YAAAA,eAAe,GAAArY,cAAA,CAAAA,cAAA,KAChB6X,YAAY,CAAA,EAAA,EAAA,EAAA;EACfvI,cAAAA,MAAM,EAAEyI,cAAc;EACtBpV,cAAAA,MAAM,EAAEA,MAAM,CAAC/M,WAAW,EAAE;gBAC5ByL,OAAO,EAAEA,OAAO,CAAC0E,SAAS,EAAE,CAAC/L,MAAM,EAAE;EACrC8c,cAAAA,IAAI,EAAEre,IAAI;EACVse,cAAAA,MAAM,EAAE,MAAM;EACd+B,cAAAA,WAAW,EAAEV,sBAAsB,GAAGvL,eAAe,GAAGzb,SAAAA;EAAS,aAAA,CAAA,CAAA;cAGnEuI,OAAO,GAAG2c,kBAAkB,IAAI,IAAIT,OAAO,CAACnY,GAAG,EAAE2a,eAAe,CAAC,CAAA;EAAC/C,YAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,OAE5CwhB,kBAAkB,GAAGwB,MAAM,CAACne,OAAO,EAAEke,YAAY,CAAC,GAAGC,MAAM,CAACpa,GAAG,EAAE2a,eAAe,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;cAAnGze,QAAQ,GAAA0b,SAAA,CAAA5B,IAAA,CAAA;cAEN4E,gBAAgB,GAAGtB,sBAAsB,KAAKhV,YAAY,KAAK,QAAQ,IAAIA,YAAY,KAAK,UAAU,CAAC,CAAA;cAE7G,IAAIgV,sBAAsB,KAAKhK,kBAAkB,IAAKsL,gBAAgB,IAAIjJ,WAAY,CAAC,EAAE;gBACjF1T,OAAO,GAAG,EAAE,CAAA;gBAElB,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC1K,OAAO,CAAC,UAAA6C,IAAI,EAAI;EAClD6H,gBAAAA,OAAO,CAAC7H,IAAI,CAAC,GAAG8F,QAAQ,CAAC9F,IAAI,CAAC,CAAA;EAChC,eAAC,CAAC,CAAA;EAEIykB,cAAAA,qBAAqB,GAAGxe,OAAK,CAAC5C,cAAc,CAACyC,QAAQ,CAACyH,OAAO,CAACoE,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAA;EAAA+S,cAAAA,KAAA,GAE9DxL,kBAAkB,IAAIzC,sBAAsB,CACtEgO,qBAAqB,EACrB/O,oBAAoB,CAACgB,cAAc,CAACwC,kBAAkB,CAAC,EAAE,IAAI,CAC/D,CAAC,IAAI,EAAE,EAAAyL,KAAA,GAAA/nB,cAAA,CAAA8nB,KAAA,EAHA7D,CAAAA,CAAAA,EAAAA,WAAU,GAAA8D,KAAA,CAAElP,CAAAA,CAAAA,EAAAA,MAAK,GAAAkP,KAAA,CAAA,CAAA,CAAA,CAAA;EAKxB7e,cAAAA,QAAQ,GAAG,IAAIkc,QAAQ,CACrBpB,WAAW,CAAC9a,QAAQ,CAACkd,IAAI,EAAEnB,kBAAkB,EAAEhB,WAAU,EAAE,YAAM;kBAC/DpL,MAAK,IAAIA,MAAK,EAAE,CAAA;kBAChB8F,WAAW,IAAIA,WAAW,EAAE,CAAA;iBAC7B,CAAC,EACF1T,OACF,CAAC,CAAA;EACH,aAAA;cAEAqG,YAAY,GAAGA,YAAY,IAAI,MAAM,CAAA;EAACsT,YAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,OAEbmiB,SAAS,CAACld,OAAK,CAACnI,OAAO,CAACqlB,SAAS,EAAEjV,YAAY,CAAC,IAAI,MAAM,CAAC,CAACpI,QAAQ,EAAEF,MAAM,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;cAAlGkW,YAAY,GAAA0F,SAAA,CAAA5B,IAAA,CAAA;EAEhB,YAAA,CAAC4E,gBAAgB,IAAIjJ,WAAW,IAAIA,WAAW,EAAE,CAAA;EAACiG,YAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,YAAA,OAErC,IAAI4Z,OAAO,CAAC,UAACjH,OAAO,EAAEC,MAAM,EAAK;EAC5CF,cAAAA,MAAM,CAACC,OAAO,EAAEC,MAAM,EAAE;EACtBjP,gBAAAA,IAAI,EAAEmX,YAAY;kBAClBvO,OAAO,EAAE+C,cAAY,CAAC9J,IAAI,CAACV,QAAQ,CAACyH,OAAO,CAAC;kBAC5CvH,MAAM,EAAEF,QAAQ,CAACE,MAAM;kBACvBgW,UAAU,EAAElW,QAAQ,CAACkW,UAAU;EAC/BpW,gBAAAA,MAAM,EAANA,MAAM;EACNC,gBAAAA,OAAO,EAAPA,OAAAA;EACF,eAAC,CAAC,CAAA;EACJ,aAAC,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;EAAA,YAAA,OAAA2b,SAAA,CAAA1C,MAAA,CAAA0C,QAAAA,EAAAA,SAAA,CAAA5B,IAAA,CAAA,CAAA;EAAA,UAAA,KAAA,EAAA;EAAA4B,YAAAA,SAAA,CAAA5C,IAAA,GAAA,EAAA,CAAA;cAAA4C,SAAA,CAAAyD,EAAA,GAAAzD,SAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA;cAEFjG,WAAW,IAAIA,WAAW,EAAE,CAAA;cAAC,IAEzBiG,EAAAA,SAAA,CAAAyD,EAAA,IAAOzD,SAAA,CAAAyD,EAAA,CAAI1iB,IAAI,KAAK,WAAW,IAAI,oBAAoB,CAACmF,IAAI,CAAC8Z,SAAA,CAAAyD,EAAA,CAAIvf,OAAO,CAAC,CAAA,EAAA;EAAA8b,cAAAA,SAAA,CAAAxgB,IAAA,GAAA,EAAA,CAAA;EAAA,cAAA,MAAA;EAAA,aAAA;EAAA,YAAA,MACrE1H,MAAM,CAACoG,MAAM,CACjB,IAAI+F,UAAU,CAAC,eAAe,EAAEA,UAAU,CAACmX,WAAW,EAAEhX,MAAM,EAAEC,OAAO,CAAC,EACxE;gBACEiB,KAAK,EAAE0a,SAAA,CAAAyD,EAAA,CAAIne,KAAK,IAAA0a,SAAA,CAAAyD,EAAAA;EAClB,aACF,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA;cAAA,MAGGxf,UAAU,CAACe,IAAI,CAAAgb,SAAA,CAAAyD,EAAA,EAAMzD,SAAA,CAAAyD,EAAA,IAAOzD,SAAA,CAAAyD,EAAA,CAAItf,IAAI,EAAEC,MAAM,EAAEC,OAAO,CAAC,CAAA;EAAA,UAAA,KAAA,EAAA,CAAA;EAAA,UAAA,KAAA,KAAA;cAAA,OAAA2b,SAAA,CAAAzC,IAAA,EAAA,CAAA;EAAA,SAAA;EAAA,OAAA,EAAA6E,QAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA;OAE/D,CAAA,CAAA,CAAA;EAAA,IAAA,OAAA,UAAAsB,GAAA,EAAA;EAAA,MAAA,OAAAxgB,KAAA,CAAAvL,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,KAAA,CAAA;EAAA,GAAA,EAAA,CAAA;EACH,CAAC,CAAA;EAED,IAAM+rB,SAAS,GAAG,IAAIC,GAAG,EAAE,CAAA;EAEpB,IAAMC,QAAQ,GAAG,SAAXA,QAAQA,CAAIzf,MAAM,EAAK;IAClC,IAAImI,GAAG,GAAGnI,MAAM,GAAGA,MAAM,CAACmI,GAAG,GAAG,EAAE,CAAA;EAClC,EAAA,IAAOuU,KAAK,GAAuBvU,GAAG,CAA/BuU,KAAK;MAAEP,OAAO,GAAchU,GAAG,CAAxBgU,OAAO;MAAEC,QAAQ,GAAIjU,GAAG,CAAfiU,QAAQ,CAAA;IAC/B,IAAMsD,KAAK,GAAG,CACZvD,OAAO,EAAEC,QAAQ,EAAEM,KAAK,CACzB,CAAA;EAED,EAAA,IAAI1kB,GAAG,GAAG0nB,KAAK,CAAC1pB,MAAM;EAAE6B,IAAAA,CAAC,GAAGG,GAAG;MAC7B2nB,IAAI;MAAEzhB,MAAM;EAAEpH,IAAAA,GAAG,GAAGyoB,SAAS,CAAA;IAE/B,OAAO1nB,CAAC,EAAE,EAAE;EACV8nB,IAAAA,IAAI,GAAGD,KAAK,CAAC7nB,CAAC,CAAC,CAAA;EACfqG,IAAAA,MAAM,GAAGpH,GAAG,CAACiV,GAAG,CAAC4T,IAAI,CAAC,CAAA;MAEtBzhB,MAAM,KAAKxG,SAAS,IAAIZ,GAAG,CAACmG,GAAG,CAAC0iB,IAAI,EAAEzhB,MAAM,GAAIrG,CAAC,GAAG,IAAI2nB,GAAG,EAAE,GAAGjD,OAAO,CAACpU,GAAG,CAAE,CAAC,CAAA;EAE9ErR,IAAAA,GAAG,GAAGoH,MAAM,CAAA;EACd,GAAA;EAEA,EAAA,OAAOA,MAAM,CAAA;EACf,CAAC,CAAA;EAEeuhB,QAAQ;;ECvRxB,IAAMG,aAAa,GAAG;EACpBC,EAAAA,IAAI,EAAEC,WAAW;EACjBC,EAAAA,GAAG,EAAEC,UAAU;EACftD,EAAAA,KAAK,EAAE;MACL3Q,GAAG,EAAEkU,QAAaR;EACpB,GAAA;EACF,CAAC,CAAA;AAEDpf,SAAK,CAAC9I,OAAO,CAACqoB,aAAa,EAAE,UAACxsB,EAAE,EAAEyG,KAAK,EAAK;EAC1C,EAAA,IAAIzG,EAAE,EAAE;MACN,IAAI;EACFM,MAAAA,MAAM,CAACkG,cAAc,CAACxG,EAAE,EAAE,MAAM,EAAE;EAACyG,QAAAA,KAAK,EAALA,KAAAA;EAAK,OAAC,CAAC,CAAA;OAC3C,CAAC,OAAO5D,CAAC,EAAE;EACV;EAAA,KAAA;EAEFvC,IAAAA,MAAM,CAACkG,cAAc,CAACxG,EAAE,EAAE,aAAa,EAAE;EAACyG,MAAAA,KAAK,EAALA,KAAAA;EAAK,KAAC,CAAC,CAAA;EACnD,GAAA;EACF,CAAC,CAAC,CAAA;EAEF,IAAMqmB,YAAY,GAAG,SAAfA,YAAYA,CAAI5H,MAAM,EAAA;IAAA,OAAAnZ,IAAAA,CAAAA,MAAA,CAAUmZ,MAAM,CAAA,CAAA;EAAA,CAAE,CAAA;EAE9C,IAAM6H,gBAAgB,GAAG,SAAnBA,gBAAgBA,CAAI1Y,OAAO,EAAA;EAAA,EAAA,OAAKpH,OAAK,CAACnL,UAAU,CAACuS,OAAO,CAAC,IAAIA,OAAO,KAAK,IAAI,IAAIA,OAAO,KAAK,KAAK,CAAA;EAAA,CAAA,CAAA;AAExG,iBAAe;EACb2Y,EAAAA,UAAU,EAAE,SAAAA,UAAAA,CAACC,QAAQ,EAAErgB,MAAM,EAAK;EAChCqgB,IAAAA,QAAQ,GAAGhgB,OAAK,CAACzL,OAAO,CAACyrB,QAAQ,CAAC,GAAGA,QAAQ,GAAG,CAACA,QAAQ,CAAC,CAAA;MAE1D,IAAAC,SAAA,GAAiBD,QAAQ;QAAlBrqB,MAAM,GAAAsqB,SAAA,CAANtqB,MAAM,CAAA;EACb,IAAA,IAAIuqB,aAAa,CAAA;EACjB,IAAA,IAAI9Y,OAAO,CAAA;MAEX,IAAM+Y,eAAe,GAAG,EAAE,CAAA;MAE1B,KAAK,IAAI3oB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG7B,MAAM,EAAE6B,CAAC,EAAE,EAAE;EAC/B0oB,MAAAA,aAAa,GAAGF,QAAQ,CAACxoB,CAAC,CAAC,CAAA;EAC3B,MAAA,IAAIkN,EAAE,GAAA,KAAA,CAAA,CAAA;EAEN0C,MAAAA,OAAO,GAAG8Y,aAAa,CAAA;EAEvB,MAAA,IAAI,CAACJ,gBAAgB,CAACI,aAAa,CAAC,EAAE;EACpC9Y,QAAAA,OAAO,GAAGmY,aAAa,CAAC,CAAC7a,EAAE,GAAGtK,MAAM,CAAC8lB,aAAa,CAAC,EAAEjsB,WAAW,EAAE,CAAC,CAAA;UAEnE,IAAImT,OAAO,KAAK/P,SAAS,EAAE;EACzB,UAAA,MAAM,IAAImI,UAAU,CAAA,mBAAA,CAAAV,MAAA,CAAqB4F,EAAE,MAAG,CAAC,CAAA;EACjD,SAAA;EACF,OAAA;EAEA,MAAA,IAAI0C,OAAO,KAAKpH,OAAK,CAACnL,UAAU,CAACuS,OAAO,CAAC,KAAKA,OAAO,GAAGA,OAAO,CAACsE,GAAG,CAAC/L,MAAM,CAAC,CAAC,CAAC,EAAE;EAC7E,QAAA,MAAA;EACF,OAAA;QAEAwgB,eAAe,CAACzb,EAAE,IAAI,GAAG,GAAGlN,CAAC,CAAC,GAAG4P,OAAO,CAAA;EAC1C,KAAA;MAEA,IAAI,CAACA,OAAO,EAAE;EAEZ,MAAA,IAAMgZ,OAAO,GAAG/sB,MAAM,CAACuT,OAAO,CAACuZ,eAAe,CAAC,CAC5C1pB,GAAG,CAAC,UAAAW,IAAA,EAAA;EAAA,QAAA,IAAAmB,KAAA,GAAA5B,cAAA,CAAAS,IAAA,EAAA,CAAA,CAAA;EAAEsN,UAAAA,EAAE,GAAAnM,KAAA,CAAA,CAAA,CAAA;EAAE8nB,UAAAA,KAAK,GAAA9nB,KAAA,CAAA,CAAA,CAAA,CAAA;EAAA,QAAA,OAAM,UAAAuG,CAAAA,MAAA,CAAW4F,EAAE,EAChC2b,GAAAA,CAAAA,IAAAA,KAAK,KAAK,KAAK,GAAG,qCAAqC,GAAG,+BAA+B,CAAC,CAAA;EAAA,OAC7F,CAAC,CAAA;EAEH,MAAA,IAAIjV,CAAC,GAAGzV,MAAM,GACXyqB,OAAO,CAACzqB,MAAM,GAAG,CAAC,GAAG,WAAW,GAAGyqB,OAAO,CAAC3pB,GAAG,CAACopB,YAAY,CAAC,CAACxe,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,GAAGwe,YAAY,CAACO,OAAO,CAAC,CAAC,CAAC,CAAC,GACzG,yBAAyB,CAAA;EAE3B,MAAA,MAAM,IAAI5gB,UAAU,CAClB,0DAA0D4L,CAAC,EAC3D,iBACF,CAAC,CAAA;EACH,KAAA;EAEA,IAAA,OAAOhE,OAAO,CAAA;KACf;EACD4Y,EAAAA,QAAQ,EAAET,aAAAA;EACZ,CAAC;;ECvED;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASe,4BAA4BA,CAAC3gB,MAAM,EAAE;IAC5C,IAAIA,MAAM,CAAC4T,WAAW,EAAE;EACtB5T,IAAAA,MAAM,CAAC4T,WAAW,CAACgN,gBAAgB,EAAE,CAAA;EACvC,GAAA;IAEA,IAAI5gB,MAAM,CAAC4V,MAAM,IAAI5V,MAAM,CAAC4V,MAAM,CAACkC,OAAO,EAAE;EAC1C,IAAA,MAAM,IAAIlK,aAAa,CAAC,IAAI,EAAE5N,MAAM,CAAC,CAAA;EACvC,GAAA;EACF,CAAA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAAS6gB,eAAeA,CAAC7gB,MAAM,EAAE;IAC9C2gB,4BAA4B,CAAC3gB,MAAM,CAAC,CAAA;IAEpCA,MAAM,CAAC2H,OAAO,GAAG+C,cAAY,CAAC9J,IAAI,CAACZ,MAAM,CAAC2H,OAAO,CAAC,CAAA;;EAElD;EACA3H,EAAAA,MAAM,CAACjB,IAAI,GAAGwO,aAAa,CAACnZ,IAAI,CAC9B4L,MAAM,EACNA,MAAM,CAAC0H,gBACT,CAAC,CAAA;EAED,EAAA,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC/M,OAAO,CAACqF,MAAM,CAACiJ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE;MAC1DjJ,MAAM,CAAC2H,OAAO,CAACK,cAAc,CAAC,mCAAmC,EAAE,KAAK,CAAC,CAAA;EAC3E,GAAA;EAEA,EAAA,IAAMP,OAAO,GAAG4Y,QAAQ,CAACD,UAAU,CAACpgB,MAAM,CAACyH,OAAO,IAAIH,UAAQ,CAACG,OAAO,EAAEzH,MAAM,CAAC,CAAA;IAE/E,OAAOyH,OAAO,CAACzH,MAAM,CAAC,CAAC1B,IAAI,CAAC,SAASwiB,mBAAmBA,CAAC5gB,QAAQ,EAAE;MACjEygB,4BAA4B,CAAC3gB,MAAM,CAAC,CAAA;;EAEpC;EACAE,IAAAA,QAAQ,CAACnB,IAAI,GAAGwO,aAAa,CAACnZ,IAAI,CAChC4L,MAAM,EACNA,MAAM,CAACoI,iBAAiB,EACxBlI,QACF,CAAC,CAAA;MAEDA,QAAQ,CAACyH,OAAO,GAAG+C,cAAY,CAAC9J,IAAI,CAACV,QAAQ,CAACyH,OAAO,CAAC,CAAA;EAEtD,IAAA,OAAOzH,QAAQ,CAAA;EACjB,GAAC,EAAE,SAAS6gB,kBAAkBA,CAACzI,MAAM,EAAE;EACrC,IAAA,IAAI,CAAC5K,QAAQ,CAAC4K,MAAM,CAAC,EAAE;QACrBqI,4BAA4B,CAAC3gB,MAAM,CAAC,CAAA;;EAEpC;EACA,MAAA,IAAIsY,MAAM,IAAIA,MAAM,CAACpY,QAAQ,EAAE;EAC7BoY,QAAAA,MAAM,CAACpY,QAAQ,CAACnB,IAAI,GAAGwO,aAAa,CAACnZ,IAAI,CACvC4L,MAAM,EACNA,MAAM,CAACoI,iBAAiB,EACxBkQ,MAAM,CAACpY,QACT,CAAC,CAAA;EACDoY,QAAAA,MAAM,CAACpY,QAAQ,CAACyH,OAAO,GAAG+C,cAAY,CAAC9J,IAAI,CAAC0X,MAAM,CAACpY,QAAQ,CAACyH,OAAO,CAAC,CAAA;EACtE,OAAA;EACF,KAAA;EAEA,IAAA,OAAOqN,OAAO,CAAChH,MAAM,CAACsK,MAAM,CAAC,CAAA;EAC/B,GAAC,CAAC,CAAA;EACJ;;EChFO,IAAM0I,OAAO,GAAG,QAAQ;;ECK/B,IAAMC,YAAU,GAAG,EAAE,CAAA;;EAErB;EACA,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC1pB,OAAO,CAAC,UAAC9C,IAAI,EAAEoD,CAAC,EAAK;IACnFopB,YAAU,CAACxsB,IAAI,CAAC,GAAG,SAASysB,SAASA,CAAChtB,KAAK,EAAE;EAC3C,IAAA,OAAOS,OAAA,CAAOT,KAAK,CAAKO,KAAAA,IAAI,IAAI,GAAG,IAAIoD,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,GAAGpD,IAAI,CAAA;KAClE,CAAA;EACH,CAAC,CAAC,CAAA;EAEF,IAAM0sB,kBAAkB,GAAG,EAAE,CAAA;;EAE7B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;AACAF,cAAU,CAAC1Z,YAAY,GAAG,SAASA,YAAYA,CAAC2Z,SAAS,EAAEE,OAAO,EAAEthB,OAAO,EAAE;EAC3E,EAAA,SAASuhB,aAAaA,CAACC,GAAG,EAAEC,IAAI,EAAE;EAChC,IAAA,OAAO,UAAU,GAAGP,OAAO,GAAG,0BAA0B,GAAGM,GAAG,GAAG,IAAI,GAAGC,IAAI,IAAIzhB,OAAO,GAAG,IAAI,GAAGA,OAAO,GAAG,EAAE,CAAC,CAAA;EAChH,GAAA;;EAEA;EACA,EAAA,OAAO,UAACjG,KAAK,EAAEynB,GAAG,EAAEE,IAAI,EAAK;MAC3B,IAAIN,SAAS,KAAK,KAAK,EAAE;QACvB,MAAM,IAAIrhB,UAAU,CAClBwhB,aAAa,CAACC,GAAG,EAAE,mBAAmB,IAAIF,OAAO,GAAG,MAAM,GAAGA,OAAO,GAAG,EAAE,CAAC,CAAC,EAC3EvhB,UAAU,CAAC4hB,cACb,CAAC,CAAA;EACH,KAAA;EAEA,IAAA,IAAIL,OAAO,IAAI,CAACD,kBAAkB,CAACG,GAAG,CAAC,EAAE;EACvCH,MAAAA,kBAAkB,CAACG,GAAG,CAAC,GAAG,IAAI,CAAA;EAC9B;EACAI,MAAAA,OAAO,CAACC,IAAI,CACVN,aAAa,CACXC,GAAG,EACH,8BAA8B,GAAGF,OAAO,GAAG,yCAC7C,CACF,CAAC,CAAA;EACH,KAAA;MAEA,OAAOF,SAAS,GAAGA,SAAS,CAACrnB,KAAK,EAAEynB,GAAG,EAAEE,IAAI,CAAC,GAAG,IAAI,CAAA;KACtD,CAAA;EACH,CAAC,CAAA;AAEDP,cAAU,CAACW,QAAQ,GAAG,SAASA,QAAQA,CAACC,eAAe,EAAE;EACvD,EAAA,OAAO,UAAChoB,KAAK,EAAEynB,GAAG,EAAK;EACrB;MACAI,OAAO,CAACC,IAAI,CAAA,EAAA,CAAAxiB,MAAA,CAAImiB,GAAG,EAAA,8BAAA,CAAA,CAAAniB,MAAA,CAA+B0iB,eAAe,CAAE,CAAC,CAAA;EACpE,IAAA,OAAO,IAAI,CAAA;KACZ,CAAA;EACH,CAAC,CAAA;;EAED;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA,SAASC,aAAaA,CAAC7f,OAAO,EAAE8f,MAAM,EAAEC,YAAY,EAAE;EACpD,EAAA,IAAIrtB,OAAA,CAAOsN,OAAO,CAAA,KAAK,QAAQ,EAAE;MAC/B,MAAM,IAAIpC,UAAU,CAAC,2BAA2B,EAAEA,UAAU,CAACoiB,oBAAoB,CAAC,CAAA;EACpF,GAAA;EACA,EAAA,IAAMlsB,IAAI,GAAGrC,MAAM,CAACqC,IAAI,CAACkM,OAAO,CAAC,CAAA;EACjC,EAAA,IAAIpK,CAAC,GAAG9B,IAAI,CAACC,MAAM,CAAA;EACnB,EAAA,OAAO6B,CAAC,EAAE,GAAG,CAAC,EAAE;EACd,IAAA,IAAMypB,GAAG,GAAGvrB,IAAI,CAAC8B,CAAC,CAAC,CAAA;EACnB,IAAA,IAAMqpB,SAAS,GAAGa,MAAM,CAACT,GAAG,CAAC,CAAA;EAC7B,IAAA,IAAIJ,SAAS,EAAE;EACb,MAAA,IAAMrnB,KAAK,GAAGoI,OAAO,CAACqf,GAAG,CAAC,CAAA;EAC1B,MAAA,IAAMjsB,MAAM,GAAGwE,KAAK,KAAKnC,SAAS,IAAIwpB,SAAS,CAACrnB,KAAK,EAAEynB,GAAG,EAAErf,OAAO,CAAC,CAAA;QACpE,IAAI5M,MAAM,KAAK,IAAI,EAAE;EACnB,QAAA,MAAM,IAAIwK,UAAU,CAAC,SAAS,GAAGyhB,GAAG,GAAG,WAAW,GAAGjsB,MAAM,EAAEwK,UAAU,CAACoiB,oBAAoB,CAAC,CAAA;EAC/F,OAAA;EACA,MAAA,SAAA;EACF,KAAA;MACA,IAAID,YAAY,KAAK,IAAI,EAAE;QACzB,MAAM,IAAIniB,UAAU,CAAC,iBAAiB,GAAGyhB,GAAG,EAAEzhB,UAAU,CAACqiB,cAAc,CAAC,CAAA;EAC1E,KAAA;EACF,GAAA;EACF,CAAA;AAEA,kBAAe;EACbJ,EAAAA,aAAa,EAAbA,aAAa;EACbb,EAAAA,UAAU,EAAVA,YAAAA;EACF,CAAC;;ECvFD,IAAMA,UAAU,GAAGC,SAAS,CAACD,UAAU,CAAA;;EAEvC;EACA;EACA;EACA;EACA;EACA;EACA;EANA,IAOMkB,KAAK,gBAAA,YAAA;IACT,SAAAA,KAAAA,CAAYC,cAAc,EAAE;EAAA9d,IAAAA,eAAA,OAAA6d,KAAA,CAAA,CAAA;EAC1B,IAAA,IAAI,CAAC7a,QAAQ,GAAG8a,cAAc,IAAI,EAAE,CAAA;MACpC,IAAI,CAACC,YAAY,GAAG;EAClBpiB,MAAAA,OAAO,EAAE,IAAIoE,oBAAkB,EAAE;QACjCnE,QAAQ,EAAE,IAAImE,oBAAkB,EAAC;OAClC,CAAA;EACH,GAAA;;EAEA;EACF;EACA;EACA;EACA;EACA;EACA;EACA;EAPEG,EAAAA,YAAA,CAAA2d,KAAA,EAAA,CAAA;MAAAlqB,GAAA,EAAA,SAAA;MAAA4B,KAAA,GAAA,YAAA;EAAA,MAAA,IAAAyoB,SAAA,GAAAhH,iBAAA,eAAA9C,mBAAA,EAAA,CAAAC,IAAA,CAQA,SAAAa,OAAAA,CAAciJ,WAAW,EAAEviB,MAAM,EAAA;UAAA,IAAAwiB,KAAA,EAAAzkB,KAAA,CAAA;EAAA,QAAA,OAAAya,mBAAA,EAAA,CAAAllB,IAAA,CAAA,SAAAqmB,SAAAZ,QAAA,EAAA;EAAA,UAAA,OAAA,CAAA,EAAA,QAAAA,QAAA,CAAAC,IAAA,GAAAD,QAAA,CAAA3d,IAAA;EAAA,YAAA,KAAA,CAAA;EAAA2d,cAAAA,QAAA,CAAAC,IAAA,GAAA,CAAA,CAAA;EAAAD,cAAAA,QAAA,CAAA3d,IAAA,GAAA,CAAA,CAAA;EAAA,cAAA,OAEhB,IAAI,CAACuiB,QAAQ,CAAC4E,WAAW,EAAEviB,MAAM,CAAC,CAAA;EAAA,YAAA,KAAA,CAAA;EAAA,cAAA,OAAA+Y,QAAA,CAAAG,MAAA,CAAAH,QAAAA,EAAAA,QAAA,CAAAiB,IAAA,CAAA,CAAA;EAAA,YAAA,KAAA,CAAA;EAAAjB,cAAAA,QAAA,CAAAC,IAAA,GAAA,CAAA,CAAA;gBAAAD,QAAA,CAAAgD,EAAA,GAAAhD,QAAA,CAAA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EAE/C,cAAA,IAAIA,QAAA,CAAAgD,EAAA,YAAe7e,KAAK,EAAE;kBACpBslB,KAAK,GAAG,EAAE,CAAA;EAEdtlB,gBAAAA,KAAK,CAACiD,iBAAiB,GAAGjD,KAAK,CAACiD,iBAAiB,CAACqiB,KAAK,CAAC,GAAIA,KAAK,GAAG,IAAItlB,KAAK,EAAG,CAAA;;EAEhF;EACMa,gBAAAA,KAAK,GAAGykB,KAAK,CAACzkB,KAAK,GAAGykB,KAAK,CAACzkB,KAAK,CAACzG,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,CAAA;kBACjE,IAAI;EACF,kBAAA,IAAI,CAACyhB,QAAA,CAAAgD,EAAA,CAAIhe,KAAK,EAAE;EACdgb,oBAAAA,QAAA,CAAAgD,EAAA,CAAIhe,KAAK,GAAGA,KAAK,CAAA;EACjB;qBACD,MAAM,IAAIA,KAAK,IAAI,CAACtD,MAAM,CAACse,QAAA,CAAAgD,EAAA,CAAIhe,KAAK,CAAC,CAACzD,QAAQ,CAACyD,KAAK,CAACzG,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,EAAE;EAC/EyhB,oBAAAA,QAAA,CAAAgD,EAAA,CAAIhe,KAAK,IAAI,IAAI,GAAGA,KAAK,CAAA;EAC3B,mBAAA;mBACD,CAAC,OAAO9H,CAAC,EAAE;EACV;EAAA,iBAAA;EAEJ,eAAA;gBAAC,MAAA8iB,QAAA,CAAAgD,EAAA,CAAA;EAAA,YAAA,KAAA,EAAA,CAAA;EAAA,YAAA,KAAA,KAAA;gBAAA,OAAAhD,QAAA,CAAAI,IAAA,EAAA,CAAA;EAAA,WAAA;EAAA,SAAA,EAAAG,OAAA,EAAA,IAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA;SAIJ,CAAA,CAAA,CAAA;QAAA,SAAArZ,OAAAA,CAAAoa,EAAA,EAAAC,GAAA,EAAA;EAAA,QAAA,OAAAgI,SAAA,CAAA/uB,KAAA,CAAA,IAAA,EAAAC,SAAA,CAAA,CAAA;EAAA,OAAA;EAAA,MAAA,OAAAyM,OAAA,CAAA;EAAA,KAAA,EAAA,CAAA;EAAA,GAAA,EAAA;MAAAhI,GAAA,EAAA,UAAA;EAAA4B,IAAAA,KAAA,EAED,SAAA8jB,QAAAA,CAAS4E,WAAW,EAAEviB,MAAM,EAAE;EAC5B;EACA;EACA,MAAA,IAAI,OAAOuiB,WAAW,KAAK,QAAQ,EAAE;EACnCviB,QAAAA,MAAM,GAAGA,MAAM,IAAI,EAAE,CAAA;UACrBA,MAAM,CAACgE,GAAG,GAAGue,WAAW,CAAA;EAC1B,OAAC,MAAM;EACLviB,QAAAA,MAAM,GAAGuiB,WAAW,IAAI,EAAE,CAAA;EAC5B,OAAA;QAEAviB,MAAM,GAAGwS,WAAW,CAAC,IAAI,CAAClL,QAAQ,EAAEtH,MAAM,CAAC,CAAA;QAE3C,IAAAkV,OAAA,GAAkDlV,MAAM;UAAjDuH,YAAY,GAAA2N,OAAA,CAAZ3N,YAAY;UAAE0L,gBAAgB,GAAAiC,OAAA,CAAhBjC,gBAAgB;UAAEtL,OAAO,GAAAuN,OAAA,CAAPvN,OAAO,CAAA;QAE9C,IAAIJ,YAAY,KAAK7P,SAAS,EAAE;EAC9BwpB,QAAAA,SAAS,CAACY,aAAa,CAACva,YAAY,EAAE;EACpCpC,UAAAA,iBAAiB,EAAE8b,UAAU,CAAC1Z,YAAY,CAAC0Z,UAAU,WAAQ,CAAC;EAC9D7b,UAAAA,iBAAiB,EAAE6b,UAAU,CAAC1Z,YAAY,CAAC0Z,UAAU,WAAQ,CAAC;EAC9D5b,UAAAA,mBAAmB,EAAE4b,UAAU,CAAC1Z,YAAY,CAAC0Z,UAAU,CAAQ,SAAA,CAAA,CAAA;WAChE,EAAE,KAAK,CAAC,CAAA;EACX,OAAA;QAEA,IAAIhO,gBAAgB,IAAI,IAAI,EAAE;EAC5B,QAAA,IAAI5S,OAAK,CAACnL,UAAU,CAAC+d,gBAAgB,CAAC,EAAE;YACtCjT,MAAM,CAACiT,gBAAgB,GAAG;EACxBhP,YAAAA,SAAS,EAAEgP,gBAAAA;aACZ,CAAA;EACH,SAAC,MAAM;EACLiO,UAAAA,SAAS,CAACY,aAAa,CAAC7O,gBAAgB,EAAE;cACxC3P,MAAM,EAAE2d,UAAU,CAAS,UAAA,CAAA;EAC3Bhd,YAAAA,SAAS,EAAEgd,UAAU,CAAA,UAAA,CAAA;aACtB,EAAE,IAAI,CAAC,CAAA;EACV,SAAA;EACF,OAAA;;EAEA;EACA,MAAA,IAAIjhB,MAAM,CAACqS,iBAAiB,KAAK3a,SAAS,EAAE,CAE3C,MAAM,IAAI,IAAI,CAAC4P,QAAQ,CAAC+K,iBAAiB,KAAK3a,SAAS,EAAE;EACxDsI,QAAAA,MAAM,CAACqS,iBAAiB,GAAG,IAAI,CAAC/K,QAAQ,CAAC+K,iBAAiB,CAAA;EAC5D,OAAC,MAAM;UACLrS,MAAM,CAACqS,iBAAiB,GAAG,IAAI,CAAA;EACjC,OAAA;EAEA6O,MAAAA,SAAS,CAACY,aAAa,CAAC9hB,MAAM,EAAE;EAC9ByiB,QAAAA,OAAO,EAAExB,UAAU,CAACW,QAAQ,CAAC,SAAS,CAAC;EACvCc,QAAAA,aAAa,EAAEzB,UAAU,CAACW,QAAQ,CAAC,eAAe,CAAA;SACnD,EAAE,IAAI,CAAC,CAAA;;EAER;EACA5hB,MAAAA,MAAM,CAACiJ,MAAM,GAAG,CAACjJ,MAAM,CAACiJ,MAAM,IAAI,IAAI,CAAC3B,QAAQ,CAAC2B,MAAM,IAAI,KAAK,EAAE3U,WAAW,EAAE,CAAA;;EAE9E;EACA,MAAA,IAAIquB,cAAc,GAAGhb,OAAO,IAAItH,OAAK,CAAC1H,KAAK,CACzCgP,OAAO,CAACqB,MAAM,EACdrB,OAAO,CAAC3H,MAAM,CAACiJ,MAAM,CACvB,CAAC,CAAA;QAEDtB,OAAO,IAAItH,OAAK,CAAC9I,OAAO,CACtB,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAC3D,UAAC0R,MAAM,EAAK;UACV,OAAOtB,OAAO,CAACsB,MAAM,CAAC,CAAA;EACxB,OACF,CAAC,CAAA;QAEDjJ,MAAM,CAAC2H,OAAO,GAAG+C,cAAY,CAACvL,MAAM,CAACwjB,cAAc,EAAEhb,OAAO,CAAC,CAAA;;EAE7D;QACA,IAAMib,uBAAuB,GAAG,EAAE,CAAA;QAClC,IAAIC,8BAA8B,GAAG,IAAI,CAAA;QACzC,IAAI,CAACR,YAAY,CAACpiB,OAAO,CAAC1I,OAAO,CAAC,SAASurB,0BAA0BA,CAACC,WAAW,EAAE;EACjF,QAAA,IAAI,OAAOA,WAAW,CAACle,OAAO,KAAK,UAAU,IAAIke,WAAW,CAACle,OAAO,CAAC7E,MAAM,CAAC,KAAK,KAAK,EAAE;EACtF,UAAA,OAAA;EACF,SAAA;EAEA6iB,QAAAA,8BAA8B,GAAGA,8BAA8B,IAAIE,WAAW,CAACne,WAAW,CAAA;UAE1Fge,uBAAuB,CAACI,OAAO,CAACD,WAAW,CAACre,SAAS,EAAEqe,WAAW,CAACpe,QAAQ,CAAC,CAAA;EAC9E,OAAC,CAAC,CAAA;QAEF,IAAMse,wBAAwB,GAAG,EAAE,CAAA;QACnC,IAAI,CAACZ,YAAY,CAACniB,QAAQ,CAAC3I,OAAO,CAAC,SAAS2rB,wBAAwBA,CAACH,WAAW,EAAE;UAChFE,wBAAwB,CAACtnB,IAAI,CAAConB,WAAW,CAACre,SAAS,EAAEqe,WAAW,CAACpe,QAAQ,CAAC,CAAA;EAC5E,OAAC,CAAC,CAAA;EAEF,MAAA,IAAIwe,OAAO,CAAA;QACX,IAAItrB,CAAC,GAAG,CAAC,CAAA;EACT,MAAA,IAAIG,GAAG,CAAA;QAEP,IAAI,CAAC6qB,8BAA8B,EAAE;UACnC,IAAMO,KAAK,GAAG,CAACvC,eAAe,CAAC1tB,IAAI,CAAC,IAAI,CAAC,EAAEuE,SAAS,CAAC,CAAA;UACrD0rB,KAAK,CAACJ,OAAO,CAAAzvB,KAAA,CAAb6vB,KAAK,EAAYR,uBAAuB,CAAC,CAAA;UACzCQ,KAAK,CAACznB,IAAI,CAAApI,KAAA,CAAV6vB,KAAK,EAASH,wBAAwB,CAAC,CAAA;UACvCjrB,GAAG,GAAGorB,KAAK,CAACptB,MAAM,CAAA;EAElBmtB,QAAAA,OAAO,GAAGnO,OAAO,CAACjH,OAAO,CAAC/N,MAAM,CAAC,CAAA;UAEjC,OAAOnI,CAAC,GAAGG,GAAG,EAAE;EACdmrB,UAAAA,OAAO,GAAGA,OAAO,CAAC7kB,IAAI,CAAC8kB,KAAK,CAACvrB,CAAC,EAAE,CAAC,EAAEurB,KAAK,CAACvrB,CAAC,EAAE,CAAC,CAAC,CAAA;EAChD,SAAA;EAEA,QAAA,OAAOsrB,OAAO,CAAA;EAChB,OAAA;QAEAnrB,GAAG,GAAG4qB,uBAAuB,CAAC5sB,MAAM,CAAA;QAEpC,IAAIie,SAAS,GAAGjU,MAAM,CAAA;QAEtB,OAAOnI,CAAC,GAAGG,GAAG,EAAE;EACd,QAAA,IAAMqrB,WAAW,GAAGT,uBAAuB,CAAC/qB,CAAC,EAAE,CAAC,CAAA;EAChD,QAAA,IAAMyrB,UAAU,GAAGV,uBAAuB,CAAC/qB,CAAC,EAAE,CAAC,CAAA;UAC/C,IAAI;EACFoc,UAAAA,SAAS,GAAGoP,WAAW,CAACpP,SAAS,CAAC,CAAA;WACnC,CAAC,OAAOpT,KAAK,EAAE;EACdyiB,UAAAA,UAAU,CAAClvB,IAAI,CAAC,IAAI,EAAEyM,KAAK,CAAC,CAAA;EAC5B,UAAA,MAAA;EACF,SAAA;EACF,OAAA;QAEA,IAAI;UACFsiB,OAAO,GAAGtC,eAAe,CAACzsB,IAAI,CAAC,IAAI,EAAE6f,SAAS,CAAC,CAAA;SAChD,CAAC,OAAOpT,KAAK,EAAE;EACd,QAAA,OAAOmU,OAAO,CAAChH,MAAM,CAACnN,KAAK,CAAC,CAAA;EAC9B,OAAA;EAEAhJ,MAAAA,CAAC,GAAG,CAAC,CAAA;QACLG,GAAG,GAAGirB,wBAAwB,CAACjtB,MAAM,CAAA;QAErC,OAAO6B,CAAC,GAAGG,GAAG,EAAE;EACdmrB,QAAAA,OAAO,GAAGA,OAAO,CAAC7kB,IAAI,CAAC2kB,wBAAwB,CAACprB,CAAC,EAAE,CAAC,EAAEorB,wBAAwB,CAACprB,CAAC,EAAE,CAAC,CAAC,CAAA;EACtF,OAAA;EAEA,MAAA,OAAOsrB,OAAO,CAAA;EAChB,KAAA;EAAC,GAAA,EAAA;MAAAlrB,GAAA,EAAA,QAAA;EAAA4B,IAAAA,KAAA,EAED,SAAA0pB,MAAOvjB,CAAAA,MAAM,EAAE;QACbA,MAAM,GAAGwS,WAAW,CAAC,IAAI,CAAClL,QAAQ,EAAEtH,MAAM,CAAC,CAAA;EAC3C,MAAA,IAAMwjB,QAAQ,GAAGrR,aAAa,CAACnS,MAAM,CAACiS,OAAO,EAAEjS,MAAM,CAACgE,GAAG,EAAEhE,MAAM,CAACqS,iBAAiB,CAAC,CAAA;QACpF,OAAOtO,QAAQ,CAACyf,QAAQ,EAAExjB,MAAM,CAAC2D,MAAM,EAAE3D,MAAM,CAACiT,gBAAgB,CAAC,CAAA;EACnE,KAAA;EAAC,GAAA,CAAA,CAAA,CAAA;EAAA,EAAA,OAAAkP,KAAA,CAAA;EAAA,CAGH,EAAA,CAAA;AACA9hB,SAAK,CAAC9I,OAAO,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAASksB,mBAAmBA,CAACxa,MAAM,EAAE;EACvF;IACAkZ,KAAK,CAACxuB,SAAS,CAACsV,MAAM,CAAC,GAAG,UAASjF,GAAG,EAAEhE,MAAM,EAAE;MAC9C,OAAO,IAAI,CAACC,OAAO,CAACuS,WAAW,CAACxS,MAAM,IAAI,EAAE,EAAE;EAC5CiJ,MAAAA,MAAM,EAANA,MAAM;EACNjF,MAAAA,GAAG,EAAHA,GAAG;EACHjF,MAAAA,IAAI,EAAE,CAACiB,MAAM,IAAI,EAAE,EAAEjB,IAAAA;EACvB,KAAC,CAAC,CAAC,CAAA;KACJ,CAAA;EACH,CAAC,CAAC,CAAA;AAEFsB,SAAK,CAAC9I,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,SAASmsB,qBAAqBA,CAACza,MAAM,EAAE;EAC7E;;IAEA,SAAS0a,kBAAkBA,CAACC,MAAM,EAAE;MAClC,OAAO,SAASC,UAAUA,CAAC7f,GAAG,EAAEjF,IAAI,EAAEiB,MAAM,EAAE;QAC5C,OAAO,IAAI,CAACC,OAAO,CAACuS,WAAW,CAACxS,MAAM,IAAI,EAAE,EAAE;EAC5CiJ,QAAAA,MAAM,EAANA,MAAM;UACNtB,OAAO,EAAEic,MAAM,GAAG;EAChB,UAAA,cAAc,EAAE,qBAAA;WACjB,GAAG,EAAE;EACN5f,QAAAA,GAAG,EAAHA,GAAG;EACHjF,QAAAA,IAAI,EAAJA,IAAAA;EACF,OAAC,CAAC,CAAC,CAAA;OACJ,CAAA;EACH,GAAA;IAEAojB,KAAK,CAACxuB,SAAS,CAACsV,MAAM,CAAC,GAAG0a,kBAAkB,EAAE,CAAA;IAE9CxB,KAAK,CAACxuB,SAAS,CAACsV,MAAM,GAAG,MAAM,CAAC,GAAG0a,kBAAkB,CAAC,IAAI,CAAC,CAAA;EAC7D,CAAC,CAAC,CAAA;AAEF,gBAAexB,KAAK;;EC3OpB;EACA;EACA;EACA;EACA;EACA;EACA;EANA,IAOM2B,WAAW,gBAAA,YAAA;IACf,SAAAA,WAAAA,CAAYC,QAAQ,EAAE;EAAAzf,IAAAA,eAAA,OAAAwf,WAAA,CAAA,CAAA;EACpB,IAAA,IAAI,OAAOC,QAAQ,KAAK,UAAU,EAAE;EAClC,MAAA,MAAM,IAAI7hB,SAAS,CAAC,8BAA8B,CAAC,CAAA;EACrD,KAAA;EAEA,IAAA,IAAI8hB,cAAc,CAAA;MAElB,IAAI,CAACb,OAAO,GAAG,IAAInO,OAAO,CAAC,SAASiP,eAAeA,CAAClW,OAAO,EAAE;EAC3DiW,MAAAA,cAAc,GAAGjW,OAAO,CAAA;EAC1B,KAAC,CAAC,CAAA;MAEF,IAAMpP,KAAK,GAAG,IAAI,CAAA;;EAElB;EACA,IAAA,IAAI,CAACwkB,OAAO,CAAC7kB,IAAI,CAAC,UAAAqZ,MAAM,EAAI;EAC1B,MAAA,IAAI,CAAChZ,KAAK,CAACulB,UAAU,EAAE,OAAA;EAEvB,MAAA,IAAIrsB,CAAC,GAAG8G,KAAK,CAACulB,UAAU,CAACluB,MAAM,CAAA;EAE/B,MAAA,OAAO6B,CAAC,EAAE,GAAG,CAAC,EAAE;EACd8G,QAAAA,KAAK,CAACulB,UAAU,CAACrsB,CAAC,CAAC,CAAC8f,MAAM,CAAC,CAAA;EAC7B,OAAA;QACAhZ,KAAK,CAACulB,UAAU,GAAG,IAAI,CAAA;EACzB,KAAC,CAAC,CAAA;;EAEF;EACA,IAAA,IAAI,CAACf,OAAO,CAAC7kB,IAAI,GAAG,UAAA6lB,WAAW,EAAI;EACjC,MAAA,IAAI9N,QAAQ,CAAA;EACZ;EACA,MAAA,IAAM8M,OAAO,GAAG,IAAInO,OAAO,CAAC,UAAAjH,OAAO,EAAI;EACrCpP,QAAAA,KAAK,CAACkZ,SAAS,CAAC9J,OAAO,CAAC,CAAA;EACxBsI,QAAAA,QAAQ,GAAGtI,OAAO,CAAA;EACpB,OAAC,CAAC,CAACzP,IAAI,CAAC6lB,WAAW,CAAC,CAAA;EAEpBhB,MAAAA,OAAO,CAACxL,MAAM,GAAG,SAAS3J,MAAMA,GAAG;EACjCrP,QAAAA,KAAK,CAACgX,WAAW,CAACU,QAAQ,CAAC,CAAA;SAC5B,CAAA;EAED,MAAA,OAAO8M,OAAO,CAAA;OACf,CAAA;MAEDY,QAAQ,CAAC,SAASpM,MAAMA,CAAC7X,OAAO,EAAEE,MAAM,EAAEC,OAAO,EAAE;QACjD,IAAItB,KAAK,CAAC2Z,MAAM,EAAE;EAChB;EACA,QAAA,OAAA;EACF,OAAA;QAEA3Z,KAAK,CAAC2Z,MAAM,GAAG,IAAI1K,aAAa,CAAC9N,OAAO,EAAEE,MAAM,EAAEC,OAAO,CAAC,CAAA;EAC1D+jB,MAAAA,cAAc,CAACrlB,KAAK,CAAC2Z,MAAM,CAAC,CAAA;EAC9B,KAAC,CAAC,CAAA;EACJ,GAAA;;EAEA;EACF;EACA;EAFE9T,EAAAA,YAAA,CAAAsf,WAAA,EAAA,CAAA;MAAA7rB,GAAA,EAAA,kBAAA;MAAA4B,KAAA,EAGA,SAAA+mB,gBAAAA,GAAmB;QACjB,IAAI,IAAI,CAACtI,MAAM,EAAE;UACf,MAAM,IAAI,CAACA,MAAM,CAAA;EACnB,OAAA;EACF,KAAA;;EAEA;EACF;EACA;EAFE,GAAA,EAAA;MAAArgB,GAAA,EAAA,WAAA;EAAA4B,IAAAA,KAAA,EAIA,SAAAge,SAAU9H,CAAAA,QAAQ,EAAE;QAClB,IAAI,IAAI,CAACuI,MAAM,EAAE;EACfvI,QAAAA,QAAQ,CAAC,IAAI,CAACuI,MAAM,CAAC,CAAA;EACrB,QAAA,OAAA;EACF,OAAA;QAEA,IAAI,IAAI,CAAC4L,UAAU,EAAE;EACnB,QAAA,IAAI,CAACA,UAAU,CAACvoB,IAAI,CAACoU,QAAQ,CAAC,CAAA;EAChC,OAAC,MAAM;EACL,QAAA,IAAI,CAACmU,UAAU,GAAG,CAACnU,QAAQ,CAAC,CAAA;EAC9B,OAAA;EACF,KAAA;;EAEA;EACF;EACA;EAFE,GAAA,EAAA;MAAA9X,GAAA,EAAA,aAAA;EAAA4B,IAAAA,KAAA,EAIA,SAAA8b,WAAY5F,CAAAA,QAAQ,EAAE;EACpB,MAAA,IAAI,CAAC,IAAI,CAACmU,UAAU,EAAE;EACpB,QAAA,OAAA;EACF,OAAA;QACA,IAAMhhB,KAAK,GAAG,IAAI,CAACghB,UAAU,CAACvpB,OAAO,CAACoV,QAAQ,CAAC,CAAA;EAC/C,MAAA,IAAI7M,KAAK,KAAK,CAAC,CAAC,EAAE;UAChB,IAAI,CAACghB,UAAU,CAACE,MAAM,CAAClhB,KAAK,EAAE,CAAC,CAAC,CAAA;EAClC,OAAA;EACF,KAAA;EAAC,GAAA,EAAA;MAAAjL,GAAA,EAAA,eAAA;MAAA4B,KAAA,EAED,SAAAslB,aAAAA,GAAgB;EAAA,MAAA,IAAAkF,KAAA,GAAA,IAAA,CAAA;EACd,MAAA,IAAMjM,UAAU,GAAG,IAAIC,eAAe,EAAE,CAAA;EAExC,MAAA,IAAMT,KAAK,GAAG,SAARA,KAAKA,CAAI/L,GAAG,EAAK;EACrBuM,QAAAA,UAAU,CAACR,KAAK,CAAC/L,GAAG,CAAC,CAAA;SACtB,CAAA;EAED,MAAA,IAAI,CAACgM,SAAS,CAACD,KAAK,CAAC,CAAA;EAErBQ,MAAAA,UAAU,CAACxC,MAAM,CAACD,WAAW,GAAG,YAAA;EAAA,QAAA,OAAM0O,KAAI,CAAC1O,WAAW,CAACiC,KAAK,CAAC,CAAA;EAAA,OAAA,CAAA;QAE7D,OAAOQ,UAAU,CAACxC,MAAM,CAAA;EAC1B,KAAA;;EAEA;EACF;EACA;EACA;EAHE,GAAA,CAAA,EAAA,CAAA;MAAA3d,GAAA,EAAA,QAAA;MAAA4B,KAAA,EAIA,SAAAoE,MAAAA,GAAgB;EACd,MAAA,IAAI0Z,MAAM,CAAA;QACV,IAAMhZ,KAAK,GAAG,IAAImlB,WAAW,CAAC,SAASC,QAAQA,CAACO,CAAC,EAAE;EACjD3M,QAAAA,MAAM,GAAG2M,CAAC,CAAA;EACZ,OAAC,CAAC,CAAA;QACF,OAAO;EACL3lB,QAAAA,KAAK,EAALA,KAAK;EACLgZ,QAAAA,MAAM,EAANA,MAAAA;SACD,CAAA;EACH,KAAA;EAAC,GAAA,CAAA,CAAA,CAAA;EAAA,EAAA,OAAAmM,WAAA,CAAA;EAAA,CAAA,EAAA,CAAA;AAGH,sBAAeA,WAAW;;ECpI1B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAASS,MAAMA,CAACC,QAAQ,EAAE;EACvC,EAAA,OAAO,SAASlxB,IAAIA,CAACuH,GAAG,EAAE;EACxB,IAAA,OAAO2pB,QAAQ,CAACjxB,KAAK,CAAC,IAAI,EAAEsH,GAAG,CAAC,CAAA;KACjC,CAAA;EACH;;ECvBA;EACA;EACA;EACA;EACA;EACA;EACA;EACe,SAAS4pB,YAAYA,CAACC,OAAO,EAAE;IAC5C,OAAOrkB,OAAK,CAAC1K,QAAQ,CAAC+uB,OAAO,CAAC,IAAKA,OAAO,CAACD,YAAY,KAAK,IAAK,CAAA;EACnE;;ECbA,IAAME,cAAc,GAAG;EACrBC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,kBAAkB,EAAE,GAAG;EACvBC,EAAAA,UAAU,EAAE,GAAG;EACfC,EAAAA,UAAU,EAAE,GAAG;EACfC,EAAAA,EAAE,EAAE,GAAG;EACPC,EAAAA,OAAO,EAAE,GAAG;EACZC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,2BAA2B,EAAE,GAAG;EAChCC,EAAAA,SAAS,EAAE,GAAG;EACdC,EAAAA,YAAY,EAAE,GAAG;EACjBC,EAAAA,cAAc,EAAE,GAAG;EACnBC,EAAAA,WAAW,EAAE,GAAG;EAChBC,EAAAA,eAAe,EAAE,GAAG;EACpBC,EAAAA,MAAM,EAAE,GAAG;EACXC,EAAAA,eAAe,EAAE,GAAG;EACpBC,EAAAA,gBAAgB,EAAE,GAAG;EACrBC,EAAAA,KAAK,EAAE,GAAG;EACVC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,WAAW,EAAE,GAAG;EAChBC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,MAAM,EAAE,GAAG;EACXC,EAAAA,iBAAiB,EAAE,GAAG;EACtBC,EAAAA,iBAAiB,EAAE,GAAG;EACtBC,EAAAA,UAAU,EAAE,GAAG;EACfC,EAAAA,YAAY,EAAE,GAAG;EACjBC,EAAAA,eAAe,EAAE,GAAG;EACpBC,EAAAA,SAAS,EAAE,GAAG;EACdC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,gBAAgB,EAAE,GAAG;EACrBC,EAAAA,aAAa,EAAE,GAAG;EAClBC,EAAAA,2BAA2B,EAAE,GAAG;EAChCC,EAAAA,cAAc,EAAE,GAAG;EACnBC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,IAAI,EAAE,GAAG;EACTC,EAAAA,cAAc,EAAE,GAAG;EACnBC,EAAAA,kBAAkB,EAAE,GAAG;EACvBC,EAAAA,eAAe,EAAE,GAAG;EACpBC,EAAAA,UAAU,EAAE,GAAG;EACfC,EAAAA,oBAAoB,EAAE,GAAG;EACzBC,EAAAA,mBAAmB,EAAE,GAAG;EACxBC,EAAAA,iBAAiB,EAAE,GAAG;EACtBC,EAAAA,SAAS,EAAE,GAAG;EACdC,EAAAA,kBAAkB,EAAE,GAAG;EACvBC,EAAAA,mBAAmB,EAAE,GAAG;EACxBC,EAAAA,MAAM,EAAE,GAAG;EACXC,EAAAA,gBAAgB,EAAE,GAAG;EACrBC,EAAAA,QAAQ,EAAE,GAAG;EACbC,EAAAA,eAAe,EAAE,GAAG;EACpBC,EAAAA,oBAAoB,EAAE,GAAG;EACzBC,EAAAA,eAAe,EAAE,GAAG;EACpBC,EAAAA,2BAA2B,EAAE,GAAG;EAChCC,EAAAA,0BAA0B,EAAE,GAAG;EAC/BC,EAAAA,mBAAmB,EAAE,GAAG;EACxBC,EAAAA,cAAc,EAAE,GAAG;EACnBC,EAAAA,UAAU,EAAE,GAAG;EACfC,EAAAA,kBAAkB,EAAE,GAAG;EACvBC,EAAAA,cAAc,EAAE,GAAG;EACnBC,EAAAA,uBAAuB,EAAE,GAAG;EAC5BC,EAAAA,qBAAqB,EAAE,GAAG;EAC1BC,EAAAA,mBAAmB,EAAE,GAAG;EACxBC,EAAAA,YAAY,EAAE,GAAG;EACjBC,EAAAA,WAAW,EAAE,GAAG;EAChBC,EAAAA,6BAA6B,EAAE,GAAA;EACjC,CAAC,CAAA;EAEDh1B,MAAM,CAACuT,OAAO,CAAC0d,cAAc,CAAC,CAACptB,OAAO,CAAC,UAAAE,IAAA,EAAkB;EAAA,EAAA,IAAAmB,KAAA,GAAA5B,cAAA,CAAAS,IAAA,EAAA,CAAA,CAAA;EAAhBQ,IAAAA,GAAG,GAAAW,KAAA,CAAA,CAAA,CAAA;EAAEiB,IAAAA,KAAK,GAAAjB,KAAA,CAAA,CAAA,CAAA,CAAA;EACjD+rB,EAAAA,cAAc,CAAC9qB,KAAK,CAAC,GAAG5B,GAAG,CAAA;EAC7B,CAAC,CAAC,CAAA;AAEF,yBAAe0sB,cAAc;;EClD7B;EACA;EACA;EACA;EACA;EACA;EACA;EACA,SAASgE,cAAcA,CAACC,aAAa,EAAE;EACrC,EAAA,IAAMlwB,OAAO,GAAG,IAAIypB,OAAK,CAACyG,aAAa,CAAC,CAAA;IACxC,IAAMC,QAAQ,GAAG11B,IAAI,CAACgvB,OAAK,CAACxuB,SAAS,CAACsM,OAAO,EAAEvH,OAAO,CAAC,CAAA;;EAEvD;IACA2H,OAAK,CAACpH,MAAM,CAAC4vB,QAAQ,EAAE1G,OAAK,CAACxuB,SAAS,EAAE+E,OAAO,EAAE;EAACd,IAAAA,UAAU,EAAE,IAAA;EAAI,GAAC,CAAC,CAAA;;EAEpE;IACAyI,OAAK,CAACpH,MAAM,CAAC4vB,QAAQ,EAAEnwB,OAAO,EAAE,IAAI,EAAE;EAACd,IAAAA,UAAU,EAAE,IAAA;EAAI,GAAC,CAAC,CAAA;;EAEzD;EACAixB,EAAAA,QAAQ,CAACt0B,MAAM,GAAG,SAASA,MAAMA,CAAC6tB,cAAc,EAAE;MAChD,OAAOuG,cAAc,CAACnW,WAAW,CAACoW,aAAa,EAAExG,cAAc,CAAC,CAAC,CAAA;KAClE,CAAA;EAED,EAAA,OAAOyG,QAAQ,CAAA;EACjB,CAAA;;EAEA;AACA,MAAMC,KAAK,GAAGH,cAAc,CAACrhB,UAAQ,EAAC;;EAEtC;EACAwhB,KAAK,CAAC3G,KAAK,GAAGA,OAAK,CAAA;;EAEnB;EACA2G,KAAK,CAAClb,aAAa,GAAGA,aAAa,CAAA;EACnCkb,KAAK,CAAChF,WAAW,GAAGA,aAAW,CAAA;EAC/BgF,KAAK,CAACpb,QAAQ,GAAGA,QAAQ,CAAA;EACzBob,KAAK,CAAC9H,OAAO,GAAGA,OAAO,CAAA;EACvB8H,KAAK,CAAC/mB,UAAU,GAAGA,UAAU,CAAA;;EAE7B;EACA+mB,KAAK,CAACjpB,UAAU,GAAGA,UAAU,CAAA;;EAE7B;EACAipB,KAAK,CAACC,MAAM,GAAGD,KAAK,CAAClb,aAAa,CAAA;;EAElC;EACAkb,KAAK,CAACE,GAAG,GAAG,SAASA,GAAGA,CAACC,QAAQ,EAAE;EACjC,EAAA,OAAOjU,OAAO,CAACgU,GAAG,CAACC,QAAQ,CAAC,CAAA;EAC9B,CAAC,CAAA;EAEDH,KAAK,CAACvE,MAAM,GAAGA,MAAM,CAAA;;EAErB;EACAuE,KAAK,CAACrE,YAAY,GAAGA,YAAY,CAAA;;EAEjC;EACAqE,KAAK,CAACtW,WAAW,GAAGA,WAAW,CAAA;EAE/BsW,KAAK,CAACpe,YAAY,GAAGA,cAAY,CAAA;EAEjCoe,KAAK,CAACI,UAAU,GAAG,UAAAh1B,KAAK,EAAA;EAAA,EAAA,OAAI2S,cAAc,CAACxG,OAAK,CAACzE,UAAU,CAAC1H,KAAK,CAAC,GAAG,IAAIwC,QAAQ,CAACxC,KAAK,CAAC,GAAGA,KAAK,CAAC,CAAA;EAAA,CAAA,CAAA;EAEjG40B,KAAK,CAAC1I,UAAU,GAAGC,QAAQ,CAACD,UAAU,CAAA;EAEtC0I,KAAK,CAACnE,cAAc,GAAGA,gBAAc,CAAA;EAErCmE,KAAK,CAAA,SAAA,CAAQ,GAAGA,KAAK;;;;;;;;"} \ No newline at end of file diff --git a/node_modules/axios/dist/axios.min.js b/node_modules/axios/dist/axios.min.js new file mode 100644 index 0000000..634ed55 --- /dev/null +++ b/node_modules/axios/dist/axios.min.js @@ -0,0 +1,3 @@ +/*! Axios v1.12.2 Copyright (c) 2025 Matt Zabriskie and contributors */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).axios=t()}(this,(function(){"use strict";function e(e){var r,n;function o(r,n){try{var a=e[r](n),s=a.value,u=s instanceof t;Promise.resolve(u?s.v:s).then((function(t){if(u){var n="return"===r?"return":"next";if(!s.k||t.done)return o(n,t);t=e[n](t).value}i(a.done?"return":"normal",t)}),(function(e){o("throw",e)}))}catch(e){i("throw",e)}}function i(e,t){switch(e){case"return":r.resolve({value:t,done:!0});break;case"throw":r.reject(t);break;default:r.resolve({value:t,done:!1})}(r=r.next)?o(r.key,r.arg):n=null}this._invoke=function(e,t){return new Promise((function(i,a){var s={key:e,arg:t,resolve:i,reject:a,next:null};n?n=n.next=s:(r=n=s,o(e,t))}))},"function"!=typeof e.return&&(this.return=void 0)}function t(e,t){this.v=e,this.k=t}function r(e){var r={},n=!1;function o(r,o){return n=!0,o=new Promise((function(t){t(e[r](o))})),{done:!1,value:new t(o,1)}}return r["undefined"!=typeof Symbol&&Symbol.iterator||"@@iterator"]=function(){return this},r.next=function(e){return n?(n=!1,e):o("next",e)},"function"==typeof e.throw&&(r.throw=function(e){if(n)throw n=!1,e;return o("throw",e)}),"function"==typeof e.return&&(r.return=function(e){return n?(n=!1,e):o("return",e)}),r}function n(e){var t,r,n,i=2;for("undefined"!=typeof Symbol&&(r=Symbol.asyncIterator,n=Symbol.iterator);i--;){if(r&&null!=(t=e[r]))return t.call(e);if(n&&null!=(t=e[n]))return new o(t.call(e));r="@@asyncIterator",n="@@iterator"}throw new TypeError("Object is not async iterable")}function o(e){function t(e){if(Object(e)!==e)return Promise.reject(new TypeError(e+" is not an object."));var t=e.done;return Promise.resolve(e.value).then((function(e){return{value:e,done:t}}))}return o=function(e){this.s=e,this.n=e.next},o.prototype={s:null,n:null,next:function(){return t(this.n.apply(this.s,arguments))},return:function(e){var r=this.s.return;return void 0===r?Promise.resolve({value:e,done:!0}):t(r.apply(this.s,arguments))},throw:function(e){var r=this.s.return;return void 0===r?Promise.reject(e):t(r.apply(this.s,arguments))}},new o(e)}function i(e){return new t(e,0)}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function s(e){for(var t=1;t=0;--i){var a=this.tryEntries[i],s=a.completion;if("root"===a.tryLoc)return o("end");if(a.tryLoc<=this.prev){var u=n.call(a,"catchLoc"),c=n.call(a,"finallyLoc");if(u&&c){if(this.prev=0;--r){var o=this.tryEntries[r];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--t){var r=this.tryEntries[t];if(r.finallyLoc===e)return this.complete(r.completion,r.afterLoc),A(r),y}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var r=this.tryEntries[t];if(r.tryLoc===e){var n=r.completion;if("throw"===n.type){var o=n.arg;A(r)}return o}}throw new Error("illegal catch attempt")},delegateYield:function(t,r,n){return this.delegate={iterator:L(t),resultName:r,nextLoc:n},"next"===this.method&&(this.arg=e),y}},t}function c(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var n=r.call(e,t||"default");if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"==typeof t?t:String(t)}function f(e){return f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},f(e)}function l(t){return function(){return new e(t.apply(this,arguments))}}function p(e,t,r,n,o,i,a){try{var s=e[i](a),u=s.value}catch(e){return void r(e)}s.done?t(u):Promise.resolve(u).then(n,o)}function h(e){return function(){var t=this,r=arguments;return new Promise((function(n,o){var i=e.apply(t,r);function a(e){p(i,n,o,a,s,"next",e)}function s(e){p(i,n,o,a,s,"throw",e)}a(void 0)}))}}function d(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function v(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=new Array(t);r2&&void 0!==arguments[2]?arguments[2]:{},i=o.allOwnKeys,a=void 0!==i&&i;if(null!=e)if("object"!==f(e)&&(e=[e]),L(e))for(r=0,n=e.length;r0;)if(t===(r=n[o]).toLowerCase())return r;return null}var Q="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,Z=function(e){return!N(e)&&e!==Q};var ee,te=(ee="undefined"!=typeof Uint8Array&&R(Uint8Array),function(e){return ee&&e instanceof ee}),re=A("HTMLFormElement"),ne=function(e){var t=Object.prototype.hasOwnProperty;return function(e,r){return t.call(e,r)}}(),oe=A("RegExp"),ie=function(e,t){var r=Object.getOwnPropertyDescriptors(e),n={};$(r,(function(r,o){var i;!1!==(i=t(r,o,e))&&(n[o]=i||r)})),Object.defineProperties(e,n)};var ae,se,ue,ce,fe=A("AsyncFunction"),le=(ae="function"==typeof setImmediate,se=F(Q.postMessage),ae?setImmediate:se?(ue="axios@".concat(Math.random()),ce=[],Q.addEventListener("message",(function(e){var t=e.source,r=e.data;t===Q&&r===ue&&ce.length&&ce.shift()()}),!1),function(e){ce.push(e),Q.postMessage(ue,"*")}):function(e){return setTimeout(e)}),pe="undefined"!=typeof queueMicrotask?queueMicrotask.bind(Q):"undefined"!=typeof process&&process.nextTick||le,he={isArray:L,isArrayBuffer:C,isBuffer:_,isFormData:function(e){var t;return e&&("function"==typeof FormData&&e instanceof FormData||F(e.append)&&("formdata"===(t=T(e))||"object"===t&&F(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&C(e.buffer)},isString:U,isNumber:B,isBoolean:function(e){return!0===e||!1===e},isObject:D,isPlainObject:I,isEmptyObject:function(e){if(!D(e)||_(e))return!1;try{return 0===Object.keys(e).length&&Object.getPrototypeOf(e)===Object.prototype}catch(e){return!1}},isReadableStream:K,isRequest:V,isResponse:G,isHeaders:X,isUndefined:N,isDate:q,isFile:M,isBlob:z,isRegExp:oe,isFunction:F,isStream:function(e){return D(e)&&F(e.pipe)},isURLSearchParams:J,isTypedArray:te,isFileList:H,forEach:$,merge:function e(){for(var t=Z(this)&&this||{},r=t.caseless,n=t.skipUndefined,o={},i=function(t,i){var a=r&&Y(o,i)||i;I(o[a])&&I(t)?o[a]=e(o[a],t):I(t)?o[a]=e({},t):L(t)?o[a]=t.slice():n&&N(t)||(o[a]=t)},a=0,s=arguments.length;a3&&void 0!==arguments[3]?arguments[3]:{},o=n.allOwnKeys;return $(t,(function(t,n){r&&F(t)?e[n]=O(t,r):e[n]=t}),{allOwnKeys:o}),e},trim:function(e){return e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")},stripBOM:function(e){return 65279===e.charCodeAt(0)&&(e=e.slice(1)),e},inherits:function(e,t,r,n){e.prototype=Object.create(t.prototype,n),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),r&&Object.assign(e.prototype,r)},toFlatObject:function(e,t,r,n){var o,i,a,s={};if(t=t||{},null==e)return t;do{for(i=(o=Object.getOwnPropertyNames(e)).length;i-- >0;)a=o[i],n&&!n(a,e,t)||s[a]||(t[a]=e[a],s[a]=!0);e=!1!==r&&R(e)}while(e&&(!r||r(e,t))&&e!==Object.prototype);return t},kindOf:T,kindOfTest:A,endsWith:function(e,t,r){e=String(e),(void 0===r||r>e.length)&&(r=e.length),r-=t.length;var n=e.indexOf(t,r);return-1!==n&&n===r},toArray:function(e){if(!e)return null;if(L(e))return e;var t=e.length;if(!B(t))return null;for(var r=new Array(t);t-- >0;)r[t]=e[t];return r},forEachEntry:function(e,t){for(var r,n=(e&&e[k]).call(e);(r=n.next())&&!r.done;){var o=r.value;t.call(e,o[0],o[1])}},matchAll:function(e,t){for(var r,n=[];null!==(r=e.exec(t));)n.push(r);return n},isHTMLForm:re,hasOwnProperty:ne,hasOwnProp:ne,reduceDescriptors:ie,freezeMethods:function(e){ie(e,(function(t,r){if(F(e)&&-1!==["arguments","caller","callee"].indexOf(r))return!1;var n=e[r];F(n)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=function(){throw Error("Can not rewrite read-only method '"+r+"'")}))}))},toObjectSet:function(e,t){var r={},n=function(e){e.forEach((function(e){r[e]=!0}))};return L(e)?n(e):n(String(e).split(t)),r},toCamelCase:function(e){return e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,r){return t.toUpperCase()+r}))},noop:function(){},toFiniteNumber:function(e,t){return null!=e&&Number.isFinite(e=+e)?e:t},findKey:Y,global:Q,isContextDefined:Z,isSpecCompliantForm:function(e){return!!(e&&F(e.append)&&"FormData"===e[j]&&e[k])},toJSONObject:function(e){var t=new Array(10);return function e(r,n){if(D(r)){if(t.indexOf(r)>=0)return;if(_(r))return r;if(!("toJSON"in r)){t[n]=r;var o=L(r)?[]:{};return $(r,(function(t,r){var i=e(t,n+1);!N(i)&&(o[r]=i)})),t[n]=void 0,o}}return r}(e,0)},isAsyncFn:fe,isThenable:function(e){return e&&(D(e)||F(e))&&F(e.then)&&F(e.catch)},setImmediate:le,asap:pe,isIterable:function(e){return null!=e&&F(e[k])}};function de(e,t,r,n,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),r&&(this.config=r),n&&(this.request=n),o&&(this.response=o,this.status=o.status?o.status:null)}he.inherits(de,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:he.toJSONObject(this.config),code:this.code,status:this.status}}});var ve=de.prototype,ye={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((function(e){ye[e]={value:e}})),Object.defineProperties(de,ye),Object.defineProperty(ve,"isAxiosError",{value:!0}),de.from=function(e,t,r,n,o,i){var a=Object.create(ve);he.toFlatObject(e,a,(function(e){return e!==Error.prototype}),(function(e){return"isAxiosError"!==e}));var s=e&&e.message?e.message:"Error",u=null==t&&e?e.code:t;return de.call(a,s,u,r,n,o),e&&null==a.cause&&Object.defineProperty(a,"cause",{value:e,configurable:!0}),a.name=e&&e.name||"Error",i&&Object.assign(a,i),a};function me(e){return he.isPlainObject(e)||he.isArray(e)}function be(e){return he.endsWith(e,"[]")?e.slice(0,-2):e}function ge(e,t,r){return e?e.concat(t).map((function(e,t){return e=be(e),!r&&t?"["+e+"]":e})).join(r?".":""):t}var we=he.toFlatObject(he,{},null,(function(e){return/^is[A-Z]/.test(e)}));function Ee(e,t,r){if(!he.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;var n=(r=he.toFlatObject(r,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!he.isUndefined(t[e])}))).metaTokens,o=r.visitor||c,i=r.dots,a=r.indexes,s=(r.Blob||"undefined"!=typeof Blob&&Blob)&&he.isSpecCompliantForm(t);if(!he.isFunction(o))throw new TypeError("visitor must be a function");function u(e){if(null===e)return"";if(he.isDate(e))return e.toISOString();if(he.isBoolean(e))return e.toString();if(!s&&he.isBlob(e))throw new de("Blob is not supported. Use a Buffer instead.");return he.isArrayBuffer(e)||he.isTypedArray(e)?s&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function c(e,r,o){var s=e;if(e&&!o&&"object"===f(e))if(he.endsWith(r,"{}"))r=n?r:r.slice(0,-2),e=JSON.stringify(e);else if(he.isArray(e)&&function(e){return he.isArray(e)&&!e.some(me)}(e)||(he.isFileList(e)||he.endsWith(r,"[]"))&&(s=he.toArray(e)))return r=be(r),s.forEach((function(e,n){!he.isUndefined(e)&&null!==e&&t.append(!0===a?ge([r],n,i):null===a?r:r+"[]",u(e))})),!1;return!!me(e)||(t.append(ge(o,r,i),u(e)),!1)}var l=[],p=Object.assign(we,{defaultVisitor:c,convertValue:u,isVisitable:me});if(!he.isObject(e))throw new TypeError("data must be an object");return function e(r,n){if(!he.isUndefined(r)){if(-1!==l.indexOf(r))throw Error("Circular reference detected in "+n.join("."));l.push(r),he.forEach(r,(function(r,i){!0===(!(he.isUndefined(r)||null===r)&&o.call(t,r,he.isString(i)?i.trim():i,n,p))&&e(r,n?n.concat(i):[i])})),l.pop()}}(e),t}function Oe(e){var t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function Se(e,t){this._pairs=[],e&&Ee(e,this,t)}var xe=Se.prototype;function Re(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function ke(e,t,r){if(!t)return e;var n=r&&r.encode||Re;he.isFunction(r)&&(r={serialize:r});var o,i=r&&r.serialize;if(o=i?i(t,r):he.isURLSearchParams(t)?t.toString():new Se(t,r).toString(n)){var a=e.indexOf("#");-1!==a&&(e=e.slice(0,a)),e+=(-1===e.indexOf("?")?"?":"&")+o}return e}xe.append=function(e,t){this._pairs.push([e,t])},xe.toString=function(e){var t=e?function(t){return e.call(this,t,Oe)}:Oe;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};var je=function(){function e(){d(this,e),this.handlers=[]}return y(e,[{key:"use",value:function(e,t,r){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!r&&r.synchronous,runWhen:r?r.runWhen:null}),this.handlers.length-1}},{key:"eject",value:function(e){this.handlers[e]&&(this.handlers[e]=null)}},{key:"clear",value:function(){this.handlers&&(this.handlers=[])}},{key:"forEach",value:function(e){he.forEach(this.handlers,(function(t){null!==t&&e(t)}))}}]),e}(),Te={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Ae={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:Se,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},Pe="undefined"!=typeof window&&"undefined"!=typeof document,Le="object"===("undefined"==typeof navigator?"undefined":f(navigator))&&navigator||void 0,Ne=Pe&&(!Le||["ReactNative","NativeScript","NS"].indexOf(Le.product)<0),_e="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,Ce=Pe&&window.location.href||"http://localhost",Ue=s(s({},Object.freeze({__proto__:null,hasBrowserEnv:Pe,hasStandardBrowserWebWorkerEnv:_e,hasStandardBrowserEnv:Ne,navigator:Le,origin:Ce})),Ae);function Fe(e){function t(e,r,n,o){var i=e[o++];if("__proto__"===i)return!0;var a=Number.isFinite(+i),s=o>=e.length;return i=!i&&he.isArray(n)?n.length:i,s?(he.hasOwnProp(n,i)?n[i]=[n[i],r]:n[i]=r,!a):(n[i]&&he.isObject(n[i])||(n[i]=[]),t(e,r,n[i],o)&&he.isArray(n[i])&&(n[i]=function(e){var t,r,n={},o=Object.keys(e),i=o.length;for(t=0;t-1,i=he.isObject(e);if(i&&he.isHTMLForm(e)&&(e=new FormData(e)),he.isFormData(e))return o?JSON.stringify(Fe(e)):e;if(he.isArrayBuffer(e)||he.isBuffer(e)||he.isStream(e)||he.isFile(e)||he.isBlob(e)||he.isReadableStream(e))return e;if(he.isArrayBufferView(e))return e.buffer;if(he.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return Ee(e,new Ue.classes.URLSearchParams,s({visitor:function(e,t,r,n){return Ue.isNode&&he.isBuffer(e)?(this.append(t,e.toString("base64")),!1):n.defaultVisitor.apply(this,arguments)}},t))}(e,this.formSerializer).toString();if((r=he.isFileList(e))||n.indexOf("multipart/form-data")>-1){var a=this.env&&this.env.FormData;return Ee(r?{"files[]":e}:e,a&&new a,this.formSerializer)}}return i||o?(t.setContentType("application/json",!1),function(e,t,r){if(he.isString(e))try{return(t||JSON.parse)(e),he.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(r||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){var t=this.transitional||Be.transitional,r=t&&t.forcedJSONParsing,n="json"===this.responseType;if(he.isResponse(e)||he.isReadableStream(e))return e;if(e&&he.isString(e)&&(r&&!this.responseType||n)){var o=!(t&&t.silentJSONParsing)&&n;try{return JSON.parse(e,this.parseReviver)}catch(e){if(o){if("SyntaxError"===e.name)throw de.from(e,de.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:Ue.classes.FormData,Blob:Ue.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};he.forEach(["delete","get","head","post","put","patch"],(function(e){Be.headers[e]={}}));var De=Be,Ie=he.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),qe=Symbol("internals");function Me(e){return e&&String(e).trim().toLowerCase()}function ze(e){return!1===e||null==e?e:he.isArray(e)?e.map(ze):String(e)}function He(e,t,r,n,o){return he.isFunction(n)?n.call(this,t,r):(o&&(t=r),he.isString(t)?he.isString(n)?-1!==t.indexOf(n):he.isRegExp(n)?n.test(t):void 0:void 0)}var Je=function(e,t){function r(e){d(this,r),e&&this.set(e)}return y(r,[{key:"set",value:function(e,t,r){var n=this;function o(e,t,r){var o=Me(t);if(!o)throw new Error("header name must be a non-empty string");var i=he.findKey(n,o);(!i||void 0===n[i]||!0===r||void 0===r&&!1!==n[i])&&(n[i||t]=ze(e))}var i=function(e,t){return he.forEach(e,(function(e,r){return o(e,r,t)}))};if(he.isPlainObject(e)||e instanceof this.constructor)i(e,t);else if(he.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))i(function(e){var t,r,n,o={};return e&&e.split("\n").forEach((function(e){n=e.indexOf(":"),t=e.substring(0,n).trim().toLowerCase(),r=e.substring(n+1).trim(),!t||o[t]&&Ie[t]||("set-cookie"===t?o[t]?o[t].push(r):o[t]=[r]:o[t]=o[t]?o[t]+", "+r:r)})),o}(e),t);else if(he.isObject(e)&&he.isIterable(e)){var a,s,u,c={},f=function(e,t){var r="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!r){if(Array.isArray(e)||(r=w(e))||t&&e&&"number"==typeof e.length){r&&(e=r);var n=0,o=function(){};return{s:o,n:function(){return n>=e.length?{done:!0}:{done:!1,value:e[n++]}},e:function(e){throw e},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,a=!0,s=!1;return{s:function(){r=r.call(e)},n:function(){var e=r.next();return a=e.done,e},e:function(e){s=!0,i=e},f:function(){try{a||null==r.return||r.return()}finally{if(s)throw i}}}}(e);try{for(f.s();!(u=f.n()).done;){var l=u.value;if(!he.isArray(l))throw TypeError("Object iterator must return a key-value pair");c[s=l[0]]=(a=c[s])?he.isArray(a)?[].concat(g(a),[l[1]]):[a,l[1]]:l[1]}}catch(e){f.e(e)}finally{f.f()}i(c,t)}else null!=e&&o(t,e,r);return this}},{key:"get",value:function(e,t){if(e=Me(e)){var r=he.findKey(this,e);if(r){var n=this[r];if(!t)return n;if(!0===t)return function(e){for(var t,r=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;t=n.exec(e);)r[t[1]]=t[2];return r}(n);if(he.isFunction(t))return t.call(this,n,r);if(he.isRegExp(t))return t.exec(n);throw new TypeError("parser must be boolean|regexp|function")}}}},{key:"has",value:function(e,t){if(e=Me(e)){var r=he.findKey(this,e);return!(!r||void 0===this[r]||t&&!He(0,this[r],r,t))}return!1}},{key:"delete",value:function(e,t){var r=this,n=!1;function o(e){if(e=Me(e)){var o=he.findKey(r,e);!o||t&&!He(0,r[o],o,t)||(delete r[o],n=!0)}}return he.isArray(e)?e.forEach(o):o(e),n}},{key:"clear",value:function(e){for(var t=Object.keys(this),r=t.length,n=!1;r--;){var o=t[r];e&&!He(0,this[o],o,e,!0)||(delete this[o],n=!0)}return n}},{key:"normalize",value:function(e){var t=this,r={};return he.forEach(this,(function(n,o){var i=he.findKey(r,o);if(i)return t[i]=ze(n),void delete t[o];var a=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(function(e,t,r){return t.toUpperCase()+r}))}(o):String(o).trim();a!==o&&delete t[o],t[a]=ze(n),r[a]=!0})),this}},{key:"concat",value:function(){for(var e,t=arguments.length,r=new Array(t),n=0;n1?r-1:0),o=1;o1&&void 0!==arguments[1]?arguments[1]:Date.now();o=i,r=null,n&&(clearTimeout(n),n=null),e.apply(void 0,g(t))};return[function(){for(var e=Date.now(),t=e-o,s=arguments.length,u=new Array(s),c=0;c=i?a(u,e):(r=u,n||(n=setTimeout((function(){n=null,a(r)}),i-t)))},function(){return r&&a(r)}]}he.inherits(Ge,de,{__CANCEL__:!0});var Qe=function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:3,n=0,o=$e(50,250);return Ye((function(r){var i=r.loaded,a=r.lengthComputable?r.total:void 0,s=i-n,u=o(s);n=i;var c=m({loaded:i,total:a,progress:a?i/a:void 0,bytes:s,rate:u||void 0,estimated:u&&a&&i<=a?(a-i)/u:void 0,event:r,lengthComputable:null!=a},t?"download":"upload",!0);e(c)}),r)},Ze=function(e,t){var r=null!=e;return[function(n){return t[0]({lengthComputable:r,total:e,loaded:n})},t[1]]},et=function(e){return function(){for(var t=arguments.length,r=new Array(t),n=0;n1?t-1:0),n=1;n1?"since :\n"+u.map(xt).join("\n"):" "+xt(u[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return n};function jt(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Ge(null,e)}function Tt(e){return jt(e),e.headers=We.from(e.headers),e.data=Ke.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),kt(e.adapter||De.adapter,e)(e).then((function(t){return jt(e),t.data=Ke.call(e,e.transformResponse,t),t.headers=We.from(t.headers),t}),(function(t){return Ve(t)||(jt(e),t&&t.response&&(t.response.data=Ke.call(e,e.transformResponse,t.response),t.response.headers=We.from(t.response.headers))),Promise.reject(t)}))}var At="1.12.2",Pt={};["object","boolean","number","function","string","symbol"].forEach((function(e,t){Pt[e]=function(r){return f(r)===e||"a"+(t<1?"n ":" ")+e}}));var Lt={};Pt.transitional=function(e,t,r){function n(e,t){return"[Axios v1.12.2] Transitional option '"+e+"'"+t+(r?". "+r:"")}return function(r,o,i){if(!1===e)throw new de(n(o," has been removed"+(t?" in "+t:"")),de.ERR_DEPRECATED);return t&&!Lt[o]&&(Lt[o]=!0,console.warn(n(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(r,o,i)}},Pt.spelling=function(e){return function(t,r){return console.warn("".concat(r," is likely a misspelling of ").concat(e)),!0}};var Nt={assertOptions:function(e,t,r){if("object"!==f(e))throw new de("options must be an object",de.ERR_BAD_OPTION_VALUE);for(var n=Object.keys(e),o=n.length;o-- >0;){var i=n[o],a=t[i];if(a){var s=e[i],u=void 0===s||a(s,i,e);if(!0!==u)throw new de("option "+i+" must be "+u,de.ERR_BAD_OPTION_VALUE)}else if(!0!==r)throw new de("Unknown option "+i,de.ERR_BAD_OPTION)}},validators:Pt},_t=Nt.validators,Ct=function(){function e(t){d(this,e),this.defaults=t||{},this.interceptors={request:new je,response:new je}}var t;return y(e,[{key:"request",value:(t=h(u().mark((function e(t,r){var n,o;return u().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,this._request(t,r);case 3:return e.abrupt("return",e.sent);case 6:if(e.prev=6,e.t0=e.catch(0),e.t0 instanceof Error){n={},Error.captureStackTrace?Error.captureStackTrace(n):n=new Error,o=n.stack?n.stack.replace(/^.+\n/,""):"";try{e.t0.stack?o&&!String(e.t0.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(e.t0.stack+="\n"+o):e.t0.stack=o}catch(e){}}throw e.t0;case 10:case"end":return e.stop()}}),e,this,[[0,6]])}))),function(e,r){return t.apply(this,arguments)})},{key:"_request",value:function(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{};var r=t=it(this.defaults,t),n=r.transitional,o=r.paramsSerializer,i=r.headers;void 0!==n&&Nt.assertOptions(n,{silentJSONParsing:_t.transitional(_t.boolean),forcedJSONParsing:_t.transitional(_t.boolean),clarifyTimeoutError:_t.transitional(_t.boolean)},!1),null!=o&&(he.isFunction(o)?t.paramsSerializer={serialize:o}:Nt.assertOptions(o,{encode:_t.function,serialize:_t.function},!0)),void 0!==t.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),Nt.assertOptions(t,{baseUrl:_t.spelling("baseURL"),withXsrfToken:_t.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();var a=i&&he.merge(i.common,i[t.method]);i&&he.forEach(["delete","get","head","post","put","patch","common"],(function(e){delete i[e]})),t.headers=We.concat(a,i);var s=[],u=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(u=u&&e.synchronous,s.unshift(e.fulfilled,e.rejected))}));var c,f=[];this.interceptors.response.forEach((function(e){f.push(e.fulfilled,e.rejected)}));var l,p=0;if(!u){var h=[Tt.bind(this),void 0];for(h.unshift.apply(h,s),h.push.apply(h,f),l=h.length,c=Promise.resolve(t);p0;)n._listeners[t](e);n._listeners=null}})),this.promise.then=function(e){var t,r=new Promise((function(e){n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},t((function(e,t,o){n.reason||(n.reason=new Ge(e,t,o),r(n.reason))}))}return y(e,[{key:"throwIfRequested",value:function(){if(this.reason)throw this.reason}},{key:"subscribe",value:function(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}},{key:"unsubscribe",value:function(e){if(this._listeners){var t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}}},{key:"toAbortSignal",value:function(){var e=this,t=new AbortController,r=function(e){t.abort(e)};return this.subscribe(r),t.signal.unsubscribe=function(){return e.unsubscribe(r)},t.signal}}],[{key:"source",value:function(){var t;return{token:new e((function(e){t=e})),cancel:t}}}]),e}(),Bt=Ft;var Dt={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Dt).forEach((function(e){var t=b(e,2),r=t[0],n=t[1];Dt[n]=r}));var It=Dt;var qt=function e(t){var r=new Ut(t),n=O(Ut.prototype.request,r);return he.extend(n,Ut.prototype,r,{allOwnKeys:!0}),he.extend(n,r,null,{allOwnKeys:!0}),n.create=function(r){return e(it(t,r))},n}(De);return qt.Axios=Ut,qt.CanceledError=Ge,qt.CancelToken=Bt,qt.isCancel=Ve,qt.VERSION=At,qt.toFormData=Ee,qt.AxiosError=de,qt.Cancel=qt.CanceledError,qt.all=function(e){return Promise.all(e)},qt.spread=function(e){return function(t){return e.apply(null,t)}},qt.isAxiosError=function(e){return he.isObject(e)&&!0===e.isAxiosError},qt.mergeConfig=it,qt.AxiosHeaders=We,qt.formToJSON=function(e){return Fe(he.isHTMLForm(e)?new FormData(e):e)},qt.getAdapter=kt,qt.HttpStatusCode=It,qt.default=qt,qt})); +//# sourceMappingURL=axios.min.js.map diff --git a/node_modules/axios/dist/axios.min.js.map b/node_modules/axios/dist/axios.min.js.map new file mode 100644 index 0000000..681183d --- /dev/null +++ b/node_modules/axios/dist/axios.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"axios.min.js","sources":["../lib/helpers/bind.js","../lib/utils.js","../lib/core/AxiosError.js","../lib/helpers/toFormData.js","../lib/helpers/AxiosURLSearchParams.js","../lib/helpers/buildURL.js","../lib/core/InterceptorManager.js","../lib/defaults/transitional.js","../lib/platform/browser/index.js","../lib/platform/browser/classes/URLSearchParams.js","../lib/platform/browser/classes/FormData.js","../lib/platform/browser/classes/Blob.js","../lib/platform/common/utils.js","../lib/platform/index.js","../lib/helpers/formDataToJSON.js","../lib/defaults/index.js","../lib/helpers/toURLEncodedForm.js","../lib/helpers/parseHeaders.js","../lib/core/AxiosHeaders.js","../lib/core/transformData.js","../lib/cancel/isCancel.js","../lib/cancel/CanceledError.js","../lib/core/settle.js","../lib/helpers/speedometer.js","../lib/helpers/throttle.js","../lib/helpers/progressEventReducer.js","../lib/helpers/isURLSameOrigin.js","../lib/helpers/cookies.js","../lib/core/buildFullPath.js","../lib/helpers/isAbsoluteURL.js","../lib/helpers/combineURLs.js","../lib/core/mergeConfig.js","../lib/helpers/resolveConfig.js","../lib/adapters/fetch.js","../lib/adapters/xhr.js","../lib/helpers/parseProtocol.js","../lib/helpers/composeSignals.js","../lib/helpers/trackStream.js","../lib/adapters/adapters.js","../lib/helpers/null.js","../lib/core/dispatchRequest.js","../lib/env/data.js","../lib/helpers/validator.js","../lib/core/Axios.js","../lib/cancel/CancelToken.js","../lib/helpers/HttpStatusCode.js","../lib/axios.js","../lib/helpers/spread.js","../lib/helpers/isAxiosError.js"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n // Early return for non-objects or Buffers to prevent RangeError\n if (!isObject(val) || isBuffer(val)) {\n return false;\n }\n\n try {\n return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n } catch (e) {\n // Fallback for any other objects that might cause RangeError with Object.keys()\n return false;\n }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Buffer check\n if (isBuffer(obj)) {\n return;\n }\n\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n if (isBuffer(obj)){\n return null;\n }\n\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else if (!skipUndefined || !isUndefined(val)) {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n //Buffer check\n if (isBuffer(source)) {\n return source;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isEmptyObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n const msg = error && error.message ? error.message : 'Error';\n\n // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n const errCode = code == null && error ? error.code : code;\n AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n if (error && axiosError.cause == null) {\n Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n }\n\n axiosError.name = (error && error.name) || 'Error';\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data, this.parseReviver);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), {\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n },\n ...options\n });\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn(...args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // browser handles it\n } else if (utils.isFunction(data.getHeaders)) {\n // Node.js FormData (like form-data package)\n const formHeaders = data.getHeaders();\n // Only set safe headers to avoid overwriting security headers\n const allowedHeaders = ['content-type', 'content-length'];\n Object.entries(formHeaders).forEach(([key, val]) => {\n if (allowedHeaders.includes(key.toLowerCase())) {\n headers.set(key, val);\n }\n });\n }\n } \n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n Request, Response\n}))(utils.global);\n\nconst {\n ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst factory = (env) => {\n env = utils.merge.call({\n skipUndefined: true\n }, globalFetchAPI, env);\n\n const {fetch: envFetch, Request, Response} = env;\n const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n const isRequestSupported = isFunction(Request);\n const isResponseSupported = isFunction(Response);\n\n if (!isFetchSupported) {\n return false;\n }\n\n const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n );\n\n const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n });\n\n const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n const resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n };\n\n isFetchSupported && ((() => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = (res, config) => {\n let method = res && res[type];\n\n if (method) {\n return method.call(res);\n }\n\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n })());\n\n const getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if (utils.isBlob(body)) {\n return body.size;\n }\n\n if (utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if (utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if (utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n }\n\n const resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n }\n\n return async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n let _fetch = envFetch || fetch;\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request = null;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n const resolvedOptions = {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n };\n\n request = isRequestSupported && new Request(url, resolvedOptions);\n\n let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n let env = config ? config.env : {};\n const {fetch, Request, Response} = env;\n const seeds = [\n Request, Response, fetch\n ];\n\n let len = seeds.length, i = len,\n seed, target, map = seedCache;\n\n while (i--) {\n seed = seeds[i];\n target = map.get(seed);\n\n target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n map = target;\n }\n\n return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError(event) {\n // Browsers deliver a ProgressEvent in XHR onerror\n // (message may be empty; when present, surface it)\n // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n const msg = event && event.message ? event.message : 'Network Error';\n const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n // attach the underlying event for consumers who want details\n err.event = event || null;\n reject(err);\n request = null;\n };\n \n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: {\n get: fetchAdapter.getFetch,\n }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters, config) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift(...requestInterceptorChain);\n chain.push(...responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n"],"names":["bind","fn","thisArg","apply","arguments","cache","toString","Object","prototype","getPrototypeOf","iterator","Symbol","toStringTag","kindOf","create","thing","str","call","slice","toLowerCase","kindOfTest","type","typeOfTest","_typeof","isArray","Array","isUndefined","isBuffer","val","constructor","isFunction","isArrayBuffer","isString","isNumber","isObject","isPlainObject","isDate","isFile","isBlob","isFileList","isURLSearchParams","_map2","_slicedToArray","map","isReadableStream","isRequest","isResponse","isHeaders","forEach","obj","i","l","_ref","length","undefined","_ref$allOwnKeys","allOwnKeys","key","keys","getOwnPropertyNames","len","findKey","_key","_global","globalThis","self","window","global","isContextDefined","context","TypedArray","isTypedArray","Uint8Array","isHTMLForm","hasOwnProperty","_ref4","prop","isRegExp","reduceDescriptors","reducer","descriptors","getOwnPropertyDescriptors","reducedDescriptors","descriptor","name","ret","defineProperties","setImmediateSupported","postMessageSupported","token","callbacks","isAsyncFn","_setImmediate","setImmediate","postMessage","concat","Math","random","addEventListener","_ref5","source","data","shift","cb","push","setTimeout","asap","queueMicrotask","process","nextTick","utils$1","isFormData","kind","FormData","append","isArrayBufferView","ArrayBuffer","isView","buffer","isBoolean","isEmptyObject","e","isStream","pipe","merge","_ref2","this","caseless","skipUndefined","result","assignValue","targetKey","extend","a","b","_ref3","trim","replace","stripBOM","content","charCodeAt","inherits","superConstructor","props","defineProperty","value","assign","toFlatObject","sourceObj","destObj","filter","propFilter","merged","endsWith","searchString","position","String","lastIndex","indexOf","toArray","arr","forEachEntry","_iterator","next","done","pair","matchAll","regExp","matches","exec","hasOwnProp","freezeMethods","enumerable","writable","set","Error","toObjectSet","arrayOrString","delimiter","define","split","toCamelCase","m","p1","p2","toUpperCase","noop","toFiniteNumber","defaultValue","Number","isFinite","isSpecCompliantForm","toJSONObject","stack","visit","target","reducedValue","isThenable","then","isIterable","AxiosError","message","code","config","request","response","captureStackTrace","status","utils","toJSON","description","number","fileName","lineNumber","columnNumber","from","error","customProps","axiosError","msg","errCode","cause","configurable","isVisitable","removeBrackets","renderKey","path","dots","join","predicates","test","toFormData","formData","options","TypeError","metaTokens","indexes","option","visitor","defaultVisitor","useBlob","Blob","convertValue","toISOString","Buffer","JSON","stringify","some","isFlatArray","el","index","exposedHelpers","build","pop","encode","charMap","encodeURIComponent","match","AxiosURLSearchParams","params","_pairs","buildURL","url","_encode","serialize","serializedParams","serializeFn","hashmarkIndex","encoder","InterceptorManager$1","InterceptorManager","_classCallCheck","handlers","_createClass","fulfilled","rejected","synchronous","runWhen","id","h","transitionalDefaults","silentJSONParsing","forcedJSONParsing","clarifyTimeoutError","platform$1","isBrowser","classes","URLSearchParams","protocols","hasBrowserEnv","document","_navigator","navigator","hasStandardBrowserEnv","product","hasStandardBrowserWebWorkerEnv","WorkerGlobalScope","importScripts","origin","location","href","_objectSpread","platform","formDataToJSON","buildPath","isNumericKey","isLast","arrayToObject","entries","parsePropPath","defaults","transitional","adapter","transformRequest","headers","contentType","getContentType","hasJSONContentType","isObjectPayload","setContentType","helpers","isNode","toURLEncodedForm","formSerializer","_FormData","env","rawValue","parser","parse","stringifySafely","transformResponse","JSONRequested","responseType","strictJSONParsing","parseReviver","ERR_BAD_RESPONSE","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","maxBodyLength","validateStatus","common","Accept","method","defaults$1","ignoreDuplicateOf","$internals","normalizeHeader","header","normalizeValue","matchHeaderValue","isHeaderNameFilter","AxiosHeaders","_Symbol$iterator","_Symbol$toStringTag","valueOrRewrite","rewrite","setHeader","_value","_header","_rewrite","lHeader","setHeaders","rawHeaders","parsed","line","substring","parseHeaders","dest","_step","_createForOfIteratorHelper","s","n","entry","_toConsumableArray","err","f","tokens","tokensRE","parseTokens","matcher","deleted","deleteHeader","format","normalized","w","char","formatHeader","_this$constructor","_len","targets","asStrings","get","first","computed","_len2","_key2","accessors","defineAccessor","accessorName","methodName","arg1","arg2","arg3","buildAccessors","accessor","mapped","headerValue","AxiosHeaders$1","transformData","fns","normalize","isCancel","__CANCEL__","CanceledError","ERR_CANCELED","settle","resolve","reject","ERR_BAD_REQUEST","floor","speedometer","samplesCount","min","firstSampleTS","bytes","timestamps","head","tail","chunkLength","now","Date","startedAt","bytesCount","passed","round","throttle","freq","lastArgs","timer","timestamp","threshold","invoke","args","clearTimeout","progressEventReducer","listener","isDownloadStream","bytesNotified","_speedometer","loaded","total","lengthComputable","progressBytes","rate","_defineProperty","progress","estimated","event","progressEventDecorator","throttled","asyncDecorator","isMSIE","URL","protocol","host","port","userAgent","write","expires","domain","secure","cookie","toGMTString","read","RegExp","decodeURIComponent","remove","buildFullPath","baseURL","requestedURL","allowAbsoluteUrls","isRelativeUrl","relativeURL","combineURLs","headersToObject","mergeConfig","config1","config2","getMergedValue","mergeDeepProperties","valueFromConfig2","defaultToConfig2","mergeDirectKeys","mergeMap","paramsSerializer","timeoutMessage","withCredentials","withXSRFToken","onUploadProgress","onDownloadProgress","decompress","beforeRedirect","transport","httpAgent","httpsAgent","cancelToken","socketPath","responseEncoding","configValue","resolveConfig","newConfig","auth","btoa","username","password","unescape","getHeaders","formHeaders","allowedHeaders","includes","isURLSameOrigin","xsrfValue","cookies","xhrAdapter","XMLHttpRequest","Promise","onCanceled","uploadThrottled","downloadThrottled","flushUpload","flushDownload","_config","requestData","requestHeaders","unsubscribe","signal","removeEventListener","onloadend","responseHeaders","getAllResponseHeaders","responseText","statusText","open","onreadystatechange","readyState","responseURL","onabort","ECONNABORTED","onerror","ERR_NETWORK","ontimeout","timeoutErrorMessage","ETIMEDOUT","setRequestHeader","_progressEventReducer2","upload","_progressEventReducer4","cancel","abort","subscribe","aborted","send","composeSignals$1","signals","Boolean","controller","AbortController","reason","streamChunk","_regeneratorRuntime","mark","chunk","chunkSize","pos","end","wrap","_context","prev","byteLength","abrupt","stop","readBytes","_wrapAsyncGenerator","_callee","iterable","_iteratorAbruptCompletion","_didIteratorError","_iteratorError","_context2","_asyncIterator","readStream","_awaitAsyncGenerator","sent","delegateYield","_asyncGeneratorDelegate","t1","finish","_x","_x2","_callee2","stream","reader","_yield$_awaitAsyncGen","_context3","asyncIterator","getReader","_x3","trackStream","onProgress","onFinish","_onFinish","ReadableStream","pull","_asyncToGenerator","_callee3","_yield$iterator$next","_done","loadedBytes","_context4","close","enqueue","t0","highWaterMark","globalFetchAPI","Request","Response","_utils$global","TextEncoder","factory","_env","envFetch","fetch","isFetchSupported","isRequestSupported","isResponseSupported","isReadableStreamSupported","encodeText","arrayBuffer","supportsRequestStream","duplexAccessed","hasContentType","body","duplex","has","supportsResponseStream","resolvers","res","ERR_NOT_SUPPORT","getBodyLength","_request","size","resolveBodyLength","getContentLength","_x4","_callee4","_resolveConfig","_resolveConfig$withCr","fetchOptions","_fetch","composedSignal","requestContentLength","contentTypeHeader","_progressEventDecorat","_progressEventDecorat2","flush","isCredentialsSupported","resolvedOptions","isStreamResponse","responseContentLength","_ref6","_ref7","_onProgress","_flush","responseData","composeSignals","toAbortSignal","credentials","t2","_x5","seedCache","Map","getFetch","seed","seeds","knownAdapters","http","xhr","fetchAdapter","renderReason","isResolvedHandle","adapters","nameOrAdapter","rejectedReasons","reasons","state","throwIfCancellationRequested","throwIfRequested","dispatchRequest","VERSION","validators","deprecatedWarnings","validators$1","validator","version","formatMessage","opt","desc","opts","ERR_DEPRECATED","console","warn","spelling","correctSpelling","assertOptions","schema","allowUnknown","ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","Axios","instanceConfig","interceptors","_request2","configOrUrl","dummy","baseUrl","withXsrfToken","contextHeaders","requestInterceptorChain","synchronousRequestInterceptors","interceptor","unshift","promise","responseInterceptorChain","chain","onFulfilled","onRejected","generateHTTPMethod","isForm","Axios$1","CancelToken","executor","resolvePromise","_listeners","onfulfilled","_resolve","splice","_this","c","CancelToken$1","HttpStatusCode","Continue","SwitchingProtocols","Processing","EarlyHints","Ok","Created","Accepted","NonAuthoritativeInformation","NoContent","ResetContent","PartialContent","MultiStatus","AlreadyReported","ImUsed","MultipleChoices","MovedPermanently","Found","SeeOther","NotModified","UseProxy","Unused","TemporaryRedirect","PermanentRedirect","BadRequest","Unauthorized","PaymentRequired","Forbidden","NotFound","MethodNotAllowed","NotAcceptable","ProxyAuthenticationRequired","RequestTimeout","Conflict","Gone","LengthRequired","PreconditionFailed","PayloadTooLarge","UriTooLong","UnsupportedMediaType","RangeNotSatisfiable","ExpectationFailed","ImATeapot","MisdirectedRequest","UnprocessableEntity","Locked","FailedDependency","TooEarly","UpgradeRequired","PreconditionRequired","TooManyRequests","RequestHeaderFieldsTooLarge","UnavailableForLegalReasons","InternalServerError","NotImplemented","BadGateway","ServiceUnavailable","GatewayTimeout","HttpVersionNotSupported","VariantAlsoNegotiates","InsufficientStorage","LoopDetected","NotExtended","NetworkAuthenticationRequired","HttpStatusCode$1","axios","createInstance","defaultConfig","instance","Cancel","all","promises","spread","callback","isAxiosError","payload","formToJSON","getAdapter"],"mappings":";+4XAEe,SAASA,EAAKC,EAAIC,GAC/B,OAAO,WACL,OAAOD,EAAGE,MAAMD,EAASE,WAE7B,mSCAA,IAIgBC,EAJTC,EAAYC,OAAOC,UAAnBF,SACAG,EAAkBF,OAAlBE,eACAC,EAAyBC,OAAzBD,SAAUE,EAAeD,OAAfC,YAEXC,GAAUR,EAGbE,OAAOO,OAAO,MAHQ,SAAAC,GACrB,IAAMC,EAAMV,EAASW,KAAKF,GAC1B,OAAOV,EAAMW,KAASX,EAAMW,GAAOA,EAAIE,MAAM,GAAI,GAAGC,iBAGlDC,EAAa,SAACC,GAElB,OADAA,EAAOA,EAAKF,cACL,SAACJ,GAAK,OAAKF,EAAOE,KAAWM,CAAI,CAC1C,EAEMC,EAAa,SAAAD,GAAI,OAAI,SAAAN,GAAK,OAAIQ,EAAOR,KAAUM,CAAI,CAAA,EASlDG,EAAWC,MAAXD,QASDE,EAAcJ,EAAW,aAS/B,SAASK,EAASC,GAChB,OAAe,OAARA,IAAiBF,EAAYE,IAA4B,OAApBA,EAAIC,cAAyBH,EAAYE,EAAIC,cACpFC,EAAWF,EAAIC,YAAYF,WAAaC,EAAIC,YAAYF,SAASC,EACxE,CASA,IAAMG,EAAgBX,EAAW,eA2BjC,IAAMY,EAAWV,EAAW,UAQtBQ,EAAaR,EAAW,YASxBW,EAAWX,EAAW,UAStBY,EAAW,SAACnB,GAAK,OAAe,OAAVA,GAAmC,WAAjBQ,EAAOR,EAAkB,EAiBjEoB,EAAgB,SAACP,GACrB,GAAoB,WAAhBf,EAAOe,GACT,OAAO,EAGT,IAAMpB,EAAYC,EAAemB,GACjC,QAAsB,OAAdpB,GAAsBA,IAAcD,OAAOC,WAAkD,OAArCD,OAAOE,eAAeD,IAA0BI,KAAegB,GAAUlB,KAAYkB,EACvJ,EA8BMQ,EAAShB,EAAW,QASpBiB,EAASjB,EAAW,QASpBkB,EAASlB,EAAW,QASpBmB,EAAanB,EAAW,YAsCxBoB,EAAoBpB,EAAW,mBAE4FqB,EAAAC,EAApE,CAAC,iBAAkB,UAAW,WAAY,WAAWC,IAAIvB,GAAW,GAA1HwB,EAAgBH,EAAA,GAAEI,EAASJ,EAAA,GAAEK,EAAUL,EAAA,GAAEM,EAASN,EAAA,GA2BzD,SAASO,EAAQC,EAAKhD,GAA+B,IAM/CiD,EACAC,EAP+CC,EAAAhD,UAAAiD,OAAA,QAAAC,IAAAlD,UAAA,GAAAA,UAAA,GAAJ,CAAE,EAAAmD,EAAAH,EAAxBI,WAAAA,OAAa,IAAHD,GAAQA,EAE3C,GAAIN,QAaJ,GALmB,WAAf1B,EAAO0B,KAETA,EAAM,CAACA,IAGLzB,EAAQyB,GAEV,IAAKC,EAAI,EAAGC,EAAIF,EAAII,OAAQH,EAAIC,EAAGD,IACjCjD,EAAGgB,KAAK,KAAMgC,EAAIC,GAAIA,EAAGD,OAEtB,CAEL,GAAItB,EAASsB,GACX,OAIF,IAEIQ,EAFEC,EAAOF,EAAajD,OAAOoD,oBAAoBV,GAAO1C,OAAOmD,KAAKT,GAClEW,EAAMF,EAAKL,OAGjB,IAAKH,EAAI,EAAGA,EAAIU,EAAKV,IACnBO,EAAMC,EAAKR,GACXjD,EAAGgB,KAAK,KAAMgC,EAAIQ,GAAMA,EAAKR,EAEjC,CACF,CAEA,SAASY,EAAQZ,EAAKQ,GACpB,GAAI9B,EAASsB,GACX,OAAO,KAGTQ,EAAMA,EAAItC,cAIV,IAHA,IAEI2C,EAFEJ,EAAOnD,OAAOmD,KAAKT,GACrBC,EAAIQ,EAAKL,OAENH,KAAM,GAEX,GAAIO,KADJK,EAAOJ,EAAKR,IACK/B,cACf,OAAO2C,EAGX,OAAO,IACT,CAEA,IAAMC,EAEsB,oBAAfC,WAAmCA,WACvB,oBAATC,KAAuBA,KAA0B,oBAAXC,OAAyBA,OAASC,OAGlFC,EAAmB,SAACC,GAAO,OAAM3C,EAAY2C,IAAYA,IAAYN,CAAO,EAoDlF,IA8HsBO,GAAhBC,IAAgBD,GAKG,oBAAfE,YAA8B/D,EAAe+D,YAH9C,SAAAzD,GACL,OAAOuD,IAAcvD,aAAiBuD,KA6CpCG,GAAarD,EAAW,mBAWxBsD,GAAkB,SAAAC,GAAA,IAAED,EAAmEnE,OAAOC,UAA1EkE,eAAc,OAAM,SAACzB,EAAK2B,GAAI,OAAKF,EAAezD,KAAKgC,EAAK2B,EAAK,CAAA,CAAnE,GASlBC,GAAWzD,EAAW,UAEtB0D,GAAoB,SAAC7B,EAAK8B,GAC9B,IAAMC,EAAczE,OAAO0E,0BAA0BhC,GAC/CiC,EAAqB,CAAA,EAE3BlC,EAAQgC,GAAa,SAACG,EAAYC,GAChC,IAAIC,GAC2C,KAA1CA,EAAMN,EAAQI,EAAYC,EAAMnC,MACnCiC,EAAmBE,GAAQC,GAAOF,EAEtC,IAEA5E,OAAO+E,iBAAiBrC,EAAKiC,EAC/B,EAkEA,IA4CwBK,GAAuBC,GAKbC,GAAOC,GAbnCC,GAAYvE,EAAW,iBAQvBwE,IAAkBL,GAkBE,mBAAjBM,aAlBsCL,GAmB7C1D,EAAWiC,EAAQ+B,aAlBfP,GACKM,aAGFL,IAAyBC,GAW/BM,SAAAA,OAAWC,KAAKC,UAXsBP,GAWV,GAV3B3B,EAAQmC,iBAAiB,WAAW,SAAAC,GAAoB,IAAlBC,EAAMD,EAANC,OAAQC,EAAIF,EAAJE,KACxCD,IAAWrC,GAAWsC,IAASZ,IACjCC,GAAUrC,QAAUqC,GAAUY,OAAVZ,EAEvB,IAAE,GAEI,SAACa,GACNb,GAAUc,KAAKD,GACfxC,EAAQ+B,YAAYL,GAAO,OAEI,SAACc,GAAE,OAAKE,WAAWF,EAAG,GAMrDG,GAAiC,oBAAnBC,eAClBA,eAAe3G,KAAK+D,GAAgC,oBAAZ6C,SAA2BA,QAAQC,UAAYjB,GAQ1EkB,GAAA,CACbtF,QAAAA,EACAO,cAAAA,EACAJ,SAAAA,EACAoF,WApgBiB,SAAChG,GAClB,IAAIiG,EACJ,OAAOjG,IACgB,mBAAbkG,UAA2BlG,aAAiBkG,UAClDnF,EAAWf,EAAMmG,UACY,cAA1BF,EAAOnG,EAAOE,KAEL,WAATiG,GAAqBlF,EAAWf,EAAMT,WAAkC,sBAArBS,EAAMT,YAIlE,EA0fE6G,kBAnpBF,SAA2BvF,GAOzB,MAL4B,oBAAhBwF,aAAiCA,YAAYC,OAC9CD,YAAYC,OAAOzF,GAElBA,GAASA,EAAI0F,QAAYvF,EAAcH,EAAI0F,OAGzD,EA4oBEtF,SAAAA,EACAC,SAAAA,EACAsF,UAnmBgB,SAAAxG,GAAK,OAAc,IAAVA,IAA4B,IAAVA,CAAe,EAomB1DmB,SAAAA,EACAC,cAAAA,EACAqF,cA7kBoB,SAAC5F,GAErB,IAAKM,EAASN,IAAQD,EAASC,GAC7B,OAAO,EAGT,IACE,OAAmC,IAA5BrB,OAAOmD,KAAK9B,GAAKyB,QAAgB9C,OAAOE,eAAemB,KAASrB,OAAOC,SAIhF,CAHE,MAAOiH,GAEP,OAAO,CACT,CACF,EAkkBE7E,iBAAAA,EACAC,UAAAA,EACAC,WAAAA,EACAC,UAAAA,EACArB,YAAAA,EACAU,OAAAA,EACAC,OAAAA,EACAC,OAAAA,EACAuC,SAAAA,GACA/C,WAAAA,EACA4F,SA/hBe,SAAC9F,GAAG,OAAKM,EAASN,IAAQE,EAAWF,EAAI+F,KAAK,EAgiB7DnF,kBAAAA,EACA+B,aAAAA,GACAhC,WAAAA,EACAS,QAAAA,EACA4E,MAxZF,SAASA,IAgBP,IAfA,IAAAC,EAAkCzD,EAAiB0D,OAASA,MAAQ,CAAE,EAA/DC,EAAQF,EAARE,SAAUC,EAAaH,EAAbG,cACXC,EAAS,CAAA,EACTC,EAAc,SAACtG,EAAK6B,GACxB,IAAM0E,EAAYJ,GAAYlE,EAAQoE,EAAQxE,IAAQA,EAClDtB,EAAc8F,EAAOE,KAAehG,EAAcP,GACpDqG,EAAOE,GAAaP,EAAMK,EAAOE,GAAYvG,GACpCO,EAAcP,GACvBqG,EAAOE,GAAaP,EAAM,CAAE,EAAEhG,GACrBJ,EAAQI,GACjBqG,EAAOE,GAAavG,EAAIV,QACd8G,GAAkBtG,EAAYE,KACxCqG,EAAOE,GAAavG,IAIfsB,EAAI,EAAGC,EAAI/C,UAAUiD,OAAQH,EAAIC,EAAGD,IAC3C9C,UAAU8C,IAAMF,EAAQ5C,UAAU8C,GAAIgF,GAExC,OAAOD,CACT,EAqYEG,OAzXa,SAACC,EAAGC,EAAGpI,GAA8B,IAAAqI,EAAAnI,UAAAiD,OAAA,QAAAC,IAAAlD,UAAA,GAAAA,UAAA,GAAP,CAAE,EAAfoD,EAAU+E,EAAV/E,WAQ9B,OAPAR,EAAQsF,GAAG,SAAC1G,EAAK6B,GACXvD,GAAW4B,EAAWF,GACxByG,EAAE5E,GAAOzD,EAAK4B,EAAK1B,GAEnBmI,EAAE5E,GAAO7B,CAEb,GAAG,CAAC4B,WAAAA,IACG6E,CACT,EAiXEG,KA9fW,SAACxH,GAAG,OAAKA,EAAIwH,KACxBxH,EAAIwH,OAASxH,EAAIyH,QAAQ,qCAAsC,GAAG,EA8flEC,SAzWe,SAACC,GAIhB,OAH8B,QAA1BA,EAAQC,WAAW,KACrBD,EAAUA,EAAQzH,MAAM,IAEnByH,CACT,EAqWEE,SA1Ve,SAAChH,EAAaiH,EAAkBC,EAAO/D,GACtDnD,EAAYrB,UAAYD,OAAOO,OAAOgI,EAAiBtI,UAAWwE,GAClEnD,EAAYrB,UAAUqB,YAAcA,EACpCtB,OAAOyI,eAAenH,EAAa,QAAS,CAC1CoH,MAAOH,EAAiBtI,YAE1BuI,GAASxI,OAAO2I,OAAOrH,EAAYrB,UAAWuI,EAChD,EAoVEI,aAzUmB,SAACC,EAAWC,EAASC,EAAQC,GAChD,IAAIR,EACA7F,EACA0B,EACE4E,EAAS,CAAA,EAIf,GAFAH,EAAUA,GAAW,GAEJ,MAAbD,EAAmB,OAAOC,EAE9B,EAAG,CAGD,IADAnG,GADA6F,EAAQxI,OAAOoD,oBAAoByF,IACzB/F,OACHH,KAAM,GACX0B,EAAOmE,EAAM7F,GACPqG,IAAcA,EAAW3E,EAAMwE,EAAWC,IAAcG,EAAO5E,KACnEyE,EAAQzE,GAAQwE,EAAUxE,GAC1B4E,EAAO5E,IAAQ,GAGnBwE,GAAuB,IAAXE,GAAoB7I,EAAe2I,EACjD,OAASA,KAAeE,GAAUA,EAAOF,EAAWC,KAAaD,IAAc7I,OAAOC,WAEtF,OAAO6I,CACT,EAkTExI,OAAAA,EACAO,WAAAA,EACAqI,SAzSe,SAACzI,EAAK0I,EAAcC,GACnC3I,EAAM4I,OAAO5I,SACIsC,IAAbqG,GAA0BA,EAAW3I,EAAIqC,UAC3CsG,EAAW3I,EAAIqC,QAEjBsG,GAAYD,EAAarG,OACzB,IAAMwG,EAAY7I,EAAI8I,QAAQJ,EAAcC,GAC5C,OAAsB,IAAfE,GAAoBA,IAAcF,CAC3C,EAkSEI,QAxRc,SAAChJ,GACf,IAAKA,EAAO,OAAO,KACnB,GAAIS,EAAQT,GAAQ,OAAOA,EAC3B,IAAImC,EAAInC,EAAMsC,OACd,IAAKpB,EAASiB,GAAI,OAAO,KAEzB,IADA,IAAM8G,EAAM,IAAIvI,MAAMyB,GACfA,KAAM,GACX8G,EAAI9G,GAAKnC,EAAMmC,GAEjB,OAAO8G,CACT,EA+QEC,aArPmB,SAAChH,EAAKhD,GAOzB,IANA,IAIIgI,EAFEiC,GAFYjH,GAAOA,EAAIvC,IAEDO,KAAKgC,IAIzBgF,EAASiC,EAAUC,UAAYlC,EAAOmC,MAAM,CAClD,IAAMC,EAAOpC,EAAOgB,MACpBhJ,EAAGgB,KAAKgC,EAAKoH,EAAK,GAAIA,EAAK,GAC7B,CACF,EA2OEC,SAjOe,SAACC,EAAQvJ,GAIxB,IAHA,IAAIwJ,EACER,EAAM,GAE4B,QAAhCQ,EAAUD,EAAOE,KAAKzJ,KAC5BgJ,EAAIxD,KAAKgE,GAGX,OAAOR,CACT,EAyNEvF,WAAAA,GACAC,eAAAA,GACAgG,WAAYhG,GACZI,kBAAAA,GACA6F,cAjLoB,SAAC1H,GACrB6B,GAAkB7B,GAAK,SAACkC,EAAYC,GAElC,GAAItD,EAAWmB,KAA6D,IAArD,CAAC,YAAa,SAAU,UAAU6G,QAAQ1E,GAC/D,OAAO,EAGT,IAAM6D,EAAQhG,EAAImC,GAEbtD,EAAWmH,KAEhB9D,EAAWyF,YAAa,EAEpB,aAAczF,EAChBA,EAAW0F,UAAW,EAInB1F,EAAW2F,MACd3F,EAAW2F,IAAM,WACf,MAAMC,MAAM,qCAAwC3F,EAAO,OAGjE,GACF,EA0JE4F,YAxJkB,SAACC,EAAeC,GAClC,IAAMjI,EAAM,CAAA,EAENkI,EAAS,SAACnB,GACdA,EAAIhH,SAAQ,SAAAiG,GACVhG,EAAIgG,IAAS,CACf,KAKF,OAFAzH,EAAQyJ,GAAiBE,EAAOF,GAAiBE,EAAOvB,OAAOqB,GAAeG,MAAMF,IAE7EjI,CACT,EA6IEoI,YA1NkB,SAAArK,GAClB,OAAOA,EAAIG,cAAcsH,QAAQ,yBAC/B,SAAkB6C,EAAGC,EAAIC,GACvB,OAAOD,EAAGE,cAAgBD,CAC5B,GAEJ,EAqNEE,KA5IW,aA6IXC,eA3IqB,SAAC1C,EAAO2C,GAC7B,OAAgB,MAAT3C,GAAiB4C,OAAOC,SAAS7C,GAASA,GAASA,EAAQ2C,CACpE,EA0IE/H,QAAAA,EACAM,OAAQJ,EACRK,iBAAAA,EACA2H,oBAlIF,SAA6BhL,GAC3B,SAAUA,GAASe,EAAWf,EAAMmG,SAAkC,aAAvBnG,EAAMH,IAA+BG,EAAML,GAC5F,EAiIEsL,aA/HmB,SAAC/I,GACpB,IAAMgJ,EAAQ,IAAIxK,MAAM,IAgCxB,OA9Bc,SAARyK,EAAS9F,EAAQlD,GAErB,GAAIhB,EAASkE,GAAS,CACpB,GAAI6F,EAAMnC,QAAQ1D,IAAW,EAC3B,OAIF,GAAIzE,EAASyE,GACX,OAAOA,EAGT,KAAK,WAAYA,GAAS,CACxB6F,EAAM/I,GAAKkD,EACX,IAAM+F,EAAS3K,EAAQ4E,GAAU,GAAK,CAAA,EAStC,OAPApD,EAAQoD,GAAQ,SAAC6C,EAAOxF,GACtB,IAAM2I,EAAeF,EAAMjD,EAAO/F,EAAI,IACrCxB,EAAY0K,KAAkBD,EAAO1I,GAAO2I,EAC/C,IAEAH,EAAM/I,QAAKI,EAEJ6I,CACT,CACF,CAEA,OAAO/F,EAGF8F,CAAMjJ,EAAK,EACpB,EA8FE0C,UAAAA,GACA0G,WA3FiB,SAACtL,GAAK,OACvBA,IAAUmB,EAASnB,IAAUe,EAAWf,KAAWe,EAAWf,EAAMuL,OAASxK,EAAWf,EAAK,MAAO,EA2FpG8E,aAAcD,GACdc,KAAAA,GACA6F,WA5DiB,SAACxL,GAAK,OAAc,MAATA,GAAiBe,EAAWf,EAAML,GAAU,GCjsB1E,SAAS8L,GAAWC,EAASC,EAAMC,EAAQC,EAASC,GAClD9B,MAAM9J,KAAK6G,MAEPiD,MAAM+B,kBACR/B,MAAM+B,kBAAkBhF,KAAMA,KAAKjG,aAEnCiG,KAAKmE,OAAS,IAAIlB,OAASkB,MAG7BnE,KAAK2E,QAAUA,EACf3E,KAAK1C,KAAO,aACZsH,IAAS5E,KAAK4E,KAAOA,GACrBC,IAAW7E,KAAK6E,OAASA,GACzBC,IAAY9E,KAAK8E,QAAUA,GACvBC,IACF/E,KAAK+E,SAAWA,EAChB/E,KAAKiF,OAASF,EAASE,OAASF,EAASE,OAAS,KAEtD,CAEAC,GAAMnE,SAAS2D,GAAYzB,MAAO,CAChCkC,OAAQ,WACN,MAAO,CAELR,QAAS3E,KAAK2E,QACdrH,KAAM0C,KAAK1C,KAEX8H,YAAapF,KAAKoF,YAClBC,OAAQrF,KAAKqF,OAEbC,SAAUtF,KAAKsF,SACfC,WAAYvF,KAAKuF,WACjBC,aAAcxF,KAAKwF,aACnBrB,MAAOnE,KAAKmE,MAEZU,OAAQK,GAAMhB,aAAalE,KAAK6E,QAChCD,KAAM5E,KAAK4E,KACXK,OAAQjF,KAAKiF,OAEjB,IAGF,IAAMvM,GAAYgM,GAAWhM,UACvBwE,GAAc,CAAA,EAEpB,CACE,uBACA,iBACA,eACA,YACA,cACA,4BACA,iBACA,mBACA,kBACA,eACA,kBACA,mBAEAhC,SAAQ,SAAA0J,GACR1H,GAAY0H,GAAQ,CAACzD,MAAOyD,EAC9B,IAEAnM,OAAO+E,iBAAiBkH,GAAYxH,IACpCzE,OAAOyI,eAAexI,GAAW,eAAgB,CAACyI,OAAO,IAGzDuD,GAAWe,KAAO,SAACC,EAAOd,EAAMC,EAAQC,EAASC,EAAUY,GACzD,IAAMC,EAAanN,OAAOO,OAAON,IAEjCwM,GAAM7D,aAAaqE,EAAOE,GAAY,SAAgBzK,GACpD,OAAOA,IAAQ8H,MAAMvK,SACtB,IAAE,SAAAoE,GACD,MAAgB,iBAATA,CACT,IAEA,IAAM+I,EAAMH,GAASA,EAAMf,QAAUe,EAAMf,QAAU,QAG/CmB,EAAkB,MAARlB,GAAgBc,EAAQA,EAAMd,KAAOA,EAYrD,OAXAF,GAAWvL,KAAKyM,EAAYC,EAAKC,EAASjB,EAAQC,EAASC,GAGvDW,GAA6B,MAApBE,EAAWG,OACtBtN,OAAOyI,eAAe0E,EAAY,QAAS,CAAEzE,MAAOuE,EAAOM,cAAc,IAG3EJ,EAAWtI,KAAQoI,GAASA,EAAMpI,MAAS,QAE3CqI,GAAelN,OAAO2I,OAAOwE,EAAYD,GAElCC,CACT,EC7FA,SAASK,GAAYhN,GACnB,OAAOiM,GAAM7K,cAAcpB,IAAUiM,GAAMxL,QAAQT,EACrD,CASA,SAASiN,GAAevK,GACtB,OAAOuJ,GAAMvD,SAAShG,EAAK,MAAQA,EAAIvC,MAAM,GAAI,GAAKuC,CACxD,CAWA,SAASwK,GAAUC,EAAMzK,EAAK0K,GAC5B,OAAKD,EACEA,EAAKnI,OAAOtC,GAAKd,KAAI,SAAc8C,EAAOvC,GAG/C,OADAuC,EAAQuI,GAAevI,IACf0I,GAAQjL,EAAI,IAAMuC,EAAQ,IAAMA,CACzC,IAAE2I,KAAKD,EAAO,IAAM,IALH1K,CAMpB,CAaA,IAAM4K,GAAarB,GAAM7D,aAAa6D,GAAO,CAAE,EAAE,MAAM,SAAgBpI,GACrE,MAAO,WAAW0J,KAAK1J,EACzB,IAyBA,SAAS2J,GAAWtL,EAAKuL,EAAUC,GACjC,IAAKzB,GAAM9K,SAASe,GAClB,MAAM,IAAIyL,UAAU,4BAItBF,EAAWA,GAAY,IAAyBvH,SAYhD,IAAM0H,GATNF,EAAUzB,GAAM7D,aAAasF,EAAS,CACpCE,YAAY,EACZR,MAAM,EACNS,SAAS,IACR,GAAO,SAAiBC,EAAQzI,GAEjC,OAAQ4G,GAAMtL,YAAY0E,EAAOyI,GACnC,KAE2BF,WAErBG,EAAUL,EAAQK,SAAWC,EAC7BZ,EAAOM,EAAQN,KACfS,EAAUH,EAAQG,QAElBI,GADQP,EAAQQ,MAAwB,oBAATA,MAAwBA,OACpCjC,GAAMjB,oBAAoByC,GAEnD,IAAKxB,GAAMlL,WAAWgN,GACpB,MAAM,IAAIJ,UAAU,8BAGtB,SAASQ,EAAajG,GACpB,GAAc,OAAVA,EAAgB,MAAO,GAE3B,GAAI+D,GAAM5K,OAAO6G,GACf,OAAOA,EAAMkG,cAGf,GAAInC,GAAMzF,UAAU0B,GAClB,OAAOA,EAAM3I,WAGf,IAAK0O,GAAWhC,GAAM1K,OAAO2G,GAC3B,MAAM,IAAIuD,GAAW,gDAGvB,OAAIQ,GAAMjL,cAAckH,IAAU+D,GAAMzI,aAAa0E,GAC5C+F,GAA2B,mBAATC,KAAsB,IAAIA,KAAK,CAAChG,IAAUmG,OAAO7B,KAAKtE,GAG1EA,CACT,CAYA,SAAS8F,EAAe9F,EAAOxF,EAAKyK,GAClC,IAAIlE,EAAMf,EAEV,GAAIA,IAAUiF,GAAyB,WAAjB3M,EAAO0H,GAC3B,GAAI+D,GAAMvD,SAAShG,EAAK,MAEtBA,EAAMkL,EAAalL,EAAMA,EAAIvC,MAAM,GAAI,GAEvC+H,EAAQoG,KAAKC,UAAUrG,QAClB,GACJ+D,GAAMxL,QAAQyH,IAvGvB,SAAqBe,GACnB,OAAOgD,GAAMxL,QAAQwI,KAASA,EAAIuF,KAAKxB,GACzC,CAqGiCyB,CAAYvG,KACnC+D,GAAMzK,WAAW0G,IAAU+D,GAAMvD,SAAShG,EAAK,SAAWuG,EAAMgD,GAAMjD,QAAQd,IAYhF,OATAxF,EAAMuK,GAAevK,GAErBuG,EAAIhH,SAAQ,SAAcyM,EAAIC,IAC1B1C,GAAMtL,YAAY+N,IAAc,OAAPA,GAAgBjB,EAAStH,QAEtC,IAAZ0H,EAAmBX,GAAU,CAACxK,GAAMiM,EAAOvB,GAAqB,OAAZS,EAAmBnL,EAAMA,EAAM,KACnFyL,EAAaO,GAEjB,KACO,EAIX,QAAI1B,GAAY9E,KAIhBuF,EAAStH,OAAO+G,GAAUC,EAAMzK,EAAK0K,GAAOe,EAAajG,KAElD,EACT,CAEA,IAAMgD,EAAQ,GAER0D,EAAiBpP,OAAO2I,OAAOmF,GAAY,CAC/CU,eAAAA,EACAG,aAAAA,EACAnB,YAAAA,KAyBF,IAAKf,GAAM9K,SAASe,GAClB,MAAM,IAAIyL,UAAU,0BAKtB,OA5BA,SAASkB,EAAM3G,EAAOiF,GACpB,IAAIlB,GAAMtL,YAAYuH,GAAtB,CAEA,IAA8B,IAA1BgD,EAAMnC,QAAQb,GAChB,MAAM8B,MAAM,kCAAoCmD,EAAKE,KAAK,MAG5DnC,EAAMzF,KAAKyC,GAEX+D,GAAMhK,QAAQiG,GAAO,SAAcwG,EAAIhM,IAKtB,OAJEuJ,GAAMtL,YAAY+N,IAAc,OAAPA,IAAgBX,EAAQ7N,KAChEuN,EAAUiB,EAAIzC,GAAMhL,SAASyB,GAAOA,EAAI+E,OAAS/E,EAAKyK,EAAMyB,KAI5DC,EAAMH,EAAIvB,EAAOA,EAAKnI,OAAOtC,GAAO,CAACA,GAEzC,IAEAwI,EAAM4D,KAlBwB,CAmBhC,CAMAD,CAAM3M,GAECuL,CACT,CChNA,SAASsB,GAAO9O,GACd,IAAM+O,EAAU,CACd,IAAK,MACL,IAAK,MACL,IAAK,MACL,IAAK,MACL,IAAK,MACL,MAAO,IACP,MAAO,MAET,OAAOC,mBAAmBhP,GAAKyH,QAAQ,oBAAoB,SAAkBwH,GAC3E,OAAOF,EAAQE,EACjB,GACF,CAUA,SAASC,GAAqBC,EAAQ1B,GACpC3G,KAAKsI,OAAS,GAEdD,GAAU5B,GAAW4B,EAAQrI,KAAM2G,EACrC,CAEA,IAAMjO,GAAY0P,GAAqB1P,UC5BvC,SAASsP,GAAOlO,GACd,OAAOoO,mBAAmBpO,GACxB6G,QAAQ,QAAS,KACjBA,QAAQ,OAAQ,KAChBA,QAAQ,QAAS,KACjBA,QAAQ,OAAQ,IACpB,CAWe,SAAS4H,GAASC,EAAKH,EAAQ1B,GAE5C,IAAK0B,EACH,OAAOG,EAGT,IAAMC,EAAU9B,GAAWA,EAAQqB,QAAUA,GAEzC9C,GAAMlL,WAAW2M,KACnBA,EAAU,CACR+B,UAAW/B,IAIf,IAEIgC,EAFEC,EAAcjC,GAAWA,EAAQ+B,UAYvC,GAPEC,EADEC,EACiBA,EAAYP,EAAQ1B,GAEpBzB,GAAMxK,kBAAkB2N,GACzCA,EAAO7P,WACP,IAAI4P,GAAqBC,EAAQ1B,GAASnO,SAASiQ,GAGjC,CACpB,IAAMI,EAAgBL,EAAIxG,QAAQ,MAEX,IAAnB6G,IACFL,EAAMA,EAAIpP,MAAM,EAAGyP,IAErBL,KAA8B,IAAtBA,EAAIxG,QAAQ,KAAc,IAAM,KAAO2G,CACjD,CAEA,OAAOH,CACT,CDvBA9P,GAAU0G,OAAS,SAAgB9B,EAAM6D,GACvCnB,KAAKsI,OAAO5J,KAAK,CAACpB,EAAM6D,GAC1B,EAEAzI,GAAUF,SAAW,SAAkBsQ,GACrC,IAAML,EAAUK,EAAU,SAAS3H,GACjC,OAAO2H,EAAQ3P,KAAK6G,KAAMmB,EAAO6G,GAClC,EAAGA,GAEJ,OAAOhI,KAAKsI,OAAOzN,KAAI,SAAc0H,GACnC,OAAOkG,EAAQlG,EAAK,IAAM,IAAMkG,EAAQlG,EAAK,GAC9C,GAAE,IAAI+D,KAAK,IACd,EErDkC,IAoElCyC,GAlEwB,WACtB,SAAAC,IAAcC,OAAAD,GACZhJ,KAAKkJ,SAAW,EAClB,CA4DC,OA1DDC,EAAAH,EAAA,CAAA,CAAArN,IAAA,MAAAwF,MAQA,SAAIiI,EAAWC,EAAU1C,GAOvB,OANA3G,KAAKkJ,SAASxK,KAAK,CACjB0K,UAAAA,EACAC,SAAAA,EACAC,cAAa3C,GAAUA,EAAQ2C,YAC/BC,QAAS5C,EAAUA,EAAQ4C,QAAU,OAEhCvJ,KAAKkJ,SAAS3N,OAAS,CAChC,GAEA,CAAAI,IAAA,QAAAwF,MAOA,SAAMqI,GACAxJ,KAAKkJ,SAASM,KAChBxJ,KAAKkJ,SAASM,GAAM,KAExB,GAEA,CAAA7N,IAAA,QAAAwF,MAKA,WACMnB,KAAKkJ,WACPlJ,KAAKkJ,SAAW,GAEpB,GAEA,CAAAvN,IAAA,UAAAwF,MAUA,SAAQhJ,GACN+M,GAAMhK,QAAQ8E,KAAKkJ,UAAU,SAAwBO,GACzC,OAANA,GACFtR,EAAGsR,EAEP,GACF,KAACT,CAAA,CA/DqB,GCFTU,GAAA,CACbC,mBAAmB,EACnBC,mBAAmB,EACnBC,qBAAqB,GCDRC,GAAA,CACbC,WAAW,EACXC,QAAS,CACPC,gBCJsC,oBAApBA,gBAAkCA,gBAAkB7B,GDKtEjJ,SEN+B,oBAAbA,SAA2BA,SAAW,KFOxDgI,KGP2B,oBAATA,KAAuBA,KAAO,MHSlD+C,UAAW,CAAC,OAAQ,QAAS,OAAQ,OAAQ,MAAO,SIXhDC,GAAkC,oBAAX/N,QAA8C,oBAAbgO,SAExDC,GAAkC,YAAL5Q,oBAAT6Q,UAAS7Q,YAAAA,EAAT6Q,aAA0BA,gBAAa9O,EAmB3D+O,GAAwBJ,MAC1BE,IAAc,CAAC,cAAe,eAAgB,MAAMrI,QAAQqI,GAAWG,SAAW,GAWhFC,GAE2B,oBAAtBC,mBAEPvO,gBAAgBuO,mBACc,mBAAvBvO,KAAKwO,cAIVC,GAAST,IAAiB/N,OAAOyO,SAASC,MAAQ,mBCvCxDC,GAAAA,EAAAA,EACK7F,CAAAA,sIACA8F,IC2CL,SAASC,GAAevE,GACtB,SAASwE,EAAU9E,EAAMjF,EAAOkD,EAAQuD,GACtC,IAAItK,EAAO8I,EAAKwB,KAEhB,GAAa,cAATtK,EAAsB,OAAO,EAEjC,IAAM6N,EAAepH,OAAOC,UAAU1G,GAChC8N,EAASxD,GAASxB,EAAK7K,OAG7B,OAFA+B,GAAQA,GAAQ4H,GAAMxL,QAAQ2K,GAAUA,EAAO9I,OAAS+B,EAEpD8N,GACElG,GAAMtC,WAAWyB,EAAQ/G,GAC3B+G,EAAO/G,GAAQ,CAAC+G,EAAO/G,GAAO6D,GAE9BkD,EAAO/G,GAAQ6D,GAGTgK,IAGL9G,EAAO/G,IAAU4H,GAAM9K,SAASiK,EAAO/G,MAC1C+G,EAAO/G,GAAQ,IAGF4N,EAAU9E,EAAMjF,EAAOkD,EAAO/G,GAAOsK,IAEtC1C,GAAMxL,QAAQ2K,EAAO/G,MACjC+G,EAAO/G,GA/Cb,SAAuB4E,GACrB,IAEI9G,EAEAO,EAJER,EAAM,CAAA,EACNS,EAAOnD,OAAOmD,KAAKsG,GAEnBpG,EAAMF,EAAKL,OAEjB,IAAKH,EAAI,EAAGA,EAAIU,EAAKV,IAEnBD,EADAQ,EAAMC,EAAKR,IACA8G,EAAIvG,GAEjB,OAAOR,CACT,CAoCqBkQ,CAAchH,EAAO/G,MAG9B6N,EACV,CAEA,GAAIjG,GAAMjG,WAAWyH,IAAaxB,GAAMlL,WAAW0M,EAAS4E,SAAU,CACpE,IAAMnQ,EAAM,CAAA,EAMZ,OAJA+J,GAAM/C,aAAauE,GAAU,SAACpJ,EAAM6D,GAClC+J,EA1EN,SAAuB5N,GAKrB,OAAO4H,GAAM1C,SAAS,gBAAiBlF,GAAMzC,KAAI,SAAAsN,GAC/C,MAAoB,OAAbA,EAAM,GAAc,GAAKA,EAAM,IAAMA,EAAM,EACpD,GACF,CAkEgBoD,CAAcjO,GAAO6D,EAAOhG,EAAK,EAC7C,IAEOA,CACT,CAEA,OAAO,IACT,CCzDA,IAAMqQ,GAAW,CAEfC,aAAc/B,GAEdgC,QAAS,CAAC,MAAO,OAAQ,SAEzBC,iBAAkB,CAAC,SAA0BpN,EAAMqN,GACjD,IA+BInR,EA/BEoR,EAAcD,EAAQE,kBAAoB,GAC1CC,EAAqBF,EAAY7J,QAAQ,qBAAuB,EAChEgK,EAAkB9G,GAAM9K,SAASmE,GAQvC,GANIyN,GAAmB9G,GAAMvI,WAAW4B,KACtCA,EAAO,IAAIY,SAASZ,IAGH2G,GAAMjG,WAAWV,GAGlC,OAAOwN,EAAqBxE,KAAKC,UAAUyD,GAAe1M,IAASA,EAGrE,GAAI2G,GAAMjL,cAAcsE,IACtB2G,GAAMrL,SAAS0E,IACf2G,GAAMtF,SAASrB,IACf2G,GAAM3K,OAAOgE,IACb2G,GAAM1K,OAAO+D,IACb2G,GAAMpK,iBAAiByD,GAEvB,OAAOA,EAET,GAAI2G,GAAM7F,kBAAkBd,GAC1B,OAAOA,EAAKiB,OAEd,GAAI0F,GAAMxK,kBAAkB6D,GAE1B,OADAqN,EAAQK,eAAe,mDAAmD,GACnE1N,EAAK/F,WAKd,GAAIwT,EAAiB,CACnB,GAAIH,EAAY7J,QAAQ,sCAAwC,EAC9D,OCvEO,SAA0BzD,EAAMoI,GAC7C,OAAOF,GAAWlI,EAAM,IAAIyM,GAAShB,QAAQC,gBAAiBc,EAAA,CAC5D/D,QAAS,SAAS7F,EAAOxF,EAAKyK,EAAM8F,GAClC,OAAIlB,GAASmB,QAAUjH,GAAMrL,SAASsH,IACpCnB,KAAKZ,OAAOzD,EAAKwF,EAAM3I,SAAS,YACzB,GAGF0T,EAAQjF,eAAe5O,MAAM2H,KAAM1H,UAC5C,GACGqO,GAEP,CD2DeyF,CAAiB7N,EAAMyB,KAAKqM,gBAAgB7T,WAGrD,IAAKiC,EAAayK,GAAMzK,WAAW8D,KAAUsN,EAAY7J,QAAQ,wBAA0B,EAAG,CAC5F,IAAMsK,EAAYtM,KAAKuM,KAAOvM,KAAKuM,IAAIpN,SAEvC,OAAOsH,GACLhM,EAAa,CAAC,UAAW8D,GAAQA,EACjC+N,GAAa,IAAIA,EACjBtM,KAAKqM,eAET,CACF,CAEA,OAAIL,GAAmBD,GACrBH,EAAQK,eAAe,oBAAoB,GAxEjD,SAAyBO,EAAUC,EAAQ3D,GACzC,GAAI5D,GAAMhL,SAASsS,GACjB,IAEE,OADCC,GAAUlF,KAAKmF,OAAOF,GAChBtH,GAAMxE,KAAK8L,EAKpB,CAJE,MAAO7M,GACP,GAAe,gBAAXA,EAAErC,KACJ,MAAMqC,CAEV,CAGF,OAAQmJ,GAAWvB,KAAKC,WAAWgF,EACrC,CA4DaG,CAAgBpO,IAGlBA,CACT,GAEAqO,kBAAmB,CAAC,SAA2BrO,GAC7C,IAAMkN,EAAezL,KAAKyL,cAAgBD,GAASC,aAC7C7B,EAAoB6B,GAAgBA,EAAa7B,kBACjDiD,EAAsC,SAAtB7M,KAAK8M,aAE3B,GAAI5H,GAAMlK,WAAWuD,IAAS2G,GAAMpK,iBAAiByD,GACnD,OAAOA,EAGT,GAAIA,GAAQ2G,GAAMhL,SAASqE,KAAWqL,IAAsB5J,KAAK8M,cAAiBD,GAAgB,CAChG,IACME,IADoBtB,GAAgBA,EAAa9B,oBACPkD,EAEhD,IACE,OAAOtF,KAAKmF,MAAMnO,EAAMyB,KAAKgN,aAQ/B,CAPE,MAAOrN,GACP,GAAIoN,EAAmB,CACrB,GAAe,gBAAXpN,EAAErC,KACJ,MAAMoH,GAAWe,KAAK9F,EAAG+E,GAAWuI,iBAAkBjN,KAAM,KAAMA,KAAK+E,UAEzE,MAAMpF,CACR,CACF,CACF,CAEA,OAAOpB,CACT,GAMA2O,QAAS,EAETC,eAAgB,aAChBC,eAAgB,eAEhBC,kBAAmB,EACnBC,eAAgB,EAEhBf,IAAK,CACHpN,SAAU6L,GAAShB,QAAQ7K,SAC3BgI,KAAM6D,GAAShB,QAAQ7C,MAGzBoG,eAAgB,SAAwBtI,GACtC,OAAOA,GAAU,KAAOA,EAAS,GAClC,EAED2G,QAAS,CACP4B,OAAQ,CACNC,OAAU,oCACV,oBAAgBjS,KAKtB0J,GAAMhK,QAAQ,CAAC,SAAU,MAAO,OAAQ,OAAQ,MAAO,UAAU,SAACwS,GAChElC,GAASI,QAAQ8B,GAAU,EAC7B,IAEA,IAAAC,GAAenC,GE1JToC,GAAoB1I,GAAMhC,YAAY,CAC1C,MAAO,gBAAiB,iBAAkB,eAAgB,OAC1D,UAAW,OAAQ,OAAQ,oBAAqB,sBAChD,gBAAiB,WAAY,eAAgB,sBAC7C,UAAW,cAAe,eCLtB2K,GAAahV,OAAO,aAE1B,SAASiV,GAAgBC,GACvB,OAAOA,GAAUjM,OAAOiM,GAAQrN,OAAOrH,aACzC,CAEA,SAAS2U,GAAe7M,GACtB,OAAc,IAAVA,GAA4B,MAATA,EACdA,EAGF+D,GAAMxL,QAAQyH,GAASA,EAAMtG,IAAImT,IAAkBlM,OAAOX,EACnE,CAgBA,SAAS8M,GAAiB1R,EAAS4E,EAAO4M,EAAQvM,EAAQ0M,GACxD,OAAIhJ,GAAMlL,WAAWwH,GACZA,EAAOrI,KAAK6G,KAAMmB,EAAO4M,IAG9BG,IACF/M,EAAQ4M,GAGL7I,GAAMhL,SAASiH,GAEhB+D,GAAMhL,SAASsH,IACiB,IAA3BL,EAAMa,QAAQR,GAGnB0D,GAAMnI,SAASyE,GACVA,EAAOgF,KAAKrF,QADrB,OANA,EASF,CAoBC,IAEKgN,GAAY,SAAAC,EAAAC,GAChB,SAAAF,EAAYvC,GAAS3C,OAAAkF,GACnBvC,GAAW5L,KAAKgD,IAAI4I,EACtB,CA2NC,OA3NAzC,EAAAgF,EAAA,CAAA,CAAAxS,IAAA,MAAAwF,MAED,SAAI4M,EAAQO,EAAgBC,GAC1B,IAAMpS,EAAO6D,KAEb,SAASwO,EAAUC,EAAQC,EAASC,GAClC,IAAMC,EAAUd,GAAgBY,GAEhC,IAAKE,EACH,MAAM,IAAI3L,MAAM,0CAGlB,IAAMtH,EAAMuJ,GAAMnJ,QAAQI,EAAMyS,KAE5BjT,QAAqBH,IAAdW,EAAKR,KAAmC,IAAbgT,QAAmCnT,IAAbmT,IAAwC,IAAdxS,EAAKR,MACzFQ,EAAKR,GAAO+S,GAAWV,GAAeS,GAE1C,CAEA,IAAMI,EAAa,SAACjD,EAAS+C,GAAQ,OACnCzJ,GAAMhK,QAAQ0Q,GAAS,SAAC6C,EAAQC,GAAO,OAAKF,EAAUC,EAAQC,EAASC,KAAU,EAEnF,GAAIzJ,GAAM7K,cAAc0T,IAAWA,aAAkB/N,KAAKjG,YACxD8U,EAAWd,EAAQO,QACd,GAAGpJ,GAAMhL,SAAS6T,KAAYA,EAASA,EAAOrN,UArEtB,iCAAiC8F,KAqEmBuH,EArEVrN,QAsEvEmO,ED1ES,SAAAC,GACb,IACInT,EACA7B,EACAsB,EAHE2T,EAAS,CAAA,EAyBf,OApBAD,GAAcA,EAAWxL,MAAM,MAAMpI,SAAQ,SAAgB8T,GAC3D5T,EAAI4T,EAAKhN,QAAQ,KACjBrG,EAAMqT,EAAKC,UAAU,EAAG7T,GAAGsF,OAAOrH,cAClCS,EAAMkV,EAAKC,UAAU7T,EAAI,GAAGsF,QAEvB/E,GAAQoT,EAAOpT,IAAQiS,GAAkBjS,KAIlC,eAARA,EACEoT,EAAOpT,GACToT,EAAOpT,GAAK+C,KAAK5E,GAEjBiV,EAAOpT,GAAO,CAAC7B,GAGjBiV,EAAOpT,GAAOoT,EAAOpT,GAAOoT,EAAOpT,GAAO,KAAO7B,EAAMA,EAE3D,IAEOiV,CACR,CC+CgBG,CAAanB,GAASO,QAC5B,GAAIpJ,GAAM9K,SAAS2T,IAAW7I,GAAMT,WAAWsJ,GAAS,CAC7D,IAAcoB,EAAMxT,EACMyT,EADtBjU,EAAM,CAAE,EAAYiH,koBAAAiN,CACJtB,GAAM,IAA1B,IAAA3L,EAAAkN,MAAAF,EAAAhN,EAAAmN,KAAAjN,MAA4B,CAAA,IAAjBkN,EAAKJ,EAAAjO,MACd,IAAK+D,GAAMxL,QAAQ8V,GACjB,MAAM5I,UAAU,gDAGlBzL,EAAIQ,EAAM6T,EAAM,KAAOL,EAAOhU,EAAIQ,IAC/BuJ,GAAMxL,QAAQyV,MAAKlR,OAAAwR,EAAON,IAAMK,EAAM,KAAM,CAACL,EAAMK,EAAM,IAAOA,EAAM,EAC3E,CAAC,CAAA,MAAAE,GAAAtN,EAAAzC,EAAA+P,EAAA,CAAA,QAAAtN,EAAAuN,GAAA,CAEDd,EAAW1T,EAAKmT,EAClB,MACY,MAAVP,GAAkBS,EAAUF,EAAgBP,EAAQQ,GAGtD,OAAOvO,IACT,GAAC,CAAArE,IAAA,MAAAwF,MAED,SAAI4M,EAAQtB,GAGV,GAFAsB,EAASD,GAAgBC,GAEb,CACV,IAAMpS,EAAMuJ,GAAMnJ,QAAQiE,KAAM+N,GAEhC,GAAIpS,EAAK,CACP,IAAMwF,EAAQnB,KAAKrE,GAEnB,IAAK8Q,EACH,OAAOtL,EAGT,IAAe,IAAXsL,EACF,OApHV,SAAqBvT,GAKnB,IAJA,IAEIiP,EAFEyH,EAASnX,OAAOO,OAAO,MACvB6W,EAAW,mCAGT1H,EAAQ0H,EAASlN,KAAKzJ,IAC5B0W,EAAOzH,EAAM,IAAMA,EAAM,GAG3B,OAAOyH,CACT,CA0GiBE,CAAY3O,GAGrB,GAAI+D,GAAMlL,WAAWyS,GACnB,OAAOA,EAAOtT,KAAK6G,KAAMmB,EAAOxF,GAGlC,GAAIuJ,GAAMnI,SAAS0P,GACjB,OAAOA,EAAO9J,KAAKxB,GAGrB,MAAM,IAAIyF,UAAU,yCACtB,CACF,CACF,GAAC,CAAAjL,IAAA,MAAAwF,MAED,SAAI4M,EAAQgC,GAGV,GAFAhC,EAASD,GAAgBC,GAEb,CACV,IAAMpS,EAAMuJ,GAAMnJ,QAAQiE,KAAM+N,GAEhC,SAAUpS,QAAqBH,IAAdwE,KAAKrE,IAAwBoU,IAAW9B,GAAiBjO,EAAMA,KAAKrE,GAAMA,EAAKoU,GAClG,CAEA,OAAO,CACT,GAAC,CAAApU,IAAA,SAAAwF,MAED,SAAO4M,EAAQgC,GACb,IAAM5T,EAAO6D,KACTgQ,GAAU,EAEd,SAASC,EAAavB,GAGpB,GAFAA,EAAUZ,GAAgBY,GAEb,CACX,IAAM/S,EAAMuJ,GAAMnJ,QAAQI,EAAMuS,IAE5B/S,GAASoU,IAAW9B,GAAiB9R,EAAMA,EAAKR,GAAMA,EAAKoU,YACtD5T,EAAKR,GAEZqU,GAAU,EAEd,CACF,CAQA,OANI9K,GAAMxL,QAAQqU,GAChBA,EAAO7S,QAAQ+U,GAEfA,EAAalC,GAGRiC,CACT,GAAC,CAAArU,IAAA,QAAAwF,MAED,SAAM4O,GAKJ,IAJA,IAAMnU,EAAOnD,OAAOmD,KAAKoE,MACrB5E,EAAIQ,EAAKL,OACTyU,GAAU,EAEP5U,KAAK,CACV,IAAMO,EAAMC,EAAKR,GACb2U,IAAW9B,GAAiBjO,EAAMA,KAAKrE,GAAMA,EAAKoU,GAAS,YACtD/P,KAAKrE,GACZqU,GAAU,EAEd,CAEA,OAAOA,CACT,GAAC,CAAArU,IAAA,YAAAwF,MAED,SAAU+O,GACR,IAAM/T,EAAO6D,KACP4L,EAAU,CAAA,EAsBhB,OApBA1G,GAAMhK,QAAQ8E,MAAM,SAACmB,EAAO4M,GAC1B,IAAMpS,EAAMuJ,GAAMnJ,QAAQ6P,EAASmC,GAEnC,GAAIpS,EAGF,OAFAQ,EAAKR,GAAOqS,GAAe7M,eACpBhF,EAAK4R,GAId,IAAMoC,EAAaD,EAtKzB,SAAsBnC,GACpB,OAAOA,EAAOrN,OACXrH,cAAcsH,QAAQ,mBAAmB,SAACyP,EAAGC,EAAMnX,GAClD,OAAOmX,EAAK1M,cAAgBzK,CAC9B,GACJ,CAiKkCoX,CAAavC,GAAUjM,OAAOiM,GAAQrN,OAE9DyP,IAAepC,UACV5R,EAAK4R,GAGd5R,EAAKgU,GAAcnC,GAAe7M,GAElCyK,EAAQuE,IAAc,CACxB,IAEOnQ,IACT,GAAC,CAAArE,IAAA,SAAAwF,MAED,WAAmB,IAAA,IAAAoP,EAAAC,EAAAlY,UAAAiD,OAATkV,EAAO9W,IAAAA,MAAA6W,GAAAxU,EAAA,EAAAA,EAAAwU,EAAAxU,IAAPyU,EAAOzU,GAAA1D,UAAA0D,GACf,OAAOuU,EAAAvQ,KAAKjG,aAAYkE,OAAM5F,MAAAkY,EAAC,CAAAvQ,MAAI/B,OAAKwS,GAC1C,GAAC,CAAA9U,IAAA,SAAAwF,MAED,SAAOuP,GACL,IAAMvV,EAAM1C,OAAOO,OAAO,MAM1B,OAJAkM,GAAMhK,QAAQ8E,MAAM,SAACmB,EAAO4M,GACjB,MAAT5M,IAA2B,IAAVA,IAAoBhG,EAAI4S,GAAU2C,GAAaxL,GAAMxL,QAAQyH,GAASA,EAAMmF,KAAK,MAAQnF,EAC5G,IAEOhG,CACT,GAAC,CAAAQ,IAEA9C,OAAOD,SAFPuI,MAED,WACE,OAAO1I,OAAO6S,QAAQtL,KAAKmF,UAAUtM,OAAOD,WAC9C,GAAC,CAAA+C,IAAA,WAAAwF,MAED,WACE,OAAO1I,OAAO6S,QAAQtL,KAAKmF,UAAUtK,KAAI,SAAAS,GAAA,IAAAyE,EAAAnF,EAAAU,EAAA,GAAe,OAAPyE,EAAA,GAAsB,KAAfA,EAAA,EAA2B,IAAEuG,KAAK,KAC5F,GAAC,CAAA3K,IAAA,eAAAwF,MAED,WACE,OAAOnB,KAAK2Q,IAAI,eAAiB,EACnC,GAAC,CAAAhV,IAEI9C,OAAOC,YAFX6X,IAED,WACE,MAAO,cACT,IAAC,CAAA,CAAAhV,IAAA,OAAAwF,MAED,SAAYlI,GACV,OAAOA,aAAiB+G,KAAO/G,EAAQ,IAAI+G,KAAK/G,EAClD,GAAC,CAAA0C,IAAA,SAAAwF,MAED,SAAcyP,GACqB,IAAjC,IAAMC,EAAW,IAAI7Q,KAAK4Q,GAAOE,EAAAxY,UAAAiD,OADXkV,MAAO9W,MAAAmX,EAAAA,EAAAA,OAAAC,EAAA,EAAAA,EAAAD,EAAAC,IAAPN,EAAOM,EAAAzY,GAAAA,UAAAyY,GAK7B,OAFAN,EAAQvV,SAAQ,SAACmJ,GAAM,OAAKwM,EAAS7N,IAAIqB,MAElCwM,CACT,GAAC,CAAAlV,IAAA,WAAAwF,MAED,SAAgB4M,GACd,IAIMiD,GAJYhR,KAAK6N,IAAe7N,KAAK6N,IAAc,CACvDmD,UAAW,CAAC,IAGcA,UACtBtY,EAAYsH,KAAKtH,UAEvB,SAASuY,EAAevC,GACtB,IAAME,EAAUd,GAAgBY,GAE3BsC,EAAUpC,MAlOrB,SAAwBzT,EAAK4S,GAC3B,IAAMmD,EAAehM,GAAM3B,YAAY,IAAMwK,GAE7C,CAAC,MAAO,MAAO,OAAO7S,SAAQ,SAAAiW,GAC5B1Y,OAAOyI,eAAe/F,EAAKgW,EAAaD,EAAc,CACpD/P,MAAO,SAASiQ,EAAMC,EAAMC,GAC1B,OAAOtR,KAAKmR,GAAYhY,KAAK6G,KAAM+N,EAAQqD,EAAMC,EAAMC,EACxD,EACDtL,cAAc,GAElB,GACF,CAwNQuL,CAAe7Y,EAAWgW,GAC1BsC,EAAUpC,IAAW,EAEzB,CAIA,OAFA1J,GAAMxL,QAAQqU,GAAUA,EAAO7S,QAAQ+V,GAAkBA,EAAelD,GAEjE/N,IACT,KAACmO,CAAA,CA9Ne,GAiOlBA,GAAaqD,SAAS,CAAC,eAAgB,iBAAkB,SAAU,kBAAmB,aAAc,kBAG/FxS,GAAChC,kBAAkBmR,GAAazV,WAAW,SAAA+H,EAAU9E,GAAQ,IAAhBwF,EAAKV,EAALU,MAC5CsQ,EAAS9V,EAAI,GAAGgI,cAAgBhI,EAAIvC,MAAM,GAC9C,MAAO,CACLuX,IAAK,WAAA,OAAMxP,CAAK,EAChB6B,IAAG,SAAC0O,GACF1R,KAAKyR,GAAUC,CACjB,EAEJ,IAEAxM,GAAMrC,cAAcsL,IAEpB,IAAAwD,GAAexD,GC3SA,SAASyD,GAAcC,EAAK9M,GACzC,IAAMF,EAAS7E,MAAQwL,GACjBjP,EAAUwI,GAAYF,EACtB+G,EAAUuC,GAAa1I,KAAKlJ,EAAQqP,SACtCrN,EAAOhC,EAAQgC,KAQnB,OANA2G,GAAMhK,QAAQ2W,GAAK,SAAmB1Z,GACpCoG,EAAOpG,EAAGgB,KAAK0L,EAAQtG,EAAMqN,EAAQkG,YAAa/M,EAAWA,EAASE,YAASzJ,EACjF,IAEAoQ,EAAQkG,YAEDvT,CACT,CCzBe,SAASwT,GAAS5Q,GAC/B,SAAUA,IAASA,EAAM6Q,WAC3B,CCUA,SAASC,GAActN,EAASE,EAAQC,GAEtCJ,GAAWvL,KAAK6G,KAAiB,MAAX2E,EAAkB,WAAaA,EAASD,GAAWwN,aAAcrN,EAAQC,GAC/F9E,KAAK1C,KAAO,eACd,CCLe,SAAS6U,GAAOC,EAASC,EAAQtN,GAC9C,IAAMwI,EAAiBxI,EAASF,OAAO0I,eAClCxI,EAASE,QAAWsI,IAAkBA,EAAexI,EAASE,QAGjEoN,EAAO,IAAI3N,GACT,mCAAqCK,EAASE,OAC9C,CAACP,GAAW4N,gBAAiB5N,GAAWuI,kBAAkB/O,KAAKqU,MAAMxN,EAASE,OAAS,KAAO,GAC9FF,EAASF,OACTE,EAASD,QACTC,IAPFqN,EAAQrN,EAUZ,CClBA,SAASyN,GAAYC,EAAcC,GACjCD,EAAeA,GAAgB,GAC/B,IAIIE,EAJEC,EAAQ,IAAIjZ,MAAM8Y,GAClBI,EAAa,IAAIlZ,MAAM8Y,GACzBK,EAAO,EACPC,EAAO,EAKX,OAFAL,OAAclX,IAARkX,EAAoBA,EAAM,IAEzB,SAAcM,GACnB,IAAMC,EAAMC,KAAKD,MAEXE,EAAYN,EAAWE,GAExBJ,IACHA,EAAgBM,GAGlBL,EAAME,GAAQE,EACdH,EAAWC,GAAQG,EAKnB,IAHA,IAAI7X,EAAI2X,EACJK,EAAa,EAEVhY,IAAM0X,GACXM,GAAcR,EAAMxX,KACpBA,GAAQqX,EASV,IANAK,GAAQA,EAAO,GAAKL,KAEPM,IACXA,GAAQA,EAAO,GAAKN,KAGlBQ,EAAMN,EAAgBD,GAA1B,CAIA,IAAMW,EAASF,GAAaF,EAAME,EAElC,OAAOE,EAASnV,KAAKoV,MAAmB,IAAbF,EAAoBC,QAAU7X,CAJzD,EAMJ,CC9CA,SAAS+X,GAASpb,EAAIqb,GACpB,IAEIC,EACAC,EAHAC,EAAY,EACZC,EAAY,IAAOJ,EAIjBK,EAAS,SAACC,GAA2B,IAArBb,EAAG3a,UAAAiD,eAAAC,IAAAlD,UAAA,GAAAA,UAAG4a,GAAAA,KAAKD,MAC/BU,EAAYV,EACZQ,EAAW,KACPC,IACFK,aAAaL,GACbA,EAAQ,MAEVvb,EAAEE,WAAA,EAAAoX,EAAIqE,KAqBR,MAAO,CAlBW,WAEe,IAD/B,IAAMb,EAAMC,KAAKD,MACXI,EAASJ,EAAMU,EAAUnD,EAAAlY,UAAAiD,OAFXuY,EAAIna,IAAAA,MAAA6W,GAAAxU,EAAA,EAAAA,EAAAwU,EAAAxU,IAAJ8X,EAAI9X,GAAA1D,UAAA0D,GAGnBqX,GAAUO,EACbC,EAAOC,EAAMb,IAEbQ,EAAWK,EACNJ,IACHA,EAAQ/U,YAAW,WACjB+U,EAAQ,KACRG,EAAOJ,EACT,GAAGG,EAAYP,MAKP,WAAH,OAASI,GAAYI,EAAOJ,EAAS,EAGlD,CHrBAvO,GAAMnE,SAASkR,GAAevN,GAAY,CACxCsN,YAAY,IIjBP,IAAMgC,GAAuB,SAACC,EAAUC,GAA+B,IAAbV,EAAIlb,UAAAiD,OAAA,QAAAC,IAAAlD,UAAA,GAAAA,UAAA,GAAG,EAClE6b,EAAgB,EACdC,EAAe5B,GAAY,GAAI,KAErC,OAAOe,IAAS,SAAA5T,GACd,IAAM0U,EAAS1U,EAAE0U,OACXC,EAAQ3U,EAAE4U,iBAAmB5U,EAAE2U,WAAQ9Y,EACvCgZ,EAAgBH,EAASF,EACzBM,EAAOL,EAAaI,GAG1BL,EAAgBE,EAEhB,IAAM9V,EAAImW,EAAA,CACRL,OAAAA,EACAC,MAAAA,EACAK,SAAUL,EAASD,EAASC,OAAS9Y,EACrCoX,MAAO4B,EACPC,KAAMA,QAAcjZ,EACpBoZ,UAAWH,GAAQH,GAVLD,GAAUC,GAUeA,EAAQD,GAAUI,OAAOjZ,EAChEqZ,MAAOlV,EACP4U,iBAA2B,MAATD,GACjBJ,EAAmB,WAAa,UAAW,GAG9CD,EAAS1V,EACV,GAAEiV,EACL,EAEasB,GAAyB,SAACR,EAAOS,GAC5C,IAAMR,EAA4B,MAATD,EAEzB,MAAO,CAAC,SAACD,GAAM,OAAKU,EAAU,GAAG,CAC/BR,iBAAAA,EACAD,MAAAA,EACAD,OAAAA,GACA,EAAEU,EAAU,GAChB,EAEaC,GAAiB,SAAC7c,GAAE,OAAK,WAAA,IAAA,IAAAqY,EAAAlY,UAAAiD,OAAIuY,EAAIna,IAAAA,MAAA6W,GAAAxU,EAAA,EAAAA,EAAAwU,EAAAxU,IAAJ8X,EAAI9X,GAAA1D,UAAA0D,GAAA,OAAKkJ,GAAMtG,MAAK,WAAA,OAAMzG,EAAEE,WAAA,EAAIyb,KAAM,CAAA,ECzCjE9I,GAAAA,GAAST,sBAAyB,SAACK,EAAQqK,GAAM,OAAK,SAACzM,GAGpE,OAFAA,EAAM,IAAI0M,IAAI1M,EAAKwC,GAASJ,QAG1BA,EAAOuK,WAAa3M,EAAI2M,UACxBvK,EAAOwK,OAAS5M,EAAI4M,OACnBH,GAAUrK,EAAOyK,OAAS7M,EAAI6M,MAElC,CARgD,CAS/C,IAAIH,IAAIlK,GAASJ,QACjBI,GAASV,WAAa,kBAAkB9D,KAAKwE,GAASV,UAAUgL,YAC9D,WAAA,OAAM,CAAI,ECVCtK,GAAAA,GAAST,sBAGtB,CACEgL,MAAKA,SAACjY,EAAM6D,EAAOqU,EAASpP,EAAMqP,EAAQC,GACxC,IAAMC,EAAS,CAACrY,EAAO,IAAM4K,mBAAmB/G,IAEhD+D,GAAM/K,SAASqb,IAAYG,EAAOjX,KAAK,WAAa,IAAIwU,KAAKsC,GAASI,eAEtE1Q,GAAMhL,SAASkM,IAASuP,EAAOjX,KAAK,QAAU0H,GAE9ClB,GAAMhL,SAASub,IAAWE,EAAOjX,KAAK,UAAY+W,IAEvC,IAAXC,GAAmBC,EAAOjX,KAAK,UAE/B0L,SAASuL,OAASA,EAAOrP,KAAK,KAC/B,EAEDuP,KAAI,SAACvY,GACH,IAAM6K,EAAQiC,SAASuL,OAAOxN,MAAM,IAAI2N,OAAO,aAAexY,EAAO,cACrE,OAAQ6K,EAAQ4N,mBAAmB5N,EAAM,IAAM,IAChD,EAED6N,OAAM,SAAC1Y,GACL0C,KAAKuV,MAAMjY,EAAM,GAAI4V,KAAKD,MAAQ,MACpC,GAMF,CACEsC,MAAKA,WAAK,EACVM,KAAI,WACF,OAAO,IACR,EACDG,OAAM,WAAI,GCxBC,SAASC,GAAcC,EAASC,EAAcC,GAC3D,IAAIC,GCHG,8BAA8B7P,KDGF2P,GACnC,OAAID,IAAYG,GAAsC,GAArBD,GEPpB,SAAqBF,EAASI,GAC3C,OAAOA,EACHJ,EAAQvV,QAAQ,SAAU,IAAM,IAAM2V,EAAY3V,QAAQ,OAAQ,IAClEuV,CACN,CFIWK,CAAYL,EAASC,GAEvBA,CACT,CGhBA,IAAMK,GAAkB,SAACvd,GAAK,OAAKA,aAAiBkV,GAAYpD,EAAQ9R,CAAAA,EAAAA,GAAUA,CAAK,EAWxE,SAASwd,GAAYC,EAASC,GAE3CA,EAAUA,GAAW,GACrB,IAAM9R,EAAS,CAAA,EAEf,SAAS+R,EAAevS,EAAQ/F,EAAQxB,EAAMmD,GAC5C,OAAIiF,GAAM7K,cAAcgK,IAAWa,GAAM7K,cAAciE,GAC9C4G,GAAMpF,MAAM3G,KAAK,CAAC8G,SAAAA,GAAWoE,EAAQ/F,GACnC4G,GAAM7K,cAAciE,GACtB4G,GAAMpF,MAAM,CAAE,EAAExB,GACd4G,GAAMxL,QAAQ4E,GAChBA,EAAOlF,QAETkF,CACT,CAGA,SAASuY,EAAoBtW,EAAGC,EAAG1D,EAAOmD,GACxC,OAAKiF,GAAMtL,YAAY4G,GAEX0E,GAAMtL,YAAY2G,QAAvB,EACEqW,OAAepb,EAAW+E,EAAGzD,EAAOmD,GAFpC2W,EAAerW,EAAGC,EAAG1D,EAAOmD,EAIvC,CAGA,SAAS6W,EAAiBvW,EAAGC,GAC3B,IAAK0E,GAAMtL,YAAY4G,GACrB,OAAOoW,OAAepb,EAAWgF,EAErC,CAGA,SAASuW,EAAiBxW,EAAGC,GAC3B,OAAK0E,GAAMtL,YAAY4G,GAEX0E,GAAMtL,YAAY2G,QAAvB,EACEqW,OAAepb,EAAW+E,GAF1BqW,OAAepb,EAAWgF,EAIrC,CAGA,SAASwW,EAAgBzW,EAAGC,EAAG1D,GAC7B,OAAIA,KAAQ6Z,EACHC,EAAerW,EAAGC,GAChB1D,KAAQ4Z,EACVE,OAAepb,EAAW+E,QAD5B,CAGT,CAEA,IAAM0W,EAAW,CACfzO,IAAKsO,EACLpJ,OAAQoJ,EACRvY,KAAMuY,EACNZ,QAASa,EACTpL,iBAAkBoL,EAClBnK,kBAAmBmK,EACnBG,iBAAkBH,EAClB7J,QAAS6J,EACTI,eAAgBJ,EAChBK,gBAAiBL,EACjBM,cAAeN,EACfrL,QAASqL,EACTjK,aAAciK,EACd5J,eAAgB4J,EAChB3J,eAAgB2J,EAChBO,iBAAkBP,EAClBQ,mBAAoBR,EACpBS,WAAYT,EACZ1J,iBAAkB0J,EAClBzJ,cAAeyJ,EACfU,eAAgBV,EAChBW,UAAWX,EACXY,UAAWZ,EACXa,WAAYb,EACZc,YAAad,EACbe,WAAYf,EACZgB,iBAAkBhB,EAClBxJ,eAAgByJ,EAChBpL,QAAS,SAACrL,EAAGC,EAAI1D,GAAI,OAAK+Z,EAAoBL,GAAgBjW,GAAIiW,GAAgBhW,GAAG1D,GAAM,EAAK,GASlG,OANAoI,GAAMhK,QAAQzC,OAAOmD,KAAImP,EAAAA,KAAK2L,GAAYC,KAAW,SAA4B7Z,GAC/E,IAAMgD,EAAQmX,EAASna,IAAS+Z,EAC1BmB,EAAclY,EAAM4W,EAAQ5Z,GAAO6Z,EAAQ7Z,GAAOA,GACvDoI,GAAMtL,YAAYoe,IAAgBlY,IAAUkX,IAAqBnS,EAAO/H,GAAQkb,EACnF,IAEOnT,CACT,CChGe,ICKSvJ,GDLT2c,GAAA,SAACpT,GACd,IAAMqT,EAAYzB,GAAY,CAAE,EAAE5R,GAE5BtG,EAAuE2Z,EAAvE3Z,KAAM8Y,EAAiEa,EAAjEb,cAAejK,EAAkD8K,EAAlD9K,eAAgBD,EAAkC+K,EAAlC/K,eAAgBvB,EAAkBsM,EAAlBtM,QAASuM,EAASD,EAATC,KAapE,GAXAD,EAAUtM,QAAUA,EAAUuC,GAAa1I,KAAKmG,GAEhDsM,EAAU1P,IAAMD,GAAS0N,GAAciC,EAAUhC,QAASgC,EAAU1P,IAAK0P,EAAU9B,mBAAoBvR,EAAOwD,OAAQxD,EAAOqS,kBAGzHiB,GACFvM,EAAQ5I,IAAI,gBAAiB,SAC3BoV,MAAMD,EAAKE,UAAY,IAAM,KAAOF,EAAKG,SAAWC,SAASrQ,mBAAmBiQ,EAAKG,WAAa,MAIlGpT,GAAMjG,WAAWV,GACnB,GAAIyM,GAAST,uBAAyBS,GAASP,+BAC7CmB,EAAQK,oBAAezQ,QAClB,GAAI0J,GAAMlL,WAAWuE,EAAKia,YAAa,CAE5C,IAAMC,EAAcla,EAAKia,aAEnBE,EAAiB,CAAC,eAAgB,kBACxCjgB,OAAO6S,QAAQmN,GAAavd,SAAQ,SAAAI,GAAgB,IAAAyE,EAAAnF,EAAAU,EAAA,GAAdK,EAAGoE,EAAA,GAAEjG,EAAGiG,EAAA,GACxC2Y,EAAeC,SAAShd,EAAItC,gBAC9BuS,EAAQ5I,IAAIrH,EAAK7B,EAErB,GACF,CAOF,GAAIkR,GAAST,wBACX8M,GAAiBnS,GAAMlL,WAAWqd,KAAmBA,EAAgBA,EAAca,IAE/Eb,IAAoC,IAAlBA,GAA2BuB,GAAgBV,EAAU1P,MAAO,CAEhF,IAAMqQ,EAAYzL,GAAkBD,GAAkB2L,GAAQjD,KAAK1I,GAE/D0L,GACFjN,EAAQ5I,IAAIoK,EAAgByL,EAEhC,CAGF,OAAOX,CACR,EE9CDa,GAFwD,oBAAnBC,gBAEG,SAAUnU,GAChD,OAAO,IAAIoU,SAAQ,SAA4B7G,EAASC,GACtD,IAII6G,EACAC,EAAiBC,EACjBC,EAAaC,EANXC,EAAUtB,GAAcpT,GAC1B2U,EAAcD,EAAQhb,KACpBkb,EAAiBtL,GAAa1I,KAAK8T,EAAQ3N,SAASkG,YACrDhF,EAAsDyM,EAAtDzM,aAAcwK,EAAwCiC,EAAxCjC,iBAAkBC,EAAsBgC,EAAtBhC,mBAKrC,SAASjV,IACP+W,GAAeA,IACfC,GAAiBA,IAEjBC,EAAQ1B,aAAe0B,EAAQ1B,YAAY6B,YAAYR,GAEvDK,EAAQI,QAAUJ,EAAQI,OAAOC,oBAAoB,QAASV,EAChE,CAEA,IAAIpU,EAAU,IAAIkU,eAOlB,SAASa,IACP,GAAK/U,EAAL,CAIA,IAAMgV,EAAkB3L,GAAa1I,KACnC,0BAA2BX,GAAWA,EAAQiV,yBAahD5H,IAAO,SAAkBhR,GACvBiR,EAAQjR,GACRmB,GACF,IAAG,SAAiBoN,GAClB2C,EAAO3C,GACPpN,GACD,GAfgB,CACf/D,KAHoBuO,GAAiC,SAAjBA,GAA4C,SAAjBA,EACxChI,EAAQC,SAA/BD,EAAQkV,aAGR/U,OAAQH,EAAQG,OAChBgV,WAAYnV,EAAQmV,WACpBrO,QAASkO,EACTjV,OAAAA,EACAC,QAAAA,IAYFA,EAAU,IAzBV,CA0BF,CAwFA,GA1HAA,EAAQoV,KAAKX,EAAQ7L,OAAO/J,cAAe4V,EAAQ/Q,KAAK,GAGxD1D,EAAQoI,QAAUqM,EAAQrM,QAiCtB,cAAepI,EAEjBA,EAAQ+U,UAAYA,EAGpB/U,EAAQqV,mBAAqB,WACtBrV,GAAkC,IAAvBA,EAAQsV,aAQD,IAAnBtV,EAAQG,QAAkBH,EAAQuV,aAAwD,IAAzCvV,EAAQuV,YAAYrY,QAAQ,WAKjFrD,WAAWkb,IAKf/U,EAAQwV,QAAU,WACXxV,IAILuN,EAAO,IAAI3N,GAAW,kBAAmBA,GAAW6V,aAAc1V,EAAQC,IAG1EA,EAAU,OAIdA,EAAQ0V,QAAU,SAAqB3F,GAIlC,IACMnF,EAAM,IAAIhL,GADJmQ,GAASA,EAAMlQ,QAAUkQ,EAAMlQ,QAAU,gBACrBD,GAAW+V,YAAa5V,EAAQC,GAEhE4K,EAAImF,MAAQA,GAAS,KACrBxC,EAAO3C,GACP5K,EAAU,MAIbA,EAAQ4V,UAAY,WAClB,IAAIC,EAAsBpB,EAAQrM,QAAU,cAAgBqM,EAAQrM,QAAU,cAAgB,mBACxFzB,EAAe8N,EAAQ9N,cAAgB/B,GACzC6P,EAAQoB,sBACVA,EAAsBpB,EAAQoB,qBAEhCtI,EAAO,IAAI3N,GACTiW,EACAlP,EAAa5B,oBAAsBnF,GAAWkW,UAAYlW,GAAW6V,aACrE1V,EACAC,IAGFA,EAAU,WAIItJ,IAAhBge,GAA6BC,EAAexN,eAAe,MAGvD,qBAAsBnH,GACxBI,GAAMhK,QAAQue,EAAetU,UAAU,SAA0BrL,EAAK6B,GACpEmJ,EAAQ+V,iBAAiBlf,EAAK7B,EAChC,IAIGoL,GAAMtL,YAAY2f,EAAQnC,mBAC7BtS,EAAQsS,kBAAoBmC,EAAQnC,iBAIlCtK,GAAiC,SAAjBA,IAClBhI,EAAQgI,aAAeyM,EAAQzM,cAI7ByK,EAAoB,CAAA,IAC8DuD,EAAAlgB,EAA9CoZ,GAAqBuD,GAAoB,GAAK,GAAlF6B,EAAiB0B,EAAA,GAAExB,EAAawB,EAAA,GAClChW,EAAQ1G,iBAAiB,WAAYgb,EACvC,CAGA,GAAI9B,GAAoBxS,EAAQiW,OAAQ,CAAA,IACkCC,EAAApgB,EAAtCoZ,GAAqBsD,GAAiB,GAAtE6B,EAAe6B,EAAA,GAAE3B,EAAW2B,EAAA,GAE9BlW,EAAQiW,OAAO3c,iBAAiB,WAAY+a,GAE5CrU,EAAQiW,OAAO3c,iBAAiB,UAAWib,EAC7C,EAEIE,EAAQ1B,aAAe0B,EAAQI,UAGjCT,EAAa,SAAA+B,GACNnW,IAGLuN,GAAQ4I,GAAUA,EAAO1hB,KAAO,IAAI0Y,GAAc,KAAMpN,EAAQC,GAAWmW,GAC3EnW,EAAQoW,QACRpW,EAAU,OAGZyU,EAAQ1B,aAAe0B,EAAQ1B,YAAYsD,UAAUjC,GACjDK,EAAQI,SACVJ,EAAQI,OAAOyB,QAAUlC,IAAeK,EAAQI,OAAOvb,iBAAiB,QAAS8a,KAIrF,IC1LkC1Q,EAC9BL,EDyLEgN,GC1L4B3M,ED0LH+Q,EAAQ/Q,KCzLnCL,EAAQ,4BAA4BxF,KAAK6F,KAC/BL,EAAM,IAAM,ID0LtBgN,IAAsD,IAA1CnK,GAASd,UAAUlI,QAAQmT,GACzC9C,EAAO,IAAI3N,GAAW,wBAA0ByQ,EAAW,IAAKzQ,GAAW4N,gBAAiBzN,IAM9FC,EAAQuW,KAAK7B,GAAe,KAC9B,GACF,EExJA8B,GA3CuB,SAACC,EAASrO,GAC/B,IAAO3R,GAAWggB,EAAUA,EAAUA,EAAQ/Z,OAAOga,SAAW,IAAzDjgB,OAEP,GAAI2R,GAAW3R,EAAQ,CACrB,IAEI6f,EAFAK,EAAa,IAAIC,gBAIfpB,EAAU,SAAUqB,GACxB,IAAKP,EAAS,CACZA,GAAU,EACV1B,IACA,IAAMhK,EAAMiM,aAAkB1Y,MAAQ0Y,EAAS3b,KAAK2b,OACpDF,EAAWP,MAAMxL,aAAehL,GAAagL,EAAM,IAAIuC,GAAcvC,aAAezM,MAAQyM,EAAI/K,QAAU+K,GAC5G,GAGEgE,EAAQxG,GAAWvO,YAAW,WAChC+U,EAAQ,KACR4G,EAAQ,IAAI5V,GAAU,WAAAzG,OAAYiP,EAAO,mBAAmBxI,GAAWkW,WACxE,GAAE1N,GAEGwM,EAAc,WACd6B,IACF7H,GAASK,aAAaL,GACtBA,EAAQ,KACR6H,EAAQrgB,SAAQ,SAAAye,GACdA,EAAOD,YAAcC,EAAOD,YAAYY,GAAWX,EAAOC,oBAAoB,QAASU,EACzF,IACAiB,EAAU,OAIdA,EAAQrgB,SAAQ,SAACye,GAAM,OAAKA,EAAOvb,iBAAiB,QAASkc,MAE7D,IAAOX,EAAU8B,EAAV9B,OAIP,OAFAA,EAAOD,YAAc,WAAA,OAAMxU,GAAMtG,KAAK8a,EAAY,EAE3CC,CACT,CACF,EC5CaiC,GAAWC,IAAAC,MAAG,SAAdF,EAAyBG,EAAOC,GAAS,IAAAlgB,EAAAmgB,EAAAC,EAAA,OAAAL,IAAAM,MAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAA/Z,MAAA,KAAA,EAC1B,GAAtBvG,EAAMigB,EAAMO,WAEXN,KAAalgB,EAAMkgB,GAAS,CAAAI,EAAA/Z,KAAA,EAAA,KAAA,CAC/B,OAD+B+Z,EAAA/Z,KAAA,EACzB0Z,EAAK,KAAA,EAAA,OAAAK,EAAAG,OAAA,UAAA,KAAA,EAITN,EAAM,EAAC,KAAA,EAAA,KAGJA,EAAMngB,GAAG,CAAAsgB,EAAA/Z,KAAA,GAAA,KAAA,CAEd,OADA6Z,EAAMD,EAAMD,EAAUI,EAAA/Z,KAAA,GAChB0Z,EAAM3iB,MAAM6iB,EAAKC,GAAI,KAAA,GAC3BD,EAAMC,EAAIE,EAAA/Z,KAAA,EAAA,MAAA,KAAA,GAAA,IAAA,MAAA,OAAA+Z,EAAAI,OAAA,GAdDZ,EAAW,IAkBXa,GAAS,WAAA,IAAAnhB,EAAAohB,EAAAb,IAAAC,MAAG,SAAAa,EAAiBC,EAAUZ,GAAS,IAAAa,EAAAC,EAAAC,EAAA3a,EAAAgN,EAAA2M,EAAA,OAAAF,IAAAM,MAAA,SAAAa,GAAA,cAAAA,EAAAX,KAAAW,EAAA3a,MAAA,KAAA,EAAAwa,GAAA,EAAAC,GAAA,EAAAE,EAAAX,KAAA,EAAAja,EAAA6a,EACjCC,GAAWN,IAAS,KAAA,EAAA,OAAAI,EAAA3a,KAAA,EAAA8a,EAAA/a,EAAAC,QAAA,KAAA,EAAA,KAAAwa,IAAAzN,EAAA4N,EAAAI,MAAA9a,MAAA,CAAA0a,EAAA3a,KAAA,GAAA,KAAA,CAC5C,OADe0Z,EAAK3M,EAAAjO,MACpB6b,EAAAK,cAAAC,EAAAL,EAAOrB,GAAYG,EAAOC,KAAU,KAAA,GAAA,KAAA,EAAAa,GAAA,EAAAG,EAAA3a,KAAA,EAAA,MAAA,KAAA,GAAA2a,EAAA3a,KAAA,GAAA,MAAA,KAAA,GAAA2a,EAAAX,KAAA,GAAAW,EAAAO,GAAAP,EAAA,MAAA,GAAAF,GAAA,EAAAC,EAAAC,EAAAO,GAAA,KAAA,GAAA,GAAAP,EAAAX,KAAA,GAAAW,EAAAX,KAAA,IAAAQ,GAAA,MAAAza,EAAA,OAAA,CAAA4a,EAAA3a,KAAA,GAAA,KAAA,CAAA,OAAA2a,EAAA3a,KAAA,GAAA8a,EAAA/a,EAAA,UAAA,KAAA,GAAA,GAAA4a,EAAAX,KAAA,IAAAS,EAAA,CAAAE,EAAA3a,KAAA,GAAA,KAAA,CAAA,MAAA0a,EAAA,KAAA,GAAA,OAAAC,EAAAQ,OAAA,IAAA,KAAA,GAAA,OAAAR,EAAAQ,OAAA,IAAA,KAAA,GAAA,IAAA,MAAA,OAAAR,EAAAR,OAAA,GAAAG,EAAA,KAAA,CAAA,CAAA,EAAA,GAAA,GAAA,IAAA,CAAA,GAAA,CAAA,GAAA,KAEvC,KAAA,OAAA,SAJqBc,EAAAC,GAAA,OAAApiB,EAAAjD,MAAA2H,KAAA1H,UAAA,CAAA,CAAA,GAMhB4kB,GAAU,WAAA,IAAAnd,EAAA2c,EAAAb,IAAAC,MAAG,SAAA6B,EAAiBC,GAAM,IAAAC,EAAAC,EAAAxb,EAAAnB,EAAA,OAAA0a,IAAAM,MAAA,SAAA4B,GAAA,cAAAA,EAAA1B,KAAA0B,EAAA1b,MAAA,KAAA,EAAA,IACpCub,EAAO/kB,OAAOmlB,eAAc,CAAAD,EAAA1b,KAAA,EAAA,KAAA,CAC9B,OAAA0b,EAAAV,cAAAC,EAAAL,EAAOW,IAAM,KAAA,GAAA,KAAA,EAAA,OAAAG,EAAAxB,OAAA,UAAA,KAAA,EAITsB,EAASD,EAAOK,YAAWF,EAAA1B,KAAA,EAAA,KAAA,EAAA,OAAA0B,EAAA1b,KAAA,EAAA8a,EAGDU,EAAOhI,QAAM,KAAA,EAAvB,GAAuBiI,EAAAC,EAAAX,KAAlC9a,EAAIwb,EAAJxb,KAAMnB,EAAK2c,EAAL3c,OACTmB,EAAI,CAAAyb,EAAA1b,KAAA,GAAA,KAAA,CAAA,OAAA0b,EAAAxB,OAAA,QAAA,IAAA,KAAA,GAGR,OAHQwB,EAAA1b,KAAA,GAGFlB,EAAK,KAAA,GAAA4c,EAAA1b,KAAA,EAAA,MAAA,KAAA,GAAA,OAAA0b,EAAA1B,KAAA,GAAA0B,EAAA1b,KAAA,GAAA8a,EAGPU,EAAO5C,UAAQ,KAAA,GAAA,OAAA8C,EAAAP,OAAA,IAAA,KAAA,GAAA,IAAA,MAAA,OAAAO,EAAAvB,OAAA,GAAAmB,EAAA,KAAA,CAAA,CAAA,EAAA,CAAA,GAAA,KAExB,KAAA,OAlBKT,SAAUgB,GAAA,OAAAne,EAAA1H,MAAA2H,KAAA1H,UAAA,CAAA,CAAA,GAoBH6lB,GAAc,SAACP,EAAQ5B,EAAWoC,EAAYC,GACzD,IAGI/b,EAHE1J,EAAW6jB,GAAUmB,EAAQ5B,GAE/BpJ,EAAQ,EAER0L,EAAY,SAAC3e,GACV2C,IACHA,GAAO,EACP+b,GAAYA,EAAS1e,KAIzB,OAAO,IAAI4e,eAAe,CAClBC,KAAI,SAAC/C,GAAY,OAAAgD,EAAA5C,IAAAC,eAAA4C,IAAA,IAAAC,EAAAC,EAAAzd,EAAArF,EAAA+iB,EAAA,OAAAhD,IAAAM,MAAA,SAAA2C,GAAA,cAAAA,EAAAzC,KAAAyC,EAAAzc,MAAA,KAAA,EAAA,OAAAyc,EAAAzC,KAAA,EAAAyC,EAAAzc,KAAA,EAESzJ,EAASyJ,OAAM,KAAA,EAAzB,GAAyBsc,EAAAG,EAAA1B,KAApC9a,EAAIqc,EAAJrc,KAAMnB,EAAKwd,EAALxd,OAETmB,EAAI,CAAAwc,EAAAzc,KAAA,GAAA,KAAA,CAEa,OADpBic,IACC7C,EAAWsD,QAAQD,EAAAvC,OAAA,UAAA,KAAA,GAIjBzgB,EAAMqF,EAAMmb,WACZ8B,IACES,EAAcjM,GAAS9W,EAC3BsiB,EAAWS,IAEbpD,EAAWuD,QAAQ,IAAItiB,WAAWyE,IAAQ2d,EAAAzc,KAAA,GAAA,MAAA,KAAA,GAE3B,MAF2Byc,EAAAzC,KAAA,GAAAyC,EAAAG,GAAAH,EAAA,MAAA,GAE1CR,EAASQ,EAAAG,IAAMH,EAAAG,GAAA,KAAA,GAAA,IAAA,MAAA,OAAAH,EAAAtC,OAAA,GAAAkC,EAAA,KAAA,CAAA,CAAA,EAAA,KAAA,IAjBID,EAoBtB,EACDxD,OAAM,SAACU,GAEL,OADA2C,EAAU3C,GACH/iB,EAAe,QACxB,GACC,CACDsmB,cAAe,GAEnB,EJ1EOllB,GAAckL,GAAdlL,WAEDmlB,GAA4C,CAChDC,SADsB9jB,GAEpB4J,GAAM7I,QAFgB+iB,QACfC,SADgC/jB,GAAR+jB,UAInCC,GAEIpa,GAAM7I,OADRkiB,GAAce,GAAdf,eAAgBgB,GAAWD,GAAXC,YAIZ/Y,GAAO,SAACrO,GACZ,IAAI,IAAAqY,IAAAA,EAAAlY,UAAAiD,OADeuY,MAAIna,MAAA6W,EAAAA,EAAAA,OAAAxU,EAAA,EAAAA,EAAAwU,EAAAxU,IAAJ8X,EAAI9X,EAAA1D,GAAAA,UAAA0D,GAErB,QAAS7D,EAAEE,WAAA,EAAIyb,EAGjB,CAFE,MAAOnU,GACP,OAAO,CACT,CACF,EAEM6f,GAAU,SAACjT,GAKf,IAAAkT,EAJAlT,EAAMrH,GAAMpF,MAAM3G,KAAK,CACrB+G,eAAe,GACdif,GAAgB5S,GAELmT,EAAQD,EAAfE,MAAiBP,EAAOK,EAAPL,QAASC,EAAQI,EAARJ,SAC3BO,EAAmBF,EAAW1lB,GAAW0lB,GAA6B,mBAAVC,MAC5DE,EAAqB7lB,GAAWolB,GAChCU,EAAsB9lB,GAAWqlB,GAEvC,IAAKO,EACH,OAAO,EAGT,IAGM9W,EAHAiX,EAA4BH,GAAoB5lB,GAAWukB,IAE3DyB,EAAaJ,IAA4C,mBAAhBL,IACzCzW,EAA0C,IAAIyW,GAAlC,SAACrmB,GAAG,OAAK4P,EAAQd,OAAO9O,EAAI,GAAoB,WAAA,IAAA6G,EAAA0e,EAAA5C,IAAAC,MAC9D,SAAAa,EAAOzjB,GAAG,OAAA2iB,IAAAM,MAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAA/Z,MAAA,KAAA,EAAmB,OAAnB+Z,EAAA6C,GAASviB,WAAU0f,EAAA/Z,KAAA,EAAO,IAAI+c,EAAQlmB,GAAK+mB,cAAa,KAAA,EAAA,OAAA7D,EAAAmB,GAAAnB,EAAAgB,KAAAhB,EAAAG,OAAAH,SAAAA,IAAAA,EAAA6C,GAAA7C,EAAAmB,KAAA,KAAA,EAAA,IAAA,MAAA,OAAAnB,EAAAI,OAAA,GAAAG,EAAC,KAAA,OAAA,SAAAc,GAAA,OAAA1d,EAAA1H,MAAA2H,KAAA1H,UAAA,CACtE,KAEK4nB,EAAwBL,GAAsBE,GAA6BvZ,IAAK,WACpF,IAAI2Z,GAAiB,EAEfC,EAAiB,IAAIhB,EAAQpU,GAASJ,OAAQ,CAClDyV,KAAM,IAAI9B,GACV7Q,OAAQ,OACJ4S,aAEF,OADAH,GAAiB,EACV,MACT,IACCvU,QAAQ2U,IAAI,gBAEf,OAAOJ,IAAmBC,CAC5B,IAEMI,EAAyBV,GAAuBC,GACpDvZ,IAAK,WAAA,OAAMtB,GAAMpK,iBAAiB,IAAIukB,EAAS,IAAIgB,SAE/CI,EAAY,CAChB7C,OAAQ4C,GAA2B,SAACE,GAAG,OAAKA,EAAIL,IAAI,GAGtDT,GACE,CAAC,OAAQ,cAAe,OAAQ,WAAY,UAAU1kB,SAAQ,SAAA3B,IAC3DknB,EAAUlnB,KAAUknB,EAAUlnB,GAAQ,SAACmnB,EAAK7b,GAC3C,IAAI6I,EAASgT,GAAOA,EAAInnB,GAExB,GAAImU,EACF,OAAOA,EAAOvU,KAAKunB,GAGrB,MAAM,IAAIhc,GAAUzG,kBAAAA,OAAmB1E,EAA0BmL,sBAAAA,GAAWic,gBAAiB9b,EAC/F,EACF,IAGF,IAAM+b,EAAa,WAAA,IAAAngB,EAAAge,EAAA5C,IAAAC,MAAG,SAAA6B,EAAO0C,GAAI,IAAAQ,EAAA,OAAAhF,IAAAM,MAAA,SAAAa,GAAA,cAAAA,EAAAX,KAAAW,EAAA3a,MAAA,KAAA,EAAA,GACnB,MAARge,EAAY,CAAArD,EAAA3a,KAAA,EAAA,KAAA,CAAA,OAAA2a,EAAAT,OAAA,SACP,GAAC,KAAA,EAAA,IAGNrX,GAAM1K,OAAO6lB,GAAK,CAAArD,EAAA3a,KAAA,EAAA,KAAA,CAAA,OAAA2a,EAAAT,OACb8D,SAAAA,EAAKS,MAAI,KAAA,EAAA,IAGd5b,GAAMjB,oBAAoBoc,GAAK,CAAArD,EAAA3a,KAAA,EAAA,KAAA,CAI/B,OAHIwe,EAAW,IAAIzB,EAAQpU,GAASJ,OAAQ,CAC5C8C,OAAQ,OACR2S,KAAAA,IACArD,EAAA3a,KAAA,EACYwe,EAASZ,cAAa,KAAA,EAYN,KAAA,GAAA,OAAAjD,EAAAT,OAAA,SAAAS,EAAAI,KAAEd,YAZgB,KAAA,EAAA,IAG9CpX,GAAM7F,kBAAkBghB,KAASnb,GAAMjL,cAAcomB,GAAK,CAAArD,EAAA3a,KAAA,GAAA,KAAA,CAAA,OAAA2a,EAAAT,OACrD8D,SAAAA,EAAK/D,YAAU,KAAA,GAKvB,GAFGpX,GAAMxK,kBAAkB2lB,KAC1BA,GAAc,KAGZnb,GAAMhL,SAASmmB,GAAK,CAAArD,EAAA3a,KAAA,GAAA,KAAA,CAAA,OAAA2a,EAAA3a,KAAA,GACR2d,EAAWK,GAAiB,KAAA,GAAA,IAAA,MAAA,OAAArD,EAAAR,OAAA,GAAAmB,EAE7C,KAAA,OA5BKiD,SAAalD,GAAA,OAAAjd,EAAApI,MAAA2H,KAAA1H,UAAA,EAAA,GA8BbyoB,EAAiB,WAAA,IAAAlkB,EAAA4hB,EAAA5C,IAAAC,MAAG,SAAA4C,EAAO9S,EAASyU,GAAI,IAAA9kB,EAAA,OAAAsgB,IAAAM,MAAA,SAAA4B,GAAA,cAAAA,EAAA1B,KAAA0B,EAAA1b,MAAA,KAAA,EACmB,OAAzD9G,EAAS2J,GAAMrB,eAAe+H,EAAQoV,oBAAmBjD,EAAAxB,OAAA,SAE9C,MAAVhhB,EAAiBqlB,EAAcP,GAAQ9kB,GAAM,KAAA,EAAA,IAAA,MAAA,OAAAwiB,EAAAvB,OAAA,GAAAkC,EACrD,KAAA,OAAA,SAJsBR,EAAA+C,GAAA,OAAApkB,EAAAxE,MAAA2H,KAAA1H,UAAA,EAAA,GAMvB,OAAA,WAAA,IAAA+F,EAAAogB,EAAA5C,IAAAC,MAAO,SAAAoF,EAAOrc,GAAM,IAAAsc,EAAA3Y,EAAAkF,EAAAnP,EAAAob,EAAA9B,EAAA3K,EAAAqK,EAAAD,EAAAxK,EAAAlB,EAAAwV,EAAAhK,EAAAiK,EAAAC,EAAAC,EAAAzc,EAAA4U,EAAA8H,EAAAX,EAAAY,EAAAC,EAAAC,EAAAvD,EAAAwD,EAAAC,EAAAC,EAAA/c,EAAAgd,EAAApb,EAAAqb,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAA,OAAAxG,IAAAM,MAAA,SAAA2C,GAAA,cAAAA,EAAAzC,KAAAyC,EAAAzc,MAAA,KAAA,EAgCoE,GAhCpE8e,EAcdlJ,GAAcpT,GAZhB2D,EAAG2Y,EAAH3Y,IACAkF,EAAMyT,EAANzT,OACAnP,EAAI4iB,EAAJ5iB,KACAob,EAAMwH,EAANxH,OACA9B,EAAWsJ,EAAXtJ,YACA3K,EAAOiU,EAAPjU,QACAqK,EAAkB4J,EAAlB5J,mBACAD,EAAgB6J,EAAhB7J,iBACAxK,EAAYqU,EAAZrU,aACAlB,EAAOuV,EAAPvV,QAAOwV,EAAAD,EACP/J,gBAAAA,OAAkB,IAAHgK,EAAG,cAAaA,EAC/BC,EAAYF,EAAZE,aAGEC,EAAS5B,GAAYC,MAEzB7S,EAAeA,GAAgBA,EAAe,IAAIzT,cAAgB,OAE9DkoB,EAAiBe,GAAe,CAAC3I,EAAQ9B,GAAeA,EAAY0K,iBAAkBrV,GAEtFpI,EAAU,KAER4U,EAAc6H,GAAkBA,EAAe7H,aAAgB,WACnE6H,EAAe7H,eACfoF,EAAAzC,KAAA,EAAAyC,EAAAG,GAME3H,GAAoB4I,GAAoC,QAAXxS,GAA+B,SAAXA,GAAiBoR,EAAAG,GAAA,CAAAH,EAAAzc,KAAA,GAAA,KAAA,CAAA,OAAAyc,EAAAzc,KAAA,GACpD0e,EAAkBnV,EAASrN,GAAK,KAAA,GAAAugB,EAAAvB,GAA7DiE,EAAoB1C,EAAA1B,KAAA0B,EAAAG,GAA+C,IAA/CH,EAAAvB,GAAgD,KAAA,GAAA,IAAAuB,EAAAG,GAAA,CAAAH,EAAAzc,KAAA,GAAA,KAAA,CAEjEwe,EAAW,IAAIzB,EAAQ5W,EAAK,CAC9BkF,OAAQ,OACR2S,KAAM9hB,EACN+hB,OAAQ,SAKNpb,GAAMjG,WAAWV,KAAUkjB,EAAoBZ,EAASjV,QAAQ+E,IAAI,kBACtE/E,EAAQK,eAAewV,GAGrBZ,EAASR,OAAMqB,EACW5M,GAC1B0M,EACAxN,GAAqBgB,GAAesC,KACrCqK,EAAA/mB,EAAA8mB,EAAA,GAHMtD,EAAUuD,EAAA,GAAEC,EAAKD,EAAA,GAKxBpjB,EAAO4f,GAAY0C,EAASR,KAvKX,MAuKqCjC,EAAYwD,IACnE,KAAA,GAqB+D,OAlB7D1c,GAAMhL,SAASkd,KAClBA,EAAkBA,EAAkB,UAAY,QAK5CyK,EAAyBhC,GAAsB,gBAAiBT,EAAQ1mB,UAExEopB,EAAe/W,EAAAA,KAChBsW,GAAY,CAAA,EAAA,CACf1H,OAAQ4H,EACR7T,OAAQA,EAAO/J,cACfiI,QAASA,EAAQkG,YAAY3M,SAC7Bkb,KAAM9hB,EACN+hB,OAAQ,OACRkC,YAAaX,EAAyBzK,OAAkB5b,IAG1DsJ,EAAU+a,GAAsB,IAAIT,EAAQ5W,EAAKsZ,GAAiBhD,EAAAzc,KAAA,GAE5Cwd,EAAqByB,EAAOxc,EAASuc,GAAgBC,EAAO9Y,EAAKsZ,GAAgB,KAAA,GA2BjE,OA3BlC/c,EAAQ+Z,EAAA1B,KAEN2E,EAAmBvB,IAA4C,WAAjB1T,GAA8C,aAAjBA,GAE7E0T,IAA2BjJ,GAAuBwK,GAAoBrI,KAClE/S,EAAU,CAAA,EAEhB,CAAC,SAAU,aAAc,WAAWzL,SAAQ,SAAA4B,GAC1C6J,EAAQ7J,GAAQiI,EAASjI,EAC3B,IAEMklB,EAAwB9c,GAAMrB,eAAekB,EAAS6G,QAAQ+E,IAAI,mBAAkBsR,EAE9D1K,GAAsBzC,GAChDkN,EACAhO,GAAqBgB,GAAeuC,IAAqB,KACtD,GAAE2K,EAAAtnB,EAAAqnB,EAHA7D,GAAAA,EAAU8D,EAAEN,GAAAA,EAAKM,EAAA,GAKxBnd,EAAW,IAAIsa,EACblB,GAAYpZ,EAASsb,KAlNJ,MAkN8BjC,GAAY,WACzDwD,GAASA,IACTlI,GAAeA,OAEjB/S,IAIJmG,EAAeA,GAAgB,OAAOgS,EAAAzc,KAAA,GAEboe,EAAUvb,GAAMnJ,QAAQ0kB,EAAW3T,IAAiB,QAAQ/H,EAAUF,GAAO,KAAA,GAEpD,OAF9Cwd,EAAYvD,EAAA1B,MAEf2E,GAAoBrI,GAAeA,IAAcoF,EAAAzc,KAAA,GAErC,IAAI4W,SAAQ,SAAC7G,EAASC,GACjCF,GAAOC,EAASC,EAAQ,CACtB9T,KAAM8jB,EACNzW,QAASuC,GAAa1I,KAAKV,EAAS6G,SACpC3G,OAAQF,EAASE,OACjBgV,WAAYlV,EAASkV,WACrBpV,OAAAA,EACAC,QAAAA,GAEJ,IAAE,KAAA,GAAA,OAAAga,EAAAvC,OAAAuC,SAAAA,EAAA1B,MAAA,KAAA,GAE2B,GAF3B0B,EAAAzC,KAAA,GAAAyC,EAAA2D,GAAA3D,EAAA,MAAA,GAEFpF,GAAeA,KAEXoF,EAAA2D,IAAoB,cAAb3D,EAAA2D,GAAInlB,OAAwB,qBAAqBkJ,KAAKsY,EAAA2D,GAAI9d,SAAQ,CAAAma,EAAAzc,KAAA,GAAA,KAAA,CAAA,MACrE5J,OAAO2I,OACX,IAAIsD,GAAW,gBAAiBA,GAAW+V,YAAa5V,EAAQC,GAChE,CACEiB,MAAO+Y,EAAA2D,GAAI1c,OAAK+Y,EAAA2D,KAEnB,KAAA,GAAA,MAGG/d,GAAWe,KAAIqZ,EAAA2D,GAAM3D,EAAA2D,IAAO3D,EAAA2D,GAAI7d,KAAMC,EAAQC,GAAQ,KAAA,GAAA,IAAA,MAAA,OAAAga,EAAAtC,OAAA,GAAA0E,EAAA,KAAA,CAAA,CAAA,EAAA,KAE/D,KAAA,OAAA,SAAAwB,GAAA,OAAArkB,EAAAhG,MAAA2H,KAAA1H,UAAA,CAAA,CAtID,EAuIF,EAEMqqB,GAAY,IAAIC,IAETC,GAAW,SAAChe,GAUvB,IATA,IAOEie,EAAMze,EAPJkI,EAAM1H,EAASA,EAAO0H,IAAM,CAAA,EACzBoT,EAA4BpT,EAA5BoT,MACDoD,EAAQ,CADqBxW,EAArB6S,QAAqB7S,EAAZ8S,SAEFM,GAGGvkB,EAAd2nB,EAAMxnB,OACAV,EAAM8nB,GAEfvnB,KACL0nB,EAAOC,EAAM3nB,QAGFI,KAFX6I,EAASxJ,EAAI8V,IAAImS,KAEOjoB,EAAImI,IAAI8f,EAAMze,EAAUjJ,EAAI,IAAIwnB,IAAQpD,GAAQjT,IAExE1R,EAAMwJ,EAGR,OAAOA,CACT,EAEgBwe,KKvRhB,IAAMG,GAAgB,CACpBC,KCNa,KDObC,IAAKnK,GACL4G,MAAO,CACLhP,IAAKwS,KAIJnkB,GAAC9D,QAAQ8nB,IAAe,SAAC7qB,EAAIgJ,GAChC,GAAIhJ,EAAI,CACN,IACEM,OAAOyI,eAAe/I,EAAI,OAAQ,CAACgJ,MAAAA,GAEnC,CADA,MAAOxB,GACP,CAEFlH,OAAOyI,eAAe/I,EAAI,cAAe,CAACgJ,MAAAA,GAC5C,CACF,IAEA,IAAMiiB,GAAe,SAACzH,GAAM,MAAA1d,KAAAA,OAAU0d,EAAM,EAEtC0H,GAAmB,SAAC3X,GAAO,OAAKxG,GAAMlL,WAAW0R,IAAwB,OAAZA,IAAgC,IAAZA,CAAiB,EAEzF4X,GACD,SAACA,EAAUze,GASrB,IANA,IACI0e,EACA7X,EAFGnQ,GAFP+nB,EAAWpe,GAAMxL,QAAQ4pB,GAAYA,EAAW,CAACA,IAE1C/nB,OAIDioB,EAAkB,CAAA,EAEfpoB,EAAI,EAAGA,EAAIG,EAAQH,IAAK,CAE/B,IAAIoO,OAAE,EAIN,GAFAkC,EAHA6X,EAAgBD,EAASloB,IAKpBioB,GAAiBE,SAGJ/nB,KAFhBkQ,EAAUsX,IAAexZ,EAAK1H,OAAOyhB,IAAgBlqB,gBAGnD,MAAM,IAAIqL,GAAU,oBAAAzG,OAAqBuL,QAI7C,GAAIkC,IAAYxG,GAAMlL,WAAW0R,KAAaA,EAAUA,EAAQiF,IAAI9L,KAClE,MAGF2e,EAAgBha,GAAM,IAAMpO,GAAKsQ,CACnC,CAEA,IAAKA,EAAS,CAEZ,IAAM+X,EAAUhrB,OAAO6S,QAAQkY,GAC5B3oB,KAAI,SAAAS,GAAA,IAAAyE,EAAAnF,EAAAU,EAAA,GAAEkO,EAAEzJ,EAAA,GAAE2jB,EAAK3jB,EAAA,GAAA,MAAM,WAAA9B,OAAWuL,EAC9Bka,OAAU,IAAVA,EAAkB,sCAAwC,gCAAgC,IAO/F,MAAM,IAAIhf,GACR,yDALMnJ,EACLkoB,EAAQloB,OAAS,EAAI,YAAckoB,EAAQ5oB,IAAIuoB,IAAc9c,KAAK,MAAQ,IAAM8c,GAAaK,EAAQ,IACtG,2BAIA,kBAEJ,CAEA,OAAO/X,CACR,EE9DH,SAASiY,GAA6B9e,GAKpC,GAJIA,EAAOgT,aACThT,EAAOgT,YAAY+L,mBAGjB/e,EAAO8U,QAAU9U,EAAO8U,OAAOyB,QACjC,MAAM,IAAInJ,GAAc,KAAMpN,EAElC,CASe,SAASgf,GAAgBhf,GAiBtC,OAhBA8e,GAA6B9e,GAE7BA,EAAO+G,QAAUuC,GAAa1I,KAAKZ,EAAO+G,SAG1C/G,EAAOtG,KAAOqT,GAAczY,KAC1B0L,EACAA,EAAO8G,mBAGgD,IAArD,CAAC,OAAQ,MAAO,SAAS3J,QAAQ6C,EAAO6I,SAC1C7I,EAAO+G,QAAQK,eAAe,qCAAqC,GAGrDqX,GAAoBze,EAAO6G,SAAWF,GAASE,QAAS7G,EAEjE6G,CAAQ7G,GAAQL,MAAK,SAA6BO,GAYvD,OAXA4e,GAA6B9e,GAG7BE,EAASxG,KAAOqT,GAAczY,KAC5B0L,EACAA,EAAO+H,kBACP7H,GAGFA,EAAS6G,QAAUuC,GAAa1I,KAAKV,EAAS6G,SAEvC7G,CACT,IAAG,SAA4B4W,GAe7B,OAdK5J,GAAS4J,KACZgI,GAA6B9e,GAGzB8W,GAAUA,EAAO5W,WACnB4W,EAAO5W,SAASxG,KAAOqT,GAAczY,KACnC0L,EACAA,EAAO+H,kBACP+O,EAAO5W,UAET4W,EAAO5W,SAAS6G,QAAUuC,GAAa1I,KAAKkW,EAAO5W,SAAS6G,WAIzDqN,QAAQ5G,OAAOsJ,EACxB,GACF,CChFO,IAAMmI,GAAU,SCKjBC,GAAa,CAAA,EAGnB,CAAC,SAAU,UAAW,SAAU,WAAY,SAAU,UAAU7oB,SAAQ,SAAC3B,EAAM6B,GAC7E2oB,GAAWxqB,GAAQ,SAAmBN,GACpC,OAAOQ,EAAOR,KAAUM,GAAQ,KAAO6B,EAAI,EAAI,KAAO,KAAO7B,EAEjE,IAEA,IAAMyqB,GAAqB,CAAA,EAWjBC,GAACxY,aAAe,SAAsByY,EAAWC,EAASxf,GAClE,SAASyf,EAAcC,EAAKC,GAC1B,MAAO,wCAAoDD,EAAM,IAAOC,GAAQ3f,EAAU,KAAOA,EAAU,GAC7G,CAGA,OAAO,SAACxD,EAAOkjB,EAAKE,GAClB,IAAkB,IAAdL,EACF,MAAM,IAAIxf,GACR0f,EAAcC,EAAK,qBAAuBF,EAAU,OAASA,EAAU,KACvEzf,GAAW8f,gBAef,OAXIL,IAAYH,GAAmBK,KACjCL,GAAmBK,IAAO,EAE1BI,QAAQC,KACNN,EACEC,EACA,+BAAiCF,EAAU,8CAK1CD,GAAYA,EAAU/iB,EAAOkjB,EAAKE,GAE7C,EAEAR,GAAWY,SAAW,SAAkBC,GACtC,OAAO,SAACzjB,EAAOkjB,GAGb,OADAI,QAAQC,KAAI,GAAAzmB,OAAIomB,EAAG,gCAAApmB,OAA+B2mB,KAC3C,EAEX,EAmCe,IAAAV,GAAA,CACbW,cAxBF,SAAuBle,EAASme,EAAQC,GACtC,GAAuB,WAAnBtrB,EAAOkN,GACT,MAAM,IAAIjC,GAAW,4BAA6BA,GAAWsgB,sBAI/D,IAFA,IAAMppB,EAAOnD,OAAOmD,KAAK+K,GACrBvL,EAAIQ,EAAKL,OACNH,KAAM,GAAG,CACd,IAAMipB,EAAMzoB,EAAKR,GACX8oB,EAAYY,EAAOT,GACzB,GAAIH,EAAJ,CACE,IAAM/iB,EAAQwF,EAAQ0d,GAChBlkB,OAAmB3E,IAAV2F,GAAuB+iB,EAAU/iB,EAAOkjB,EAAK1d,GAC5D,IAAe,IAAXxG,EACF,MAAM,IAAIuE,GAAW,UAAY2f,EAAM,YAAclkB,EAAQuE,GAAWsgB,qBAG5E,MACA,IAAqB,IAAjBD,EACF,MAAM,IAAIrgB,GAAW,kBAAoB2f,EAAK3f,GAAWugB,eAE7D,CACF,EAIElB,WAAAA,ICtFIA,GAAaG,GAAUH,WASvBmB,GAAK,WACT,SAAAA,EAAYC,GAAgBlc,OAAAic,GAC1BllB,KAAKwL,SAAW2Z,GAAkB,GAClCnlB,KAAKolB,aAAe,CAClBtgB,QAAS,IAAIkE,GACbjE,SAAU,IAAIiE,GAElB,CAEA,IAAAqc,EA8KC,OA9KDlc,EAAA+b,EAAA,CAAA,CAAAvpB,IAAA,UAAAwF,OAAAkkB,EAAA5G,EAAA5C,IAAAC,MAQA,SAAAa,EAAc2I,EAAazgB,GAAM,IAAA0gB,EAAAphB,EAAA,OAAA0X,IAAAM,MAAA,SAAAC,GAAA,cAAAA,EAAAC,KAAAD,EAAA/Z,MAAA,KAAA,EAAA,OAAA+Z,EAAAC,KAAA,EAAAD,EAAA/Z,KAAA,EAEhBrC,KAAK6gB,SAASyE,EAAazgB,GAAO,KAAA,EAAA,OAAAuX,EAAAG,OAAAH,SAAAA,EAAAgB,MAAA,KAAA,EAE/C,GAF+ChB,EAAAC,KAAA,EAAAD,EAAA6C,GAAA7C,EAAA,MAAA,GAE3CA,EAAA6C,cAAehc,MAAO,CACpBsiB,EAAQ,CAAA,EAEZtiB,MAAM+B,kBAAoB/B,MAAM+B,kBAAkBugB,GAAUA,EAAQ,IAAItiB,MAGlEkB,EAAQohB,EAAMphB,MAAQohB,EAAMphB,MAAMxD,QAAQ,QAAS,IAAM,GAC/D,IACOyb,EAAA6C,GAAI9a,MAGEA,IAAUrC,OAAOsa,EAAA6C,GAAI9a,OAAOxC,SAASwC,EAAMxD,QAAQ,YAAa,OACzEyb,EAAA6C,GAAI9a,OAAS,KAAOA,GAHpBiY,EAAA6C,GAAI9a,MAAQA,CAMd,CADA,MAAOxE,GACP,CAEJ,CAAC,MAAAyc,EAAA6C,GAAA,KAAA,GAAA,IAAA,MAAA,OAAA7C,EAAAI,OAAA,GAAAG,EAAA3c,KAAA,CAAA,CAAA,EAAA,IAIJ,KAAA,SAAAyd,EAAAC,GAAA,OAAA2H,EAAAhtB,MAAA2H,KAAA1H,UAAA,IAAA,CAAAqD,IAAA,WAAAwF,MAED,SAASmkB,EAAazgB,GAGO,iBAAhBygB,GACTzgB,EAASA,GAAU,IACZ2D,IAAM8c,EAEbzgB,EAASygB,GAAe,GAK1B,IAAA/L,EAFA1U,EAAS4R,GAAYzW,KAAKwL,SAAU3G,GAE7B4G,EAAY8N,EAAZ9N,aAAcyL,EAAgBqC,EAAhBrC,iBAAkBtL,EAAO2N,EAAP3N,aAElBpQ,IAAjBiQ,GACFyY,GAAUW,cAAcpZ,EAAc,CACpC9B,kBAAmBoa,GAAWtY,aAAasY,YAC3Cna,kBAAmBma,GAAWtY,aAAasY,YAC3Cla,oBAAqBka,GAAWtY,aAAasY,GAAkB,WAC9D,GAGmB,MAApB7M,IACEhS,GAAMlL,WAAWkd,GACnBrS,EAAOqS,iBAAmB,CACxBxO,UAAWwO,GAGbgN,GAAUW,cAAc3N,EAAkB,CACxClP,OAAQ+b,GAAmB,SAC3Brb,UAAWqb,GAAU,WACpB,SAK0BvoB,IAA7BqJ,EAAOuR,yBAEoC5a,IAApCwE,KAAKwL,SAAS4K,kBACvBvR,EAAOuR,kBAAoBpW,KAAKwL,SAAS4K,kBAEzCvR,EAAOuR,mBAAoB,GAG7B8N,GAAUW,cAAchgB,EAAQ,CAC9B2gB,QAASzB,GAAWY,SAAS,WAC7Bc,cAAe1B,GAAWY,SAAS,mBAClC,GAGH9f,EAAO6I,QAAU7I,EAAO6I,QAAU1N,KAAKwL,SAASkC,QAAU,OAAOrU,cAGjE,IAAIqsB,EAAiB9Z,GAAW1G,GAAMpF,MACpC8L,EAAQ4B,OACR5B,EAAQ/G,EAAO6I,SAGjB9B,GAAW1G,GAAMhK,QACf,CAAC,SAAU,MAAO,OAAQ,OAAQ,MAAO,QAAS,WAClD,SAACwS,UACQ9B,EAAQ8B,EACjB,IAGF7I,EAAO+G,QAAUuC,GAAalQ,OAAOynB,EAAgB9Z,GAGrD,IAAM+Z,EAA0B,GAC5BC,GAAiC,EACrC5lB,KAAKolB,aAAatgB,QAAQ5J,SAAQ,SAAoC2qB,GACjC,mBAAxBA,EAAYtc,UAA0D,IAAhCsc,EAAYtc,QAAQ1E,KAIrE+gB,EAAiCA,GAAkCC,EAAYvc,YAE/Eqc,EAAwBG,QAAQD,EAAYzc,UAAWyc,EAAYxc,UACrE,IAEA,IAKI0c,EALEC,EAA2B,GACjChmB,KAAKolB,aAAargB,SAAS7J,SAAQ,SAAkC2qB,GACnEG,EAAyBtnB,KAAKmnB,EAAYzc,UAAWyc,EAAYxc,SACnE,IAGA,IACIvN,EADAV,EAAI,EAGR,IAAKwqB,EAAgC,CACnC,IAAMK,EAAQ,CAACpC,GAAgB3rB,KAAK8H,WAAOxE,GAO3C,IANAyqB,EAAMH,QAAOztB,MAAb4tB,EAAiBN,GACjBM,EAAMvnB,KAAIrG,MAAV4tB,EAAcD,GACdlqB,EAAMmqB,EAAM1qB,OAEZwqB,EAAU9M,QAAQ7G,QAAQvN,GAEnBzJ,EAAIU,GACTiqB,EAAUA,EAAQvhB,KAAKyhB,EAAM7qB,KAAM6qB,EAAM7qB,MAG3C,OAAO2qB,CACT,CAEAjqB,EAAM6pB,EAAwBpqB,OAI9B,IAFA,IAAI2c,EAAYrT,EAETzJ,EAAIU,GAAK,CACd,IAAMoqB,EAAcP,EAAwBvqB,KACtC+qB,EAAaR,EAAwBvqB,KAC3C,IACE8c,EAAYgO,EAAYhO,EAI1B,CAHE,MAAOxS,GACPygB,EAAWhtB,KAAK6G,KAAM0F,GACtB,KACF,CACF,CAEA,IACEqgB,EAAUlC,GAAgB1qB,KAAK6G,KAAMkY,EAGvC,CAFE,MAAOxS,GACP,OAAOuT,QAAQ5G,OAAO3M,EACxB,CAKA,IAHAtK,EAAI,EACJU,EAAMkqB,EAAyBzqB,OAExBH,EAAIU,GACTiqB,EAAUA,EAAQvhB,KAAKwhB,EAAyB5qB,KAAM4qB,EAAyB5qB,MAGjF,OAAO2qB,CACT,GAAC,CAAApqB,IAAA,SAAAwF,MAED,SAAO0D,GAGL,OAAO0D,GADU0N,IADjBpR,EAAS4R,GAAYzW,KAAKwL,SAAU3G,IACEqR,QAASrR,EAAO2D,IAAK3D,EAAOuR,mBACxCvR,EAAOwD,OAAQxD,EAAOqS,iBAClD,KAACgO,CAAA,CAvLQ,GA2LXhgB,GAAMhK,QAAQ,CAAC,SAAU,MAAO,OAAQ,YAAY,SAA6BwS,GAE/EwX,GAAMxsB,UAAUgV,GAAU,SAASlF,EAAK3D,GACtC,OAAO7E,KAAK8E,QAAQ2R,GAAY5R,GAAU,CAAA,EAAI,CAC5C6I,OAAAA,EACAlF,IAAAA,EACAjK,MAAOsG,GAAU,CAAA,GAAItG,QAG3B,IAEA2G,GAAMhK,QAAQ,CAAC,OAAQ,MAAO,UAAU,SAA+BwS,GAGrE,SAAS0Y,EAAmBC,GAC1B,OAAO,SAAoB7d,EAAKjK,EAAMsG,GACpC,OAAO7E,KAAK8E,QAAQ2R,GAAY5R,GAAU,CAAA,EAAI,CAC5C6I,OAAAA,EACA9B,QAASya,EAAS,CAChB,eAAgB,uBACd,CAAE,EACN7d,IAAAA,EACAjK,KAAAA,KAGN,CAEA2mB,GAAMxsB,UAAUgV,GAAU0Y,IAE1BlB,GAAMxsB,UAAUgV,EAAS,QAAU0Y,GAAmB,EACxD,IAEA,IAAAE,GAAepB,GCpOTqB,GAAW,WACf,SAAAA,EAAYC,GACV,GADoBvd,OAAAsd,GACI,mBAAbC,EACT,MAAM,IAAI5f,UAAU,gCAGtB,IAAI6f,EAEJzmB,KAAK+lB,QAAU,IAAI9M,SAAQ,SAAyB7G,GAClDqU,EAAiBrU,CACnB,IAEA,IAAMzU,EAAQqC,KAGdA,KAAK+lB,QAAQvhB,MAAK,SAAAyW,GAChB,GAAKtd,EAAM+oB,WAAX,CAIA,IAFA,IAAItrB,EAAIuC,EAAM+oB,WAAWnrB,OAElBH,KAAM,GACXuC,EAAM+oB,WAAWtrB,GAAG6f,GAEtBtd,EAAM+oB,WAAa,IAPI,CAQzB,IAGA1mB,KAAK+lB,QAAQvhB,KAAO,SAAAmiB,GAClB,IAAIC,EAEEb,EAAU,IAAI9M,SAAQ,SAAA7G,GAC1BzU,EAAMwd,UAAU/I,GAChBwU,EAAWxU,CACb,IAAG5N,KAAKmiB,GAMR,OAJAZ,EAAQ9K,OAAS,WACftd,EAAM+b,YAAYkN,IAGbb,GAGTS,GAAS,SAAgB7hB,EAASE,EAAQC,GACpCnH,EAAMge,SAKVhe,EAAMge,OAAS,IAAI1J,GAActN,EAASE,EAAQC,GAClD2hB,EAAe9oB,EAAMge,QACvB,GACF,CAqEC,OAnEDxS,EAAAod,EAAA,CAAA,CAAA5qB,IAAA,mBAAAwF,MAGA,WACE,GAAInB,KAAK2b,OACP,MAAM3b,KAAK2b,MAEf,GAEA,CAAAhgB,IAAA,YAAAwF,MAIA,SAAU8S,GACJjU,KAAK2b,OACP1H,EAASjU,KAAK2b,QAIZ3b,KAAK0mB,WACP1mB,KAAK0mB,WAAWhoB,KAAKuV,GAErBjU,KAAK0mB,WAAa,CAACzS,EAEvB,GAEA,CAAAtY,IAAA,cAAAwF,MAIA,SAAY8S,GACV,GAAKjU,KAAK0mB,WAAV,CAGA,IAAM9e,EAAQ5H,KAAK0mB,WAAW1kB,QAAQiS,IACvB,IAAXrM,GACF5H,KAAK0mB,WAAWG,OAAOjf,EAAO,EAHhC,CAKF,GAAC,CAAAjM,IAAA,gBAAAwF,MAED,WAAgB,IAAA2lB,EAAA9mB,KACRyb,EAAa,IAAIC,gBAEjBR,EAAQ,SAACxL,GACb+L,EAAWP,MAAMxL,IAOnB,OAJA1P,KAAKmb,UAAUD,GAEfO,EAAW9B,OAAOD,YAAc,WAAA,OAAMoN,EAAKpN,YAAYwB,EAAM,EAEtDO,EAAW9B,MACpB,IAEA,CAAA,CAAAhe,IAAA,SAAAwF,MAIA,WACE,IAAI8Z,EAIJ,MAAO,CACLtd,MAJY,IAAI4oB,GAAY,SAAkBQ,GAC9C9L,EAAS8L,CACX,IAGE9L,OAAAA,EAEJ,KAACsL,CAAA,CAxHc,GA2HjBS,GAAeT,GCtIf,IAAMU,GAAiB,CACrBC,SAAU,IACVC,mBAAoB,IACpBC,WAAY,IACZC,WAAY,IACZC,GAAI,IACJC,QAAS,IACTC,SAAU,IACVC,4BAA6B,IAC7BC,UAAW,IACXC,aAAc,IACdC,eAAgB,IAChBC,YAAa,IACbC,gBAAiB,IACjBC,OAAQ,IACRC,gBAAiB,IACjBC,iBAAkB,IAClBC,MAAO,IACPC,SAAU,IACVC,YAAa,IACbC,SAAU,IACVC,OAAQ,IACRC,kBAAmB,IACnBC,kBAAmB,IACnBC,WAAY,IACZC,aAAc,IACdC,gBAAiB,IACjBC,UAAW,IACXC,SAAU,IACVC,iBAAkB,IAClBC,cAAe,IACfC,4BAA6B,IAC7BC,eAAgB,IAChBC,SAAU,IACVC,KAAM,IACNC,eAAgB,IAChBC,mBAAoB,IACpBC,gBAAiB,IACjBC,WAAY,IACZC,qBAAsB,IACtBC,oBAAqB,IACrBC,kBAAmB,IACnBC,UAAW,IACXC,mBAAoB,IACpBC,oBAAqB,IACrBC,OAAQ,IACRC,iBAAkB,IAClBC,SAAU,IACVC,gBAAiB,IACjBC,qBAAsB,IACtBC,gBAAiB,IACjBC,4BAA6B,IAC7BC,2BAA4B,IAC5BC,oBAAqB,IACrBC,eAAgB,IAChBC,WAAY,IACZC,mBAAoB,IACpBC,eAAgB,IAChBC,wBAAyB,IACzBC,sBAAuB,IACvBC,oBAAqB,IACrBC,aAAc,IACdC,YAAa,IACbC,8BAA+B,KAGjCvyB,OAAO6S,QAAQ2b,IAAgB/rB,SAAQ,SAAAI,GAAkB,IAAAyE,EAAAnF,EAAAU,EAAA,GAAhBK,EAAGoE,EAAA,GAAEoB,EAAKpB,EAAA,GACjDknB,GAAe9lB,GAASxF,CAC1B,IAEA,IAAAsvB,GAAehE,GCxBf,IAAMiE,GAnBN,SAASC,EAAeC,GACtB,IAAM7uB,EAAU,IAAI2oB,GAAMkG,GACpBC,EAAWnzB,EAAKgtB,GAAMxsB,UAAUoM,QAASvI,GAa/C,OAVA2I,GAAM5E,OAAO+qB,EAAUnG,GAAMxsB,UAAW6D,EAAS,CAACb,YAAY,IAG9DwJ,GAAM5E,OAAO+qB,EAAU9uB,EAAS,KAAM,CAACb,YAAY,IAGnD2vB,EAASryB,OAAS,SAAgBmsB,GAChC,OAAOgG,EAAe1U,GAAY2U,EAAejG,KAG5CkG,CACT,CAGcF,CAAe3f,WAG7B0f,GAAMhG,MAAQA,GAGdgG,GAAMjZ,cAAgBA,GACtBiZ,GAAM3E,YAAcA,GACpB2E,GAAMnZ,SAAWA,GACjBmZ,GAAMpH,QAAUA,GAChBoH,GAAMzkB,WAAaA,GAGnBykB,GAAMxmB,WAAaA,GAGnBwmB,GAAMI,OAASJ,GAAMjZ,cAGrBiZ,GAAMK,IAAM,SAAaC,GACvB,OAAOvS,QAAQsS,IAAIC,EACrB,EAEAN,GAAMO,OC9CS,SAAgBC,GAC7B,OAAO,SAAcxpB,GACnB,OAAOwpB,EAASrzB,MAAM,KAAM6J,GAEhC,ED6CAgpB,GAAMS,aE7DS,SAAsBC,GACnC,OAAO1mB,GAAM9K,SAASwxB,KAAsC,IAAzBA,EAAQD,YAC7C,EF8DAT,GAAMzU,YAAcA,GAEpByU,GAAM/c,aAAeA,GAErB+c,GAAMW,WAAa,SAAA5yB,GAAK,OAAIgS,GAAe/F,GAAMvI,WAAW1D,GAAS,IAAIkG,SAASlG,GAASA,EAAM,EAEjGiyB,GAAMY,WAAaxI,GAEnB4H,GAAMjE,eAAiBA,GAEvBiE,GAAK,QAAWA"} \ No newline at end of file diff --git a/node_modules/axios/dist/browser/axios.cjs b/node_modules/axios/dist/browser/axios.cjs new file mode 100644 index 0000000..f476ed7 --- /dev/null +++ b/node_modules/axios/dist/browser/axios.cjs @@ -0,0 +1,3840 @@ +/*! Axios v1.12.2 Copyright (c) 2025 Matt Zabriskie and contributors */ +'use strict'; + +function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; +} + +// utils is a library of generic helper functions non-specific to axios + +const {toString} = Object.prototype; +const {getPrototypeOf} = Object; +const {iterator, toStringTag} = Symbol; + +const kindOf = (cache => thing => { + const str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); +})(Object.create(null)); + +const kindOfTest = (type) => { + type = type.toLowerCase(); + return (thing) => kindOf(thing) === type +}; + +const typeOfTest = type => thing => typeof thing === type; + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * + * @returns {boolean} True if value is an Array, otherwise false + */ +const {isArray} = Array; + +/** + * Determine if a value is undefined + * + * @param {*} val The value to test + * + * @returns {boolean} True if the value is undefined, otherwise false + */ +const isUndefined = typeOfTest('undefined'); + +/** + * Determine if a value is a Buffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Buffer, otherwise false + */ +function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); +} + +/** + * Determine if a value is an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ +const isArrayBuffer = kindOfTest('ArrayBuffer'); + + +/** + * Determine if a value is a view on an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ +function isArrayBufferView(val) { + let result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); + } + return result; +} + +/** + * Determine if a value is a String + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a String, otherwise false + */ +const isString = typeOfTest('string'); + +/** + * Determine if a value is a Function + * + * @param {*} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ +const isFunction$1 = typeOfTest('function'); + +/** + * Determine if a value is a Number + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Number, otherwise false + */ +const isNumber = typeOfTest('number'); + +/** + * Determine if a value is an Object + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an Object, otherwise false + */ +const isObject = (thing) => thing !== null && typeof thing === 'object'; + +/** + * Determine if a value is a Boolean + * + * @param {*} thing The value to test + * @returns {boolean} True if value is a Boolean, otherwise false + */ +const isBoolean = thing => thing === true || thing === false; + +/** + * Determine if a value is a plain Object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a plain Object, otherwise false + */ +const isPlainObject = (val) => { + if (kindOf(val) !== 'object') { + return false; + } + + const prototype = getPrototypeOf(val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); +}; + +/** + * Determine if a value is an empty object (safely handles Buffers) + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an empty object, otherwise false + */ +const isEmptyObject = (val) => { + // Early return for non-objects or Buffers to prevent RangeError + if (!isObject(val) || isBuffer(val)) { + return false; + } + + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + // Fallback for any other objects that might cause RangeError with Object.keys() + return false; + } +}; + +/** + * Determine if a value is a Date + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Date, otherwise false + */ +const isDate = kindOfTest('Date'); + +/** + * Determine if a value is a File + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFile = kindOfTest('File'); + +/** + * Determine if a value is a Blob + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Blob, otherwise false + */ +const isBlob = kindOfTest('Blob'); + +/** + * Determine if a value is a FileList + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFileList = kindOfTest('FileList'); + +/** + * Determine if a value is a Stream + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Stream, otherwise false + */ +const isStream = (val) => isObject(val) && isFunction$1(val.pipe); + +/** + * Determine if a value is a FormData + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an FormData, otherwise false + */ +const isFormData = (thing) => { + let kind; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || ( + isFunction$1(thing.append) && ( + (kind = kindOf(thing)) === 'formdata' || + // detect form-data instance + (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]') + ) + ) + ) +}; + +/** + * Determine if a value is a URLSearchParams object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +const isURLSearchParams = kindOfTest('URLSearchParams'); + +const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest); + +/** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * + * @returns {String} The String freed of excess whitespace + */ +const trim = (str) => str.trim ? + str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + * + * @param {Boolean} [allOwnKeys = false] + * @returns {any} + */ +function forEach(obj, fn, {allOwnKeys = false} = {}) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + + let i; + let l; + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + + if (isArray(obj)) { + // Iterate over array values + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Buffer check + if (isBuffer(obj)) { + return; + } + + // Iterate over object keys + const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + const len = keys.length; + let key; + + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } +} + +function findKey(obj, key) { + if (isBuffer(obj)){ + return null; + } + + key = key.toLowerCase(); + const keys = Object.keys(obj); + let i = keys.length; + let _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; +} + +const _global = (() => { + /*eslint no-undef:0*/ + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : global) +})(); + +const isContextDefined = (context) => !isUndefined(context) && context !== _global; + +/** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * + * @returns {Object} Result of all merge properties + */ +function merge(/* obj1, obj2, obj3, ... */) { + const {caseless, skipUndefined} = isContextDefined(this) && this || {}; + const result = {}; + const assignValue = (val, key) => { + const targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + }; + + for (let i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * + * @param {Boolean} [allOwnKeys] + * @returns {Object} The resulting value of object a + */ +const extend = (a, b, thisArg, {allOwnKeys}= {}) => { + forEach(b, (val, key) => { + if (thisArg && isFunction$1(val)) { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }, {allOwnKeys}); + return a; +}; + +/** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * + * @returns {string} content value without BOM + */ +const stripBOM = (content) => { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; +}; + +/** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + * + * @returns {void} + */ +const inherits = (constructor, superConstructor, props, descriptors) => { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + Object.defineProperty(constructor, 'super', { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); +}; + +/** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function|Boolean} [filter] + * @param {Function} [propFilter] + * + * @returns {Object} + */ +const toFlatObject = (sourceObj, destObj, filter, propFilter) => { + let props; + let i; + let prop; + const merged = {}; + + destObj = destObj || {}; + // eslint-disable-next-line no-eq-null,eqeqeq + if (sourceObj == null) return destObj; + + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + + return destObj; +}; + +/** + * Determines whether a string ends with the characters of a specified string + * + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * + * @returns {boolean} + */ +const endsWith = (str, searchString, position) => { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + const lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; +}; + + +/** + * Returns new array from array like object or null if failed + * + * @param {*} [thing] + * + * @returns {?Array} + */ +const toArray = (thing) => { + if (!thing) return null; + if (isArray(thing)) return thing; + let i = thing.length; + if (!isNumber(i)) return null; + const arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; +}; + +/** + * Checking if the Uint8Array exists and if it does, it returns a function that checks if the + * thing passed in is an instance of Uint8Array + * + * @param {TypedArray} + * + * @returns {Array} + */ +// eslint-disable-next-line func-names +const isTypedArray = (TypedArray => { + // eslint-disable-next-line func-names + return thing => { + return TypedArray && thing instanceof TypedArray; + }; +})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); + +/** + * For each entry in the object, call the function with the key and value. + * + * @param {Object} obj - The object to iterate over. + * @param {Function} fn - The function to call for each entry. + * + * @returns {void} + */ +const forEachEntry = (obj, fn) => { + const generator = obj && obj[iterator]; + + const _iterator = generator.call(obj); + + let result; + + while ((result = _iterator.next()) && !result.done) { + const pair = result.value; + fn.call(obj, pair[0], pair[1]); + } +}; + +/** + * It takes a regular expression and a string, and returns an array of all the matches + * + * @param {string} regExp - The regular expression to match against. + * @param {string} str - The string to search. + * + * @returns {Array} + */ +const matchAll = (regExp, str) => { + let matches; + const arr = []; + + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + + return arr; +}; + +/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ +const isHTMLForm = kindOfTest('HTMLFormElement'); + +const toCamelCase = str => { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, + function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + } + ); +}; + +/* Creating a function that will check if an object has a property. */ +const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype); + +/** + * Determine if a value is a RegExp object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a RegExp object, otherwise false + */ +const isRegExp = kindOfTest('RegExp'); + +const reduceDescriptors = (obj, reducer) => { + const descriptors = Object.getOwnPropertyDescriptors(obj); + const reducedDescriptors = {}; + + forEach(descriptors, (descriptor, name) => { + let ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + + Object.defineProperties(obj, reducedDescriptors); +}; + +/** + * Makes all methods read-only + * @param {Object} obj + */ + +const freezeMethods = (obj) => { + reduceDescriptors(obj, (descriptor, name) => { + // skip restricted props in strict mode + if (isFunction$1(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { + return false; + } + + const value = obj[name]; + + if (!isFunction$1(value)) return; + + descriptor.enumerable = false; + + if ('writable' in descriptor) { + descriptor.writable = false; + return; + } + + if (!descriptor.set) { + descriptor.set = () => { + throw Error('Can not rewrite read-only method \'' + name + '\''); + }; + } + }); +}; + +const toObjectSet = (arrayOrString, delimiter) => { + const obj = {}; + + const define = (arr) => { + arr.forEach(value => { + obj[value] = true; + }); + }; + + isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); + + return obj; +}; + +const noop = () => {}; + +const toFiniteNumber = (value, defaultValue) => { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; +}; + + + +/** + * If the thing is a FormData object, return true, otherwise return false. + * + * @param {unknown} thing - The thing to check. + * + * @returns {boolean} + */ +function isSpecCompliantForm(thing) { + return !!(thing && isFunction$1(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); +} + +const toJSONObject = (obj) => { + const stack = new Array(10); + + const visit = (source, i) => { + + if (isObject(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + + //Buffer check + if (isBuffer(source)) { + return source; + } + + if(!('toJSON' in source)) { + stack[i] = source; + const target = isArray(source) ? [] : {}; + + forEach(source, (value, key) => { + const reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + + stack[i] = undefined; + + return target; + } + } + + return source; + }; + + return visit(obj, 0); +}; + +const isAsyncFn = kindOfTest('AsyncFunction'); + +const isThenable = (thing) => + thing && (isObject(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing.catch); + +// original code +// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 + +const _setImmediate = ((setImmediateSupported, postMessageSupported) => { + if (setImmediateSupported) { + return setImmediate; + } + + return postMessageSupported ? ((token, callbacks) => { + _global.addEventListener("message", ({source, data}) => { + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + + return (cb) => { + callbacks.push(cb); + _global.postMessage(token, "*"); + } + })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); +})( + typeof setImmediate === 'function', + isFunction$1(_global.postMessage) +); + +const asap = typeof queueMicrotask !== 'undefined' ? + queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate); + +// ********************* + + +const isIterable = (thing) => thing != null && isFunction$1(thing[iterator]); + + +var utils$1 = { + isArray, + isArrayBuffer, + isBuffer, + isFormData, + isArrayBufferView, + isString, + isNumber, + isBoolean, + isObject, + isPlainObject, + isEmptyObject, + isReadableStream, + isRequest, + isResponse, + isHeaders, + isUndefined, + isDate, + isFile, + isBlob, + isRegExp, + isFunction: isFunction$1, + isStream, + isURLSearchParams, + isTypedArray, + isFileList, + forEach, + merge, + extend, + trim, + stripBOM, + inherits, + toFlatObject, + kindOf, + kindOfTest, + endsWith, + toArray, + forEachEntry, + matchAll, + isHTMLForm, + hasOwnProperty, + hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors, + freezeMethods, + toObjectSet, + toCamelCase, + noop, + toFiniteNumber, + findKey, + global: _global, + isContextDefined, + isSpecCompliantForm, + toJSONObject, + isAsyncFn, + isThenable, + setImmediate: _setImmediate, + asap, + isIterable +}; + +/** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ +function AxiosError(message, code, config, request, response) { + Error.call(this); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = (new Error()).stack; + } + + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status ? response.status : null; + } +} + +utils$1.inherits(AxiosError, Error, { + toJSON: function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils$1.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } +}); + +const prototype$1 = AxiosError.prototype; +const descriptors = {}; + +[ + 'ERR_BAD_OPTION_VALUE', + 'ERR_BAD_OPTION', + 'ECONNABORTED', + 'ETIMEDOUT', + 'ERR_NETWORK', + 'ERR_FR_TOO_MANY_REDIRECTS', + 'ERR_DEPRECATED', + 'ERR_BAD_RESPONSE', + 'ERR_BAD_REQUEST', + 'ERR_CANCELED', + 'ERR_NOT_SUPPORT', + 'ERR_INVALID_URL' +// eslint-disable-next-line func-names +].forEach(code => { + descriptors[code] = {value: code}; +}); + +Object.defineProperties(AxiosError, descriptors); +Object.defineProperty(prototype$1, 'isAxiosError', {value: true}); + +// eslint-disable-next-line func-names +AxiosError.from = (error, code, config, request, response, customProps) => { + const axiosError = Object.create(prototype$1); + + utils$1.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }, prop => { + return prop !== 'isAxiosError'; + }); + + const msg = error && error.message ? error.message : 'Error'; + + // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED) + const errCode = code == null && error ? error.code : code; + AxiosError.call(axiosError, msg, errCode, config, request, response); + + // Chain the original error on the standard field; non-enumerable to avoid JSON noise + if (error && axiosError.cause == null) { + Object.defineProperty(axiosError, 'cause', { value: error, configurable: true }); + } + + axiosError.name = (error && error.name) || 'Error'; + + customProps && Object.assign(axiosError, customProps); + + return axiosError; +}; + +// eslint-disable-next-line strict +var httpAdapter = null; + +/** + * Determines if the given thing is a array or js object. + * + * @param {string} thing - The object or array to be visited. + * + * @returns {boolean} + */ +function isVisitable(thing) { + return utils$1.isPlainObject(thing) || utils$1.isArray(thing); +} + +/** + * It removes the brackets from the end of a string + * + * @param {string} key - The key of the parameter. + * + * @returns {string} the key without the brackets. + */ +function removeBrackets(key) { + return utils$1.endsWith(key, '[]') ? key.slice(0, -2) : key; +} + +/** + * It takes a path, a key, and a boolean, and returns a string + * + * @param {string} path - The path to the current key. + * @param {string} key - The key of the current object being iterated over. + * @param {string} dots - If true, the key will be rendered with dots instead of brackets. + * + * @returns {string} The path to the current key. + */ +function renderKey(path, key, dots) { + if (!path) return key; + return path.concat(key).map(function each(token, i) { + // eslint-disable-next-line no-param-reassign + token = removeBrackets(token); + return !dots && i ? '[' + token + ']' : token; + }).join(dots ? '.' : ''); +} + +/** + * If the array is an array and none of its elements are visitable, then it's a flat array. + * + * @param {Array} arr - The array to check + * + * @returns {boolean} + */ +function isFlatArray(arr) { + return utils$1.isArray(arr) && !arr.some(isVisitable); +} + +const predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); +}); + +/** + * Convert a data object to FormData + * + * @param {Object} obj + * @param {?Object} [formData] + * @param {?Object} [options] + * @param {Function} [options.visitor] + * @param {Boolean} [options.metaTokens = true] + * @param {Boolean} [options.dots = false] + * @param {?Boolean} [options.indexes = false] + * + * @returns {Object} + **/ + +/** + * It converts an object into a FormData object + * + * @param {Object} obj - The object to convert to form data. + * @param {string} formData - The FormData object to append to. + * @param {Object} options + * + * @returns + */ +function toFormData(obj, formData, options) { + if (!utils$1.isObject(obj)) { + throw new TypeError('target must be an object'); + } + + // eslint-disable-next-line no-param-reassign + formData = formData || new (FormData)(); + + // eslint-disable-next-line no-param-reassign + options = utils$1.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + // eslint-disable-next-line no-eq-null,eqeqeq + return !utils$1.isUndefined(source[option]); + }); + + const metaTokens = options.metaTokens; + // eslint-disable-next-line no-use-before-define + const visitor = options.visitor || defaultVisitor; + const dots = options.dots; + const indexes = options.indexes; + const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob; + const useBlob = _Blob && utils$1.isSpecCompliantForm(formData); + + if (!utils$1.isFunction(visitor)) { + throw new TypeError('visitor must be a function'); + } + + function convertValue(value) { + if (value === null) return ''; + + if (utils$1.isDate(value)) { + return value.toISOString(); + } + + if (utils$1.isBoolean(value)) { + return value.toString(); + } + + if (!useBlob && utils$1.isBlob(value)) { + throw new AxiosError('Blob is not supported. Use a Buffer instead.'); + } + + if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) { + return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + + return value; + } + + /** + * Default visitor. + * + * @param {*} value + * @param {String|Number} key + * @param {Array} path + * @this {FormData} + * + * @returns {boolean} return true to visit the each prop of the value recursively + */ + function defaultVisitor(value, key, path) { + let arr = value; + + if (value && !path && typeof value === 'object') { + if (utils$1.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + key = metaTokens ? key : key.slice(0, -2); + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if ( + (utils$1.isArray(value) && isFlatArray(value)) || + ((utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value)) + )) { + // eslint-disable-next-line no-param-reassign + key = removeBrackets(key); + + arr.forEach(function each(el, index) { + !(utils$1.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'), + convertValue(el) + ); + }); + return false; + } + } + + if (isVisitable(value)) { + return true; + } + + formData.append(renderKey(path, key, dots), convertValue(value)); + + return false; + } + + const stack = []; + + const exposedHelpers = Object.assign(predicates, { + defaultVisitor, + convertValue, + isVisitable + }); + + function build(value, path) { + if (utils$1.isUndefined(value)) return; + + if (stack.indexOf(value) !== -1) { + throw Error('Circular reference detected in ' + path.join('.')); + } + + stack.push(value); + + utils$1.forEach(value, function each(el, key) { + const result = !(utils$1.isUndefined(el) || el === null) && visitor.call( + formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers + ); + + if (result === true) { + build(el, path ? path.concat(key) : [key]); + } + }); + + stack.pop(); + } + + if (!utils$1.isObject(obj)) { + throw new TypeError('data must be an object'); + } + + build(obj); + + return formData; +} + +/** + * It encodes a string by replacing all characters that are not in the unreserved set with + * their percent-encoded equivalents + * + * @param {string} str - The string to encode. + * + * @returns {string} The encoded string. + */ +function encode$1(str) { + const charMap = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); +} + +/** + * It takes a params object and converts it to a FormData object + * + * @param {Object} params - The parameters to be converted to a FormData object. + * @param {Object} options - The options object passed to the Axios constructor. + * + * @returns {void} + */ +function AxiosURLSearchParams(params, options) { + this._pairs = []; + + params && toFormData(params, this, options); +} + +const prototype = AxiosURLSearchParams.prototype; + +prototype.append = function append(name, value) { + this._pairs.push([name, value]); +}; + +prototype.toString = function toString(encoder) { + const _encode = encoder ? function(value) { + return encoder.call(this, value, encode$1); + } : encode$1; + + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + '=' + _encode(pair[1]); + }, '').join('&'); +}; + +/** + * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their + * URI encoded counterparts + * + * @param {string} val The value to be encoded. + * + * @returns {string} The encoded value. + */ +function encode(val) { + return encodeURIComponent(val). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'); +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @param {?(object|Function)} options + * + * @returns {string} The formatted url + */ +function buildURL(url, params, options) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + + const _encode = options && options.encode || encode; + + if (utils$1.isFunction(options)) { + options = { + serialize: options + }; + } + + const serializeFn = options && options.serialize; + + let serializedParams; + + if (serializeFn) { + serializedParams = serializeFn(params, options); + } else { + serializedParams = utils$1.isURLSearchParams(params) ? + params.toString() : + new AxiosURLSearchParams(params, options).toString(_encode); + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf("#"); + + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + + return url; +} + +class InterceptorManager { + constructor() { + this.handlers = []; + } + + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ + use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled, + rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise + */ + eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + clear() { + if (this.handlers) { + this.handlers = []; + } + } + + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + forEach(fn) { + utils$1.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } +} + +var InterceptorManager$1 = InterceptorManager; + +var transitionalDefaults = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false +}; + +var URLSearchParams$1 = typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams; + +var FormData$1 = typeof FormData !== 'undefined' ? FormData : null; + +var Blob$1 = typeof Blob !== 'undefined' ? Blob : null; + +var platform$1 = { + isBrowser: true, + classes: { + URLSearchParams: URLSearchParams$1, + FormData: FormData$1, + Blob: Blob$1 + }, + protocols: ['http', 'https', 'file', 'blob', 'url', 'data'] +}; + +const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; + +const _navigator = typeof navigator === 'object' && navigator || undefined; + +/** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + * + * @returns {boolean} + */ +const hasStandardBrowserEnv = hasBrowserEnv && + (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); + +/** + * Determine if we're running in a standard browser webWorker environment + * + * Although the `isStandardBrowserEnv` method indicates that + * `allows axios to run in a web worker`, the WebWorker will still be + * filtered out due to its judgment standard + * `typeof window !== 'undefined' && typeof document !== 'undefined'`. + * This leads to a problem when axios post `FormData` in webWorker + */ +const hasStandardBrowserWebWorkerEnv = (() => { + return ( + typeof WorkerGlobalScope !== 'undefined' && + // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && + typeof self.importScripts === 'function' + ); +})(); + +const origin = hasBrowserEnv && window.location.href || 'http://localhost'; + +var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + hasBrowserEnv: hasBrowserEnv, + hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv, + hasStandardBrowserEnv: hasStandardBrowserEnv, + navigator: _navigator, + origin: origin +}); + +var platform = { + ...utils, + ...platform$1 +}; + +function toURLEncodedForm(data, options) { + return toFormData(data, new platform.classes.URLSearchParams(), { + visitor: function(value, key, path, helpers) { + if (platform.isNode && utils$1.isBuffer(value)) { + this.append(key, value.toString('base64')); + return false; + } + + return helpers.defaultVisitor.apply(this, arguments); + }, + ...options + }); +} + +/** + * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] + * + * @param {string} name - The name of the property to get. + * + * @returns An array of strings. + */ +function parsePropPath(name) { + // foo[x][y][z] + // foo.x.y.z + // foo-x-y-z + // foo x y z + return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(match => { + return match[0] === '[]' ? '' : match[1] || match[0]; + }); +} + +/** + * Convert an array to an object. + * + * @param {Array} arr - The array to convert to an object. + * + * @returns An object with the same keys and values as the array. + */ +function arrayToObject(arr) { + const obj = {}; + const keys = Object.keys(arr); + let i; + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; +} + +/** + * It takes a FormData object and returns a JavaScript object + * + * @param {string} formData The FormData object to convert to JSON. + * + * @returns {Object | null} The converted object. + */ +function formDataToJSON(formData) { + function buildPath(path, value, target, index) { + let name = path[index++]; + + if (name === '__proto__') return true; + + const isNumericKey = Number.isFinite(+name); + const isLast = index >= path.length; + name = !name && utils$1.isArray(target) ? target.length : name; + + if (isLast) { + if (utils$1.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + + return !isNumericKey; + } + + if (!target[name] || !utils$1.isObject(target[name])) { + target[name] = []; + } + + const result = buildPath(path, value, target[name], index); + + if (result && utils$1.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + + return !isNumericKey; + } + + if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) { + const obj = {}; + + utils$1.forEachEntry(formData, (name, value) => { + buildPath(parsePropPath(name), value, obj, 0); + }); + + return obj; + } + + return null; +} + +/** + * It takes a string, tries to parse it, and if it fails, it returns the stringified version + * of the input + * + * @param {any} rawValue - The value to be stringified. + * @param {Function} parser - A function that parses a string into a JavaScript object. + * @param {Function} encoder - A function that takes a value and returns a string. + * + * @returns {string} A stringified version of the rawValue. + */ +function stringifySafely(rawValue, parser, encoder) { + if (utils$1.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils$1.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + + return (encoder || JSON.stringify)(rawValue); +} + +const defaults = { + + transitional: transitionalDefaults, + + adapter: ['xhr', 'http', 'fetch'], + + transformRequest: [function transformRequest(data, headers) { + const contentType = headers.getContentType() || ''; + const hasJSONContentType = contentType.indexOf('application/json') > -1; + const isObjectPayload = utils$1.isObject(data); + + if (isObjectPayload && utils$1.isHTMLForm(data)) { + data = new FormData(data); + } + + const isFormData = utils$1.isFormData(data); + + if (isFormData) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + + if (utils$1.isArrayBuffer(data) || + utils$1.isBuffer(data) || + utils$1.isStream(data) || + utils$1.isFile(data) || + utils$1.isBlob(data) || + utils$1.isReadableStream(data) + ) { + return data; + } + if (utils$1.isArrayBufferView(data)) { + return data.buffer; + } + if (utils$1.isURLSearchParams(data)) { + headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); + return data.toString(); + } + + let isFileList; + + if (isObjectPayload) { + if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + + if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) { + const _FormData = this.env && this.env.FormData; + + return toFormData( + isFileList ? {'files[]': data} : data, + _FormData && new _FormData(), + this.formSerializer + ); + } + } + + if (isObjectPayload || hasJSONContentType ) { + headers.setContentType('application/json', false); + return stringifySafely(data); + } + + return data; + }], + + transformResponse: [function transformResponse(data) { + const transitional = this.transitional || defaults.transitional; + const forcedJSONParsing = transitional && transitional.forcedJSONParsing; + const JSONRequested = this.responseType === 'json'; + + if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) { + return data; + } + + if (data && utils$1.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { + const silentJSONParsing = transitional && transitional.silentJSONParsing; + const strictJSONParsing = !silentJSONParsing && JSONRequested; + + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + + return data; + }], + + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + maxContentLength: -1, + maxBodyLength: -1, + + env: { + FormData: platform.classes.FormData, + Blob: platform.classes.Blob + }, + + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': undefined + } + } +}; + +utils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => { + defaults.headers[method] = {}; +}); + +var defaults$1 = defaults; + +// RawAxiosHeaders whose duplicates are ignored by node +// c.f. https://nodejs.org/api/http.html#http_message_headers +const ignoreDuplicateOf = utils$1.toObjectSet([ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' +]); + +/** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} rawHeaders Headers needing to be parsed + * + * @returns {Object} Headers parsed into an object + */ +var parseHeaders = rawHeaders => { + const parsed = {}; + let key; + let val; + let i; + + rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { + i = line.indexOf(':'); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + + if (!key || (parsed[key] && ignoreDuplicateOf[key])) { + return; + } + + if (key === 'set-cookie') { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + }); + + return parsed; +}; + +const $internals = Symbol('internals'); + +function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); +} + +function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + + return utils$1.isArray(value) ? value.map(normalizeValue) : String(value); +} + +function parseTokens(str) { + const tokens = Object.create(null); + const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + let match; + + while ((match = tokensRE.exec(str))) { + tokens[match[1]] = match[2]; + } + + return tokens; +} + +const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + +function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils$1.isFunction(filter)) { + return filter.call(this, value, header); + } + + if (isHeaderNameFilter) { + value = header; + } + + if (!utils$1.isString(value)) return; + + if (utils$1.isString(filter)) { + return value.indexOf(filter) !== -1; + } + + if (utils$1.isRegExp(filter)) { + return filter.test(value); + } +} + +function formatHeader(header) { + return header.trim() + .toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { + return char.toUpperCase() + str; + }); +} + +function buildAccessors(obj, header) { + const accessorName = utils$1.toCamelCase(' ' + header); + + ['get', 'set', 'has'].forEach(methodName => { + Object.defineProperty(obj, methodName + accessorName, { + value: function(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); +} + +class AxiosHeaders { + constructor(headers) { + headers && this.set(headers); + } + + set(header, valueOrRewrite, rewrite) { + const self = this; + + function setHeader(_value, _header, _rewrite) { + const lHeader = normalizeHeader(_header); + + if (!lHeader) { + throw new Error('header name must be a non-empty string'); + } + + const key = utils$1.findKey(self, lHeader); + + if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) { + self[key || _header] = normalizeValue(_value); + } + } + + const setHeaders = (headers, _rewrite) => + utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); + + if (utils$1.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite); + } else if(utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils$1.isObject(header) && utils$1.isIterable(header)) { + let obj = {}, dest, key; + for (const entry of header) { + if (!utils$1.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + + obj[key = entry[0]] = (dest = obj[key]) ? + (utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1]; + } + + setHeaders(obj, valueOrRewrite); + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + + return this; + } + + get(header, parser) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + if (key) { + const value = this[key]; + + if (!parser) { + return value; + } + + if (parser === true) { + return parseTokens(value); + } + + if (utils$1.isFunction(parser)) { + return parser.call(this, value, key); + } + + if (utils$1.isRegExp(parser)) { + return parser.exec(value); + } + + throw new TypeError('parser must be boolean|regexp|function'); + } + } + } + + has(header, matcher) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + + return false; + } + + delete(header, matcher) { + const self = this; + let deleted = false; + + function deleteHeader(_header) { + _header = normalizeHeader(_header); + + if (_header) { + const key = utils$1.findKey(self, _header); + + if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { + delete self[key]; + + deleted = true; + } + } + } + + if (utils$1.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + + return deleted; + } + + clear(matcher) { + const keys = Object.keys(this); + let i = keys.length; + let deleted = false; + + while (i--) { + const key = keys[i]; + if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + + return deleted; + } + + normalize(format) { + const self = this; + const headers = {}; + + utils$1.forEach(this, (value, header) => { + const key = utils$1.findKey(headers, header); + + if (key) { + self[key] = normalizeValue(value); + delete self[header]; + return; + } + + const normalized = format ? formatHeader(header) : String(header).trim(); + + if (normalized !== header) { + delete self[header]; + } + + self[normalized] = normalizeValue(value); + + headers[normalized] = true; + }); + + return this; + } + + concat(...targets) { + return this.constructor.concat(this, ...targets); + } + + toJSON(asStrings) { + const obj = Object.create(null); + + utils$1.forEach(this, (value, header) => { + value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(', ') : value); + }); + + return obj; + } + + [Symbol.iterator]() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + + toString() { + return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n'); + } + + getSetCookie() { + return this.get("set-cookie") || []; + } + + get [Symbol.toStringTag]() { + return 'AxiosHeaders'; + } + + static from(thing) { + return thing instanceof this ? thing : new this(thing); + } + + static concat(first, ...targets) { + const computed = new this(first); + + targets.forEach((target) => computed.set(target)); + + return computed; + } + + static accessor(header) { + const internals = this[$internals] = (this[$internals] = { + accessors: {} + }); + + const accessors = internals.accessors; + const prototype = this.prototype; + + function defineAccessor(_header) { + const lHeader = normalizeHeader(_header); + + if (!accessors[lHeader]) { + buildAccessors(prototype, _header); + accessors[lHeader] = true; + } + } + + utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + + return this; + } +} + +AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); + +// reserved names hotfix +utils$1.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => { + let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` + return { + get: () => value, + set(headerValue) { + this[mapped] = headerValue; + } + } +}); + +utils$1.freezeMethods(AxiosHeaders); + +var AxiosHeaders$1 = AxiosHeaders; + +/** + * Transform the data for a request or a response + * + * @param {Array|Function} fns A single function or Array of functions + * @param {?Object} response The response object + * + * @returns {*} The resulting transformed data + */ +function transformData(fns, response) { + const config = this || defaults$1; + const context = response || config; + const headers = AxiosHeaders$1.from(context.headers); + let data = context.data; + + utils$1.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); + }); + + headers.normalize(); + + return data; +} + +function isCancel(value) { + return !!(value && value.__CANCEL__); +} + +/** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ +function CanceledError(message, config, request) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); + this.name = 'CanceledError'; +} + +utils$1.inherits(CanceledError, AxiosError, { + __CANCEL__: true +}); + +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + * + * @returns {object} The response. + */ +function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError( + 'Request failed with status code ' + response.status, + [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], + response.config, + response.request, + response + )); + } +} + +function parseProtocol(url) { + const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; +} + +/** + * Calculate data maxRate + * @param {Number} [samplesCount= 10] + * @param {Number} [min= 1000] + * @returns {Function} + */ +function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + const bytes = new Array(samplesCount); + const timestamps = new Array(samplesCount); + let head = 0; + let tail = 0; + let firstSampleTS; + + min = min !== undefined ? min : 1000; + + return function push(chunkLength) { + const now = Date.now(); + + const startedAt = timestamps[tail]; + + if (!firstSampleTS) { + firstSampleTS = now; + } + + bytes[head] = chunkLength; + timestamps[head] = now; + + let i = tail; + let bytesCount = 0; + + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + + head = (head + 1) % samplesCount; + + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + + if (now - firstSampleTS < min) { + return; + } + + const passed = startedAt && now - startedAt; + + return passed ? Math.round(bytesCount * 1000 / passed) : undefined; + }; +} + +/** + * Throttle decorator + * @param {Function} fn + * @param {Number} freq + * @return {Function} + */ +function throttle(fn, freq) { + let timestamp = 0; + let threshold = 1000 / freq; + let lastArgs; + let timer; + + const invoke = (args, now = Date.now()) => { + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn(...args); + }; + + const throttled = (...args) => { + const now = Date.now(); + const passed = now - timestamp; + if ( passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(() => { + timer = null; + invoke(lastArgs); + }, threshold - passed); + } + } + }; + + const flush = () => lastArgs && invoke(lastArgs); + + return [throttled, flush]; +} + +const progressEventReducer = (listener, isDownloadStream, freq = 3) => { + let bytesNotified = 0; + const _speedometer = speedometer(50, 250); + + return throttle(e => { + const loaded = e.loaded; + const total = e.lengthComputable ? e.total : undefined; + const progressBytes = loaded - bytesNotified; + const rate = _speedometer(progressBytes); + const inRange = loaded <= total; + + bytesNotified = loaded; + + const data = { + loaded, + total, + progress: total ? (loaded / total) : undefined, + bytes: progressBytes, + rate: rate ? rate : undefined, + estimated: rate && total && inRange ? (total - loaded) / rate : undefined, + event: e, + lengthComputable: total != null, + [isDownloadStream ? 'download' : 'upload']: true + }; + + listener(data); + }, freq); +}; + +const progressEventDecorator = (total, throttled) => { + const lengthComputable = total != null; + + return [(loaded) => throttled[0]({ + lengthComputable, + total, + loaded + }), throttled[1]]; +}; + +const asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args)); + +var isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => { + url = new URL(url, platform.origin); + + return ( + origin.protocol === url.protocol && + origin.host === url.host && + (isMSIE || origin.port === url.port) + ); +})( + new URL(platform.origin), + platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent) +) : () => true; + +var cookies = platform.hasStandardBrowserEnv ? + + // Standard browser envs support document.cookie + { + write(name, value, expires, path, domain, secure) { + const cookie = [name + '=' + encodeURIComponent(value)]; + + utils$1.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString()); + + utils$1.isString(path) && cookie.push('path=' + path); + + utils$1.isString(domain) && cookie.push('domain=' + domain); + + secure === true && cookie.push('secure'); + + document.cookie = cookie.join('; '); + }, + + read(name) { + const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return (match ? decodeURIComponent(match[3]) : null); + }, + + remove(name) { + this.write(name, '', Date.now() - 86400000); + } + } + + : + + // Non-standard browser env (web workers, react-native) lack needed support. + { + write() {}, + read() { + return null; + }, + remove() {} + }; + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); +} + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * + * @returns {string} The combined URL + */ +function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; +} + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * + * @returns {string} The combined full path + */ +function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + let isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; +} + +const headersToObject = (thing) => thing instanceof AxiosHeaders$1 ? { ...thing } : thing; + +/** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * + * @returns {Object} New object resulting from merging config2 to config1 + */ +function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + const config = {}; + + function getMergedValue(target, source, prop, caseless) { + if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) { + return utils$1.merge.call({caseless}, target, source); + } else if (utils$1.isPlainObject(source)) { + return utils$1.merge({}, source); + } else if (utils$1.isArray(source)) { + return source.slice(); + } + return source; + } + + // eslint-disable-next-line consistent-return + function mergeDeepProperties(a, b, prop , caseless) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(a, b, prop , caseless); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a, prop , caseless); + } + } + + // eslint-disable-next-line consistent-return + function valueFromConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } + } + + // eslint-disable-next-line consistent-return + function defaultToConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a); + } + } + + // eslint-disable-next-line consistent-return + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(undefined, a); + } + } + + const mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true) + }; + + utils$1.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) { + const merge = mergeMap[prop] || mergeDeepProperties; + const configValue = merge(config1[prop], config2[prop], prop); + (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); + }); + + return config; +} + +var resolveConfig = (config) => { + const newConfig = mergeConfig({}, config); + + let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig; + + newConfig.headers = headers = AxiosHeaders$1.from(headers); + + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + + // HTTP basic authentication + if (auth) { + headers.set('Authorization', 'Basic ' + + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : '')) + ); + } + + if (utils$1.isFormData(data)) { + if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(undefined); // browser handles it + } else if (utils$1.isFunction(data.getHeaders)) { + // Node.js FormData (like form-data package) + const formHeaders = data.getHeaders(); + // Only set safe headers to avoid overwriting security headers + const allowedHeaders = ['content-type', 'content-length']; + Object.entries(formHeaders).forEach(([key, val]) => { + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + + if (platform.hasStandardBrowserEnv) { + withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + + if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { + // Add xsrf header + const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + + return newConfig; +}; + +const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; + +var xhrAdapter = isXHRAdapterSupported && function (config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + const _config = resolveConfig(config); + let requestData = _config.data; + const requestHeaders = AxiosHeaders$1.from(_config.headers).normalize(); + let {responseType, onUploadProgress, onDownloadProgress} = _config; + let onCanceled; + let uploadThrottled, downloadThrottled; + let flushUpload, flushDownload; + + function done() { + flushUpload && flushUpload(); // flush events + flushDownload && flushDownload(); // flush events + + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + + _config.signal && _config.signal.removeEventListener('abort', onCanceled); + } + + let request = new XMLHttpRequest(); + + request.open(_config.method.toUpperCase(), _config.url, true); + + // Set the request timeout in MS + request.timeout = _config.timeout; + + function onloadend() { + if (!request) { + return; + } + // Prepare the response + const responseHeaders = AxiosHeaders$1.from( + 'getAllResponseHeaders' in request && request.getAllResponseHeaders() + ); + const responseData = !responseType || responseType === 'text' || responseType === 'json' ? + request.responseText : request.response; + const response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config, + request + }; + + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + + // Clean up request + request = null; + } + + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError(event) { + // Browsers deliver a ProgressEvent in XHR onerror + // (message may be empty; when present, surface it) + // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event + const msg = event && event.message ? event.message : 'Network Error'; + const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); + // attach the underlying event for consumers who want details + err.event = event || null; + reject(err); + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + request)); + + // Clean up request + request = null; + }; + + // Remove Content-Type if data is undefined + requestData === undefined && requestHeaders.setContentType(null); + + // Add headers to the request + if ('setRequestHeader' in request) { + utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + + // Add withCredentials to request if needed + if (!utils$1.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + + // Add responseType to request if needed + if (responseType && responseType !== 'json') { + request.responseType = _config.responseType; + } + + // Handle progress if needed + if (onDownloadProgress) { + ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true)); + request.addEventListener('progress', downloadThrottled); + } + + // Not all browsers support upload events + if (onUploadProgress && request.upload) { + ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress)); + + request.upload.addEventListener('progress', uploadThrottled); + + request.upload.addEventListener('loadend', flushUpload); + } + + if (_config.cancelToken || _config.signal) { + // Handle cancellation + // eslint-disable-next-line func-names + onCanceled = cancel => { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); + request.abort(); + request = null; + }; + + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); + } + } + + const protocol = parseProtocol(_config.url); + + if (protocol && platform.protocols.indexOf(protocol) === -1) { + reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config)); + return; + } + + + // Send the request + request.send(requestData || null); + }); +}; + +const composeSignals = (signals, timeout) => { + const {length} = (signals = signals ? signals.filter(Boolean) : []); + + if (timeout || length) { + let controller = new AbortController(); + + let aborted; + + const onabort = function (reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + const err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err)); + } + }; + + let timer = timeout && setTimeout(() => { + timer = null; + onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT)); + }, timeout); + + const unsubscribe = () => { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach(signal => { + signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); + }); + signals = null; + } + }; + + signals.forEach((signal) => signal.addEventListener('abort', onabort)); + + const {signal} = controller; + + signal.unsubscribe = () => utils$1.asap(unsubscribe); + + return signal; + } +}; + +var composeSignals$1 = composeSignals; + +const streamChunk = function* (chunk, chunkSize) { + let len = chunk.byteLength; + + if (!chunkSize || len < chunkSize) { + yield chunk; + return; + } + + let pos = 0; + let end; + + while (pos < len) { + end = pos + chunkSize; + yield chunk.slice(pos, end); + pos = end; + } +}; + +const readBytes = async function* (iterable, chunkSize) { + for await (const chunk of readStream(iterable)) { + yield* streamChunk(chunk, chunkSize); + } +}; + +const readStream = async function* (stream) { + if (stream[Symbol.asyncIterator]) { + yield* stream; + return; + } + + const reader = stream.getReader(); + try { + for (;;) { + const {done, value} = await reader.read(); + if (done) { + break; + } + yield value; + } + } finally { + await reader.cancel(); + } +}; + +const trackStream = (stream, chunkSize, onProgress, onFinish) => { + const iterator = readBytes(stream, chunkSize); + + let bytes = 0; + let done; + let _onFinish = (e) => { + if (!done) { + done = true; + onFinish && onFinish(e); + } + }; + + return new ReadableStream({ + async pull(controller) { + try { + const {done, value} = await iterator.next(); + + if (done) { + _onFinish(); + controller.close(); + return; + } + + let len = value.byteLength; + if (onProgress) { + let loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + } catch (err) { + _onFinish(err); + throw err; + } + }, + cancel(reason) { + _onFinish(reason); + return iterator.return(); + } + }, { + highWaterMark: 2 + }) +}; + +const DEFAULT_CHUNK_SIZE = 64 * 1024; + +const {isFunction} = utils$1; + +const globalFetchAPI = (({Request, Response}) => ({ + Request, Response +}))(utils$1.global); + +const { + ReadableStream: ReadableStream$1, TextEncoder +} = utils$1.global; + + +const test = (fn, ...args) => { + try { + return !!fn(...args); + } catch (e) { + return false + } +}; + +const factory = (env) => { + env = utils$1.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + + const {fetch: envFetch, Request, Response} = env; + const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; + const isRequestSupported = isFunction(Request); + const isResponseSupported = isFunction(Response); + + if (!isFetchSupported) { + return false; + } + + const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1); + + const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ? + ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) : + async (str) => new Uint8Array(await new Request(str).arrayBuffer()) + ); + + const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { + let duplexAccessed = false; + + const hasContentType = new Request(platform.origin, { + body: new ReadableStream$1(), + method: 'POST', + get duplex() { + duplexAccessed = true; + return 'half'; + }, + }).headers.has('Content-Type'); + + return duplexAccessed && !hasContentType; + }); + + const supportsResponseStream = isResponseSupported && isReadableStreamSupported && + test(() => utils$1.isReadableStream(new Response('').body)); + + const resolvers = { + stream: supportsResponseStream && ((res) => res.body) + }; + + isFetchSupported && ((() => { + ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => { + !resolvers[type] && (resolvers[type] = (res, config) => { + let method = res && res[type]; + + if (method) { + return method.call(res); + } + + throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config); + }); + }); + })()); + + const getBodyLength = async (body) => { + if (body == null) { + return 0; + } + + if (utils$1.isBlob(body)) { + return body.size; + } + + if (utils$1.isSpecCompliantForm(body)) { + const _request = new Request(platform.origin, { + method: 'POST', + body, + }); + return (await _request.arrayBuffer()).byteLength; + } + + if (utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body)) { + return body.byteLength; + } + + if (utils$1.isURLSearchParams(body)) { + body = body + ''; + } + + if (utils$1.isString(body)) { + return (await encodeText(body)).byteLength; + } + }; + + const resolveBodyLength = async (headers, body) => { + const length = utils$1.toFiniteNumber(headers.getContentLength()); + + return length == null ? getBodyLength(body) : length; + }; + + return async (config) => { + let { + url, + method, + data, + signal, + cancelToken, + timeout, + onDownloadProgress, + onUploadProgress, + responseType, + headers, + withCredentials = 'same-origin', + fetchOptions + } = resolveConfig(config); + + let _fetch = envFetch || fetch; + + responseType = responseType ? (responseType + '').toLowerCase() : 'text'; + + let composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + + let request = null; + + const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { + composedSignal.unsubscribe(); + }); + + let requestContentLength; + + try { + if ( + onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && + (requestContentLength = await resolveBodyLength(headers, data)) !== 0 + ) { + let _request = new Request(url, { + method: 'POST', + body: data, + duplex: "half" + }); + + let contentTypeHeader; + + if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { + headers.setContentType(contentTypeHeader); + } + + if (_request.body) { + const [onProgress, flush] = progressEventDecorator( + requestContentLength, + progressEventReducer(asyncDecorator(onUploadProgress)) + ); + + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + } + + if (!utils$1.isString(withCredentials)) { + withCredentials = withCredentials ? 'include' : 'omit'; + } + + // Cloudflare Workers throws when credentials are defined + // see https://github.com/cloudflare/workerd/issues/902 + const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + + const resolvedOptions = { + ...fetchOptions, + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : undefined + }; + + request = isRequestSupported && new Request(url, resolvedOptions); + + let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions)); + + const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); + + if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) { + const options = {}; + + ['status', 'statusText', 'headers'].forEach(prop => { + options[prop] = response[prop]; + }); + + const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length')); + + const [onProgress, flush] = onDownloadProgress && progressEventDecorator( + responseContentLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true) + ) || []; + + response = new Response( + trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => { + flush && flush(); + unsubscribe && unsubscribe(); + }), + options + ); + } + + responseType = responseType || 'text'; + + let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config); + + !isStreamResponse && unsubscribe && unsubscribe(); + + return await new Promise((resolve, reject) => { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders$1.from(response.headers), + status: response.status, + statusText: response.statusText, + config, + request + }); + }) + } catch (err) { + unsubscribe && unsubscribe(); + + if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) { + throw Object.assign( + new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request), + { + cause: err.cause || err + } + ) + } + + throw AxiosError.from(err, err && err.code, config, request); + } + } +}; + +const seedCache = new Map(); + +const getFetch = (config) => { + let env = config ? config.env : {}; + const {fetch, Request, Response} = env; + const seeds = [ + Request, Response, fetch + ]; + + let len = seeds.length, i = len, + seed, target, map = seedCache; + + while (i--) { + seed = seeds[i]; + target = map.get(seed); + + target === undefined && map.set(seed, target = (i ? new Map() : factory(env))); + + map = target; + } + + return target; +}; + +getFetch(); + +const knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: getFetch, + } +}; + +utils$1.forEach(knownAdapters, (fn, value) => { + if (fn) { + try { + Object.defineProperty(fn, 'name', {value}); + } catch (e) { + // eslint-disable-next-line no-empty + } + Object.defineProperty(fn, 'adapterName', {value}); + } +}); + +const renderReason = (reason) => `- ${reason}`; + +const isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false; + +var adapters = { + getAdapter: (adapters, config) => { + adapters = utils$1.isArray(adapters) ? adapters : [adapters]; + + const {length} = adapters; + let nameOrAdapter; + let adapter; + + const rejectedReasons = {}; + + for (let i = 0; i < length; i++) { + nameOrAdapter = adapters[i]; + let id; + + adapter = nameOrAdapter; + + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + + if (adapter === undefined) { + throw new AxiosError(`Unknown adapter '${id}'`); + } + } + + if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + + rejectedReasons[id || '#' + i] = adapter; + } + + if (!adapter) { + + const reasons = Object.entries(rejectedReasons) + .map(([id, state]) => `adapter ${id} ` + + (state === false ? 'is not supported by the environment' : 'is not available in the build') + ); + + let s = length ? + (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) : + 'as no adapter specified'; + + throw new AxiosError( + `There is no suitable adapter to dispatch the request ` + s, + 'ERR_NOT_SUPPORT' + ); + } + + return adapter; + }, + adapters: knownAdapters +}; + +/** + * Throws a `CanceledError` if cancellation has been requested. + * + * @param {Object} config The config that is to be used for the request + * + * @returns {void} + */ +function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + + if (config.signal && config.signal.aborted) { + throw new CanceledError(null, config); + } +} + +/** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * + * @returns {Promise} The Promise to be fulfilled + */ +function dispatchRequest(config) { + throwIfCancellationRequested(config); + + config.headers = AxiosHeaders$1.from(config.headers); + + // Transform request data + config.data = transformData.call( + config, + config.transformRequest + ); + + if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { + config.headers.setContentType('application/x-www-form-urlencoded', false); + } + + const adapter = adapters.getAdapter(config.adapter || defaults$1.adapter, config); + + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData.call( + config, + config.transformResponse, + response + ); + + response.headers = AxiosHeaders$1.from(response.headers); + + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData.call( + config, + config.transformResponse, + reason.response + ); + reason.response.headers = AxiosHeaders$1.from(reason.response.headers); + } + } + + return Promise.reject(reason); + }); +} + +const VERSION = "1.12.2"; + +const validators$1 = {}; + +// eslint-disable-next-line func-names +['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => { + validators$1[type] = function validator(thing) { + return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; +}); + +const deprecatedWarnings = {}; + +/** + * Transitional option validator + * + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * + * @returns {function} + */ +validators$1.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return (value, opt, opts) => { + if (validator === false) { + throw new AxiosError( + formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), + AxiosError.ERR_DEPRECATED + ); + } + + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn( + formatMessage( + opt, + ' has been deprecated since v' + version + ' and will be removed in the near future' + ) + ); + } + + return validator ? validator(value, opt, opts) : true; + }; +}; + +validators$1.spelling = function spelling(correctSpelling) { + return (value, opt) => { + // eslint-disable-next-line no-console + console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); + return true; + } +}; + +/** + * Assert object's properties type + * + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + * + * @returns {object} + */ + +function assertOptions(options, schema, allowUnknown) { + if (typeof options !== 'object') { + throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE); + } + const keys = Object.keys(options); + let i = keys.length; + while (i-- > 0) { + const opt = keys[i]; + const validator = schema[opt]; + if (validator) { + const value = options[opt]; + const result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION); + } + } +} + +var validator = { + assertOptions, + validators: validators$1 +}; + +const validators = validator.validators; + +/** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + * + * @return {Axios} A new instance of Axios + */ +class Axios { + constructor(instanceConfig) { + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager$1(), + response: new InterceptorManager$1() + }; + } + + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + async request(configOrUrl, config) { + try { + return await this._request(configOrUrl, config); + } catch (err) { + if (err instanceof Error) { + let dummy = {}; + + Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error()); + + // slice off the Error: ... line + const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : ''; + try { + if (!err.stack) { + err.stack = stack; + // match without the 2 top stack lines + } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\n.+\n/, ''))) { + err.stack += '\n' + stack; + } + } catch (e) { + // ignore the case where "stack" is an un-writable property + } + } + + throw err; + } + } + + _request(configOrUrl, config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof configOrUrl === 'string') { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + + config = mergeConfig(this.defaults, config); + + const {transitional, paramsSerializer, headers} = config; + + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean) + }, false); + } + + if (paramsSerializer != null) { + if (utils$1.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + }; + } else { + validator.assertOptions(paramsSerializer, { + encode: validators.function, + serialize: validators.function + }, true); + } + } + + // Set config.allowAbsoluteUrls + if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + + validator.assertOptions(config, { + baseUrl: validators.spelling('baseURL'), + withXsrfToken: validators.spelling('withXSRFToken') + }, true); + + // Set config.method + config.method = (config.method || this.defaults.method || 'get').toLowerCase(); + + // Flatten headers + let contextHeaders = headers && utils$1.merge( + headers.common, + headers[config.method] + ); + + headers && utils$1.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + (method) => { + delete headers[method]; + } + ); + + config.headers = AxiosHeaders$1.concat(contextHeaders, headers); + + // filter out skipped interceptors + const requestInterceptorChain = []; + let synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + + const responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + + let promise; + let i = 0; + let len; + + if (!synchronousRequestInterceptors) { + const chain = [dispatchRequest.bind(this), undefined]; + chain.unshift(...requestInterceptorChain); + chain.push(...responseInterceptorChain); + len = chain.length; + + promise = Promise.resolve(config); + + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + + return promise; + } + + len = requestInterceptorChain.length; + + let newConfig = config; + + while (i < len) { + const onFulfilled = requestInterceptorChain[i++]; + const onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + + i = 0; + len = responseInterceptorChain.length; + + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + + return promise; + } + + getUri(config) { + config = mergeConfig(this.defaults, config); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } +} + +// Provide aliases for supported request methods +utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, config) { + return this.request(mergeConfig(config || {}, { + method, + url, + data: (config || {}).data + })); + }; +}); + +utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig(config || {}, { + method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url, + data + })); + }; + } + + Axios.prototype[method] = generateHTTPMethod(); + + Axios.prototype[method + 'Form'] = generateHTTPMethod(true); +}); + +var Axios$1 = Axios; + +/** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @param {Function} executor The executor function. + * + * @returns {CancelToken} + */ +class CancelToken { + constructor(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + + let resolvePromise; + + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + + const token = this; + + // eslint-disable-next-line func-names + this.promise.then(cancel => { + if (!token._listeners) return; + + let i = token._listeners.length; + + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = onfulfilled => { + let _resolve; + // eslint-disable-next-line func-names + const promise = new Promise(resolve => { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + + return promise; + }; + + executor(function cancel(message, config, request) { + if (token.reason) { + // Cancellation has already been requested + return; + } + + token.reason = new CanceledError(message, config, request); + resolvePromise(token.reason); + }); + } + + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + + /** + * Subscribe to the cancel signal + */ + + subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + + /** + * Unsubscribe from the cancel signal + */ + + unsubscribe(listener) { + if (!this._listeners) { + return; + } + const index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + + toAbortSignal() { + const controller = new AbortController(); + + const abort = (err) => { + controller.abort(err); + }; + + this.subscribe(abort); + + controller.signal.unsubscribe = () => this.unsubscribe(abort); + + return controller.signal; + } + + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + static source() { + let cancel; + const token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token, + cancel + }; + } +} + +var CancelToken$1 = CancelToken; + +/** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * + * @returns {Function} + */ +function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; +} + +/** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ +function isAxiosError(payload) { + return utils$1.isObject(payload) && (payload.isAxiosError === true); +} + +const HttpStatusCode = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511, +}; + +Object.entries(HttpStatusCode).forEach(([key, value]) => { + HttpStatusCode[value] = key; +}); + +var HttpStatusCode$1 = HttpStatusCode; + +/** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * + * @returns {Axios} A new instance of Axios + */ +function createInstance(defaultConfig) { + const context = new Axios$1(defaultConfig); + const instance = bind(Axios$1.prototype.request, context); + + // Copy axios.prototype to instance + utils$1.extend(instance, Axios$1.prototype, context, {allOwnKeys: true}); + + // Copy context to instance + utils$1.extend(instance, context, null, {allOwnKeys: true}); + + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + + return instance; +} + +// Create the default instance to be exported +const axios = createInstance(defaults$1); + +// Expose Axios class to allow class inheritance +axios.Axios = Axios$1; + +// Expose Cancel & CancelToken +axios.CanceledError = CanceledError; +axios.CancelToken = CancelToken$1; +axios.isCancel = isCancel; +axios.VERSION = VERSION; +axios.toFormData = toFormData; + +// Expose AxiosError class +axios.AxiosError = AxiosError; + +// alias for CanceledError for backward compatibility +axios.Cancel = axios.CanceledError; + +// Expose all/spread +axios.all = function all(promises) { + return Promise.all(promises); +}; + +axios.spread = spread; + +// Expose isAxiosError +axios.isAxiosError = isAxiosError; + +// Expose mergeConfig +axios.mergeConfig = mergeConfig; + +axios.AxiosHeaders = AxiosHeaders$1; + +axios.formToJSON = thing => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing); + +axios.getAdapter = adapters.getAdapter; + +axios.HttpStatusCode = HttpStatusCode$1; + +axios.default = axios; + +module.exports = axios; +//# sourceMappingURL=axios.cjs.map diff --git a/node_modules/axios/dist/browser/axios.cjs.map b/node_modules/axios/dist/browser/axios.cjs.map new file mode 100644 index 0000000..9eaa0f7 --- /dev/null +++ b/node_modules/axios/dist/browser/axios.cjs.map @@ -0,0 +1 @@ +{"version":3,"file":"axios.cjs","sources":["../../lib/helpers/bind.js","../../lib/utils.js","../../lib/core/AxiosError.js","../../lib/helpers/null.js","../../lib/helpers/toFormData.js","../../lib/helpers/AxiosURLSearchParams.js","../../lib/helpers/buildURL.js","../../lib/core/InterceptorManager.js","../../lib/defaults/transitional.js","../../lib/platform/browser/classes/URLSearchParams.js","../../lib/platform/browser/classes/FormData.js","../../lib/platform/browser/classes/Blob.js","../../lib/platform/browser/index.js","../../lib/platform/common/utils.js","../../lib/platform/index.js","../../lib/helpers/toURLEncodedForm.js","../../lib/helpers/formDataToJSON.js","../../lib/defaults/index.js","../../lib/helpers/parseHeaders.js","../../lib/core/AxiosHeaders.js","../../lib/core/transformData.js","../../lib/cancel/isCancel.js","../../lib/cancel/CanceledError.js","../../lib/core/settle.js","../../lib/helpers/parseProtocol.js","../../lib/helpers/speedometer.js","../../lib/helpers/throttle.js","../../lib/helpers/progressEventReducer.js","../../lib/helpers/isURLSameOrigin.js","../../lib/helpers/cookies.js","../../lib/helpers/isAbsoluteURL.js","../../lib/helpers/combineURLs.js","../../lib/core/buildFullPath.js","../../lib/core/mergeConfig.js","../../lib/helpers/resolveConfig.js","../../lib/adapters/xhr.js","../../lib/helpers/composeSignals.js","../../lib/helpers/trackStream.js","../../lib/adapters/fetch.js","../../lib/adapters/adapters.js","../../lib/core/dispatchRequest.js","../../lib/env/data.js","../../lib/helpers/validator.js","../../lib/core/Axios.js","../../lib/cancel/CancelToken.js","../../lib/helpers/spread.js","../../lib/helpers/isAxiosError.js","../../lib/helpers/HttpStatusCode.js","../../lib/axios.js"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n // Early return for non-objects or Buffers to prevent RangeError\n if (!isObject(val) || isBuffer(val)) {\n return false;\n }\n\n try {\n return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n } catch (e) {\n // Fallback for any other objects that might cause RangeError with Object.keys()\n return false;\n }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Buffer check\n if (isBuffer(obj)) {\n return;\n }\n\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n if (isBuffer(obj)){\n return null;\n }\n\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else if (!skipUndefined || !isUndefined(val)) {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n //Buffer check\n if (isBuffer(source)) {\n return source;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isEmptyObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n const msg = error && error.message ? error.message : 'Error';\n\n // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n const errCode = code == null && error ? error.code : code;\n AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n if (error && axiosError.cause == null) {\n Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n }\n\n axiosError.name = (error && error.name) || 'Error';\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), {\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n },\n ...options\n });\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data, this.parseReviver);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn(...args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // browser handles it\n } else if (utils.isFunction(data.getHeaders)) {\n // Node.js FormData (like form-data package)\n const formHeaders = data.getHeaders();\n // Only set safe headers to avoid overwriting security headers\n const allowedHeaders = ['content-type', 'content-length'];\n Object.entries(formHeaders).forEach(([key, val]) => {\n if (allowedHeaders.includes(key.toLowerCase())) {\n headers.set(key, val);\n }\n });\n }\n } \n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError(event) {\n // Browsers deliver a ProgressEvent in XHR onerror\n // (message may be empty; when present, surface it)\n // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n const msg = event && event.message ? event.message : 'Network Error';\n const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n // attach the underlying event for consumers who want details\n err.event = event || null;\n reject(err);\n request = null;\n };\n \n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n Request, Response\n}))(utils.global);\n\nconst {\n ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst factory = (env) => {\n env = utils.merge.call({\n skipUndefined: true\n }, globalFetchAPI, env);\n\n const {fetch: envFetch, Request, Response} = env;\n const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n const isRequestSupported = isFunction(Request);\n const isResponseSupported = isFunction(Response);\n\n if (!isFetchSupported) {\n return false;\n }\n\n const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n );\n\n const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n });\n\n const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n const resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n };\n\n isFetchSupported && ((() => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = (res, config) => {\n let method = res && res[type];\n\n if (method) {\n return method.call(res);\n }\n\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n })());\n\n const getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if (utils.isBlob(body)) {\n return body.size;\n }\n\n if (utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if (utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if (utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n }\n\n const resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n }\n\n return async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n let _fetch = envFetch || fetch;\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request = null;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n const resolvedOptions = {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n };\n\n request = isRequestSupported && new Request(url, resolvedOptions);\n\n let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n let env = config ? config.env : {};\n const {fetch, Request, Response} = env;\n const seeds = [\n Request, Response, fetch\n ];\n\n let len = seeds.length, i = len,\n seed, target, map = seedCache;\n\n while (i--) {\n seed = seeds[i];\n target = map.get(seed);\n\n target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n map = target;\n }\n\n return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: {\n get: fetchAdapter.getFetch,\n }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters, config) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift(...requestInterceptorChain);\n chain.push(...responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n"],"names":["isFunction","utils","prototype","encode","URLSearchParams","FormData","Blob","platform","defaults","AxiosHeaders","ReadableStream","composeSignals","fetchAdapter.getFetch","validators","InterceptorManager","Axios","CancelToken","HttpStatusCode"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/axios/dist/esm/axios.js b/node_modules/axios/dist/esm/axios.js new file mode 100644 index 0000000..6e10897 --- /dev/null +++ b/node_modules/axios/dist/esm/axios.js @@ -0,0 +1,3863 @@ +/*! Axios v1.12.2 Copyright (c) 2025 Matt Zabriskie and contributors */ +function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; +} + +// utils is a library of generic helper functions non-specific to axios + +const {toString} = Object.prototype; +const {getPrototypeOf} = Object; +const {iterator, toStringTag} = Symbol; + +const kindOf = (cache => thing => { + const str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); +})(Object.create(null)); + +const kindOfTest = (type) => { + type = type.toLowerCase(); + return (thing) => kindOf(thing) === type +}; + +const typeOfTest = type => thing => typeof thing === type; + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * + * @returns {boolean} True if value is an Array, otherwise false + */ +const {isArray} = Array; + +/** + * Determine if a value is undefined + * + * @param {*} val The value to test + * + * @returns {boolean} True if the value is undefined, otherwise false + */ +const isUndefined = typeOfTest('undefined'); + +/** + * Determine if a value is a Buffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Buffer, otherwise false + */ +function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); +} + +/** + * Determine if a value is an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ +const isArrayBuffer = kindOfTest('ArrayBuffer'); + + +/** + * Determine if a value is a view on an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ +function isArrayBufferView(val) { + let result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); + } + return result; +} + +/** + * Determine if a value is a String + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a String, otherwise false + */ +const isString = typeOfTest('string'); + +/** + * Determine if a value is a Function + * + * @param {*} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ +const isFunction$1 = typeOfTest('function'); + +/** + * Determine if a value is a Number + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Number, otherwise false + */ +const isNumber = typeOfTest('number'); + +/** + * Determine if a value is an Object + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an Object, otherwise false + */ +const isObject = (thing) => thing !== null && typeof thing === 'object'; + +/** + * Determine if a value is a Boolean + * + * @param {*} thing The value to test + * @returns {boolean} True if value is a Boolean, otherwise false + */ +const isBoolean = thing => thing === true || thing === false; + +/** + * Determine if a value is a plain Object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a plain Object, otherwise false + */ +const isPlainObject = (val) => { + if (kindOf(val) !== 'object') { + return false; + } + + const prototype = getPrototypeOf(val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); +}; + +/** + * Determine if a value is an empty object (safely handles Buffers) + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an empty object, otherwise false + */ +const isEmptyObject = (val) => { + // Early return for non-objects or Buffers to prevent RangeError + if (!isObject(val) || isBuffer(val)) { + return false; + } + + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + // Fallback for any other objects that might cause RangeError with Object.keys() + return false; + } +}; + +/** + * Determine if a value is a Date + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Date, otherwise false + */ +const isDate = kindOfTest('Date'); + +/** + * Determine if a value is a File + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFile = kindOfTest('File'); + +/** + * Determine if a value is a Blob + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Blob, otherwise false + */ +const isBlob = kindOfTest('Blob'); + +/** + * Determine if a value is a FileList + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFileList = kindOfTest('FileList'); + +/** + * Determine if a value is a Stream + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Stream, otherwise false + */ +const isStream = (val) => isObject(val) && isFunction$1(val.pipe); + +/** + * Determine if a value is a FormData + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an FormData, otherwise false + */ +const isFormData = (thing) => { + let kind; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || ( + isFunction$1(thing.append) && ( + (kind = kindOf(thing)) === 'formdata' || + // detect form-data instance + (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]') + ) + ) + ) +}; + +/** + * Determine if a value is a URLSearchParams object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +const isURLSearchParams = kindOfTest('URLSearchParams'); + +const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest); + +/** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * + * @returns {String} The String freed of excess whitespace + */ +const trim = (str) => str.trim ? + str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + * + * @param {Boolean} [allOwnKeys = false] + * @returns {any} + */ +function forEach(obj, fn, {allOwnKeys = false} = {}) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + + let i; + let l; + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + + if (isArray(obj)) { + // Iterate over array values + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Buffer check + if (isBuffer(obj)) { + return; + } + + // Iterate over object keys + const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + const len = keys.length; + let key; + + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } +} + +function findKey(obj, key) { + if (isBuffer(obj)){ + return null; + } + + key = key.toLowerCase(); + const keys = Object.keys(obj); + let i = keys.length; + let _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; +} + +const _global = (() => { + /*eslint no-undef:0*/ + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : global) +})(); + +const isContextDefined = (context) => !isUndefined(context) && context !== _global; + +/** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * + * @returns {Object} Result of all merge properties + */ +function merge(/* obj1, obj2, obj3, ... */) { + const {caseless, skipUndefined} = isContextDefined(this) && this || {}; + const result = {}; + const assignValue = (val, key) => { + const targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + }; + + for (let i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * + * @param {Boolean} [allOwnKeys] + * @returns {Object} The resulting value of object a + */ +const extend = (a, b, thisArg, {allOwnKeys}= {}) => { + forEach(b, (val, key) => { + if (thisArg && isFunction$1(val)) { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }, {allOwnKeys}); + return a; +}; + +/** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * + * @returns {string} content value without BOM + */ +const stripBOM = (content) => { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; +}; + +/** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + * + * @returns {void} + */ +const inherits = (constructor, superConstructor, props, descriptors) => { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + Object.defineProperty(constructor, 'super', { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); +}; + +/** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function|Boolean} [filter] + * @param {Function} [propFilter] + * + * @returns {Object} + */ +const toFlatObject = (sourceObj, destObj, filter, propFilter) => { + let props; + let i; + let prop; + const merged = {}; + + destObj = destObj || {}; + // eslint-disable-next-line no-eq-null,eqeqeq + if (sourceObj == null) return destObj; + + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + + return destObj; +}; + +/** + * Determines whether a string ends with the characters of a specified string + * + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * + * @returns {boolean} + */ +const endsWith = (str, searchString, position) => { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + const lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; +}; + + +/** + * Returns new array from array like object or null if failed + * + * @param {*} [thing] + * + * @returns {?Array} + */ +const toArray = (thing) => { + if (!thing) return null; + if (isArray(thing)) return thing; + let i = thing.length; + if (!isNumber(i)) return null; + const arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; +}; + +/** + * Checking if the Uint8Array exists and if it does, it returns a function that checks if the + * thing passed in is an instance of Uint8Array + * + * @param {TypedArray} + * + * @returns {Array} + */ +// eslint-disable-next-line func-names +const isTypedArray = (TypedArray => { + // eslint-disable-next-line func-names + return thing => { + return TypedArray && thing instanceof TypedArray; + }; +})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); + +/** + * For each entry in the object, call the function with the key and value. + * + * @param {Object} obj - The object to iterate over. + * @param {Function} fn - The function to call for each entry. + * + * @returns {void} + */ +const forEachEntry = (obj, fn) => { + const generator = obj && obj[iterator]; + + const _iterator = generator.call(obj); + + let result; + + while ((result = _iterator.next()) && !result.done) { + const pair = result.value; + fn.call(obj, pair[0], pair[1]); + } +}; + +/** + * It takes a regular expression and a string, and returns an array of all the matches + * + * @param {string} regExp - The regular expression to match against. + * @param {string} str - The string to search. + * + * @returns {Array} + */ +const matchAll = (regExp, str) => { + let matches; + const arr = []; + + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + + return arr; +}; + +/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ +const isHTMLForm = kindOfTest('HTMLFormElement'); + +const toCamelCase = str => { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, + function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + } + ); +}; + +/* Creating a function that will check if an object has a property. */ +const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype); + +/** + * Determine if a value is a RegExp object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a RegExp object, otherwise false + */ +const isRegExp = kindOfTest('RegExp'); + +const reduceDescriptors = (obj, reducer) => { + const descriptors = Object.getOwnPropertyDescriptors(obj); + const reducedDescriptors = {}; + + forEach(descriptors, (descriptor, name) => { + let ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + + Object.defineProperties(obj, reducedDescriptors); +}; + +/** + * Makes all methods read-only + * @param {Object} obj + */ + +const freezeMethods = (obj) => { + reduceDescriptors(obj, (descriptor, name) => { + // skip restricted props in strict mode + if (isFunction$1(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { + return false; + } + + const value = obj[name]; + + if (!isFunction$1(value)) return; + + descriptor.enumerable = false; + + if ('writable' in descriptor) { + descriptor.writable = false; + return; + } + + if (!descriptor.set) { + descriptor.set = () => { + throw Error('Can not rewrite read-only method \'' + name + '\''); + }; + } + }); +}; + +const toObjectSet = (arrayOrString, delimiter) => { + const obj = {}; + + const define = (arr) => { + arr.forEach(value => { + obj[value] = true; + }); + }; + + isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); + + return obj; +}; + +const noop = () => {}; + +const toFiniteNumber = (value, defaultValue) => { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; +}; + + + +/** + * If the thing is a FormData object, return true, otherwise return false. + * + * @param {unknown} thing - The thing to check. + * + * @returns {boolean} + */ +function isSpecCompliantForm(thing) { + return !!(thing && isFunction$1(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); +} + +const toJSONObject = (obj) => { + const stack = new Array(10); + + const visit = (source, i) => { + + if (isObject(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + + //Buffer check + if (isBuffer(source)) { + return source; + } + + if(!('toJSON' in source)) { + stack[i] = source; + const target = isArray(source) ? [] : {}; + + forEach(source, (value, key) => { + const reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + + stack[i] = undefined; + + return target; + } + } + + return source; + }; + + return visit(obj, 0); +}; + +const isAsyncFn = kindOfTest('AsyncFunction'); + +const isThenable = (thing) => + thing && (isObject(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing.catch); + +// original code +// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 + +const _setImmediate = ((setImmediateSupported, postMessageSupported) => { + if (setImmediateSupported) { + return setImmediate; + } + + return postMessageSupported ? ((token, callbacks) => { + _global.addEventListener("message", ({source, data}) => { + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + + return (cb) => { + callbacks.push(cb); + _global.postMessage(token, "*"); + } + })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); +})( + typeof setImmediate === 'function', + isFunction$1(_global.postMessage) +); + +const asap = typeof queueMicrotask !== 'undefined' ? + queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate); + +// ********************* + + +const isIterable = (thing) => thing != null && isFunction$1(thing[iterator]); + + +const utils$1 = { + isArray, + isArrayBuffer, + isBuffer, + isFormData, + isArrayBufferView, + isString, + isNumber, + isBoolean, + isObject, + isPlainObject, + isEmptyObject, + isReadableStream, + isRequest, + isResponse, + isHeaders, + isUndefined, + isDate, + isFile, + isBlob, + isRegExp, + isFunction: isFunction$1, + isStream, + isURLSearchParams, + isTypedArray, + isFileList, + forEach, + merge, + extend, + trim, + stripBOM, + inherits, + toFlatObject, + kindOf, + kindOfTest, + endsWith, + toArray, + forEachEntry, + matchAll, + isHTMLForm, + hasOwnProperty, + hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors, + freezeMethods, + toObjectSet, + toCamelCase, + noop, + toFiniteNumber, + findKey, + global: _global, + isContextDefined, + isSpecCompliantForm, + toJSONObject, + isAsyncFn, + isThenable, + setImmediate: _setImmediate, + asap, + isIterable +}; + +/** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ +function AxiosError$1(message, code, config, request, response) { + Error.call(this); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = (new Error()).stack; + } + + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status ? response.status : null; + } +} + +utils$1.inherits(AxiosError$1, Error, { + toJSON: function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils$1.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } +}); + +const prototype$1 = AxiosError$1.prototype; +const descriptors = {}; + +[ + 'ERR_BAD_OPTION_VALUE', + 'ERR_BAD_OPTION', + 'ECONNABORTED', + 'ETIMEDOUT', + 'ERR_NETWORK', + 'ERR_FR_TOO_MANY_REDIRECTS', + 'ERR_DEPRECATED', + 'ERR_BAD_RESPONSE', + 'ERR_BAD_REQUEST', + 'ERR_CANCELED', + 'ERR_NOT_SUPPORT', + 'ERR_INVALID_URL' +// eslint-disable-next-line func-names +].forEach(code => { + descriptors[code] = {value: code}; +}); + +Object.defineProperties(AxiosError$1, descriptors); +Object.defineProperty(prototype$1, 'isAxiosError', {value: true}); + +// eslint-disable-next-line func-names +AxiosError$1.from = (error, code, config, request, response, customProps) => { + const axiosError = Object.create(prototype$1); + + utils$1.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }, prop => { + return prop !== 'isAxiosError'; + }); + + const msg = error && error.message ? error.message : 'Error'; + + // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED) + const errCode = code == null && error ? error.code : code; + AxiosError$1.call(axiosError, msg, errCode, config, request, response); + + // Chain the original error on the standard field; non-enumerable to avoid JSON noise + if (error && axiosError.cause == null) { + Object.defineProperty(axiosError, 'cause', { value: error, configurable: true }); + } + + axiosError.name = (error && error.name) || 'Error'; + + customProps && Object.assign(axiosError, customProps); + + return axiosError; +}; + +// eslint-disable-next-line strict +const httpAdapter = null; + +/** + * Determines if the given thing is a array or js object. + * + * @param {string} thing - The object or array to be visited. + * + * @returns {boolean} + */ +function isVisitable(thing) { + return utils$1.isPlainObject(thing) || utils$1.isArray(thing); +} + +/** + * It removes the brackets from the end of a string + * + * @param {string} key - The key of the parameter. + * + * @returns {string} the key without the brackets. + */ +function removeBrackets(key) { + return utils$1.endsWith(key, '[]') ? key.slice(0, -2) : key; +} + +/** + * It takes a path, a key, and a boolean, and returns a string + * + * @param {string} path - The path to the current key. + * @param {string} key - The key of the current object being iterated over. + * @param {string} dots - If true, the key will be rendered with dots instead of brackets. + * + * @returns {string} The path to the current key. + */ +function renderKey(path, key, dots) { + if (!path) return key; + return path.concat(key).map(function each(token, i) { + // eslint-disable-next-line no-param-reassign + token = removeBrackets(token); + return !dots && i ? '[' + token + ']' : token; + }).join(dots ? '.' : ''); +} + +/** + * If the array is an array and none of its elements are visitable, then it's a flat array. + * + * @param {Array} arr - The array to check + * + * @returns {boolean} + */ +function isFlatArray(arr) { + return utils$1.isArray(arr) && !arr.some(isVisitable); +} + +const predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); +}); + +/** + * Convert a data object to FormData + * + * @param {Object} obj + * @param {?Object} [formData] + * @param {?Object} [options] + * @param {Function} [options.visitor] + * @param {Boolean} [options.metaTokens = true] + * @param {Boolean} [options.dots = false] + * @param {?Boolean} [options.indexes = false] + * + * @returns {Object} + **/ + +/** + * It converts an object into a FormData object + * + * @param {Object} obj - The object to convert to form data. + * @param {string} formData - The FormData object to append to. + * @param {Object} options + * + * @returns + */ +function toFormData$1(obj, formData, options) { + if (!utils$1.isObject(obj)) { + throw new TypeError('target must be an object'); + } + + // eslint-disable-next-line no-param-reassign + formData = formData || new (FormData)(); + + // eslint-disable-next-line no-param-reassign + options = utils$1.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + // eslint-disable-next-line no-eq-null,eqeqeq + return !utils$1.isUndefined(source[option]); + }); + + const metaTokens = options.metaTokens; + // eslint-disable-next-line no-use-before-define + const visitor = options.visitor || defaultVisitor; + const dots = options.dots; + const indexes = options.indexes; + const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob; + const useBlob = _Blob && utils$1.isSpecCompliantForm(formData); + + if (!utils$1.isFunction(visitor)) { + throw new TypeError('visitor must be a function'); + } + + function convertValue(value) { + if (value === null) return ''; + + if (utils$1.isDate(value)) { + return value.toISOString(); + } + + if (utils$1.isBoolean(value)) { + return value.toString(); + } + + if (!useBlob && utils$1.isBlob(value)) { + throw new AxiosError$1('Blob is not supported. Use a Buffer instead.'); + } + + if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) { + return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + + return value; + } + + /** + * Default visitor. + * + * @param {*} value + * @param {String|Number} key + * @param {Array} path + * @this {FormData} + * + * @returns {boolean} return true to visit the each prop of the value recursively + */ + function defaultVisitor(value, key, path) { + let arr = value; + + if (value && !path && typeof value === 'object') { + if (utils$1.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + key = metaTokens ? key : key.slice(0, -2); + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if ( + (utils$1.isArray(value) && isFlatArray(value)) || + ((utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value)) + )) { + // eslint-disable-next-line no-param-reassign + key = removeBrackets(key); + + arr.forEach(function each(el, index) { + !(utils$1.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'), + convertValue(el) + ); + }); + return false; + } + } + + if (isVisitable(value)) { + return true; + } + + formData.append(renderKey(path, key, dots), convertValue(value)); + + return false; + } + + const stack = []; + + const exposedHelpers = Object.assign(predicates, { + defaultVisitor, + convertValue, + isVisitable + }); + + function build(value, path) { + if (utils$1.isUndefined(value)) return; + + if (stack.indexOf(value) !== -1) { + throw Error('Circular reference detected in ' + path.join('.')); + } + + stack.push(value); + + utils$1.forEach(value, function each(el, key) { + const result = !(utils$1.isUndefined(el) || el === null) && visitor.call( + formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers + ); + + if (result === true) { + build(el, path ? path.concat(key) : [key]); + } + }); + + stack.pop(); + } + + if (!utils$1.isObject(obj)) { + throw new TypeError('data must be an object'); + } + + build(obj); + + return formData; +} + +/** + * It encodes a string by replacing all characters that are not in the unreserved set with + * their percent-encoded equivalents + * + * @param {string} str - The string to encode. + * + * @returns {string} The encoded string. + */ +function encode$1(str) { + const charMap = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); +} + +/** + * It takes a params object and converts it to a FormData object + * + * @param {Object} params - The parameters to be converted to a FormData object. + * @param {Object} options - The options object passed to the Axios constructor. + * + * @returns {void} + */ +function AxiosURLSearchParams(params, options) { + this._pairs = []; + + params && toFormData$1(params, this, options); +} + +const prototype = AxiosURLSearchParams.prototype; + +prototype.append = function append(name, value) { + this._pairs.push([name, value]); +}; + +prototype.toString = function toString(encoder) { + const _encode = encoder ? function(value) { + return encoder.call(this, value, encode$1); + } : encode$1; + + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + '=' + _encode(pair[1]); + }, '').join('&'); +}; + +/** + * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their + * URI encoded counterparts + * + * @param {string} val The value to be encoded. + * + * @returns {string} The encoded value. + */ +function encode(val) { + return encodeURIComponent(val). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'); +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @param {?(object|Function)} options + * + * @returns {string} The formatted url + */ +function buildURL(url, params, options) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + + const _encode = options && options.encode || encode; + + if (utils$1.isFunction(options)) { + options = { + serialize: options + }; + } + + const serializeFn = options && options.serialize; + + let serializedParams; + + if (serializeFn) { + serializedParams = serializeFn(params, options); + } else { + serializedParams = utils$1.isURLSearchParams(params) ? + params.toString() : + new AxiosURLSearchParams(params, options).toString(_encode); + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf("#"); + + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + + return url; +} + +class InterceptorManager { + constructor() { + this.handlers = []; + } + + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ + use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled, + rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise + */ + eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + clear() { + if (this.handlers) { + this.handlers = []; + } + } + + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + forEach(fn) { + utils$1.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } +} + +const InterceptorManager$1 = InterceptorManager; + +const transitionalDefaults = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false +}; + +const URLSearchParams$1 = typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams; + +const FormData$1 = typeof FormData !== 'undefined' ? FormData : null; + +const Blob$1 = typeof Blob !== 'undefined' ? Blob : null; + +const platform$1 = { + isBrowser: true, + classes: { + URLSearchParams: URLSearchParams$1, + FormData: FormData$1, + Blob: Blob$1 + }, + protocols: ['http', 'https', 'file', 'blob', 'url', 'data'] +}; + +const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; + +const _navigator = typeof navigator === 'object' && navigator || undefined; + +/** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + * + * @returns {boolean} + */ +const hasStandardBrowserEnv = hasBrowserEnv && + (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); + +/** + * Determine if we're running in a standard browser webWorker environment + * + * Although the `isStandardBrowserEnv` method indicates that + * `allows axios to run in a web worker`, the WebWorker will still be + * filtered out due to its judgment standard + * `typeof window !== 'undefined' && typeof document !== 'undefined'`. + * This leads to a problem when axios post `FormData` in webWorker + */ +const hasStandardBrowserWebWorkerEnv = (() => { + return ( + typeof WorkerGlobalScope !== 'undefined' && + // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && + typeof self.importScripts === 'function' + ); +})(); + +const origin = hasBrowserEnv && window.location.href || 'http://localhost'; + +const utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + hasBrowserEnv: hasBrowserEnv, + hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv, + hasStandardBrowserEnv: hasStandardBrowserEnv, + navigator: _navigator, + origin: origin +}); + +const platform = { + ...utils, + ...platform$1 +}; + +function toURLEncodedForm(data, options) { + return toFormData$1(data, new platform.classes.URLSearchParams(), { + visitor: function(value, key, path, helpers) { + if (platform.isNode && utils$1.isBuffer(value)) { + this.append(key, value.toString('base64')); + return false; + } + + return helpers.defaultVisitor.apply(this, arguments); + }, + ...options + }); +} + +/** + * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] + * + * @param {string} name - The name of the property to get. + * + * @returns An array of strings. + */ +function parsePropPath(name) { + // foo[x][y][z] + // foo.x.y.z + // foo-x-y-z + // foo x y z + return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(match => { + return match[0] === '[]' ? '' : match[1] || match[0]; + }); +} + +/** + * Convert an array to an object. + * + * @param {Array} arr - The array to convert to an object. + * + * @returns An object with the same keys and values as the array. + */ +function arrayToObject(arr) { + const obj = {}; + const keys = Object.keys(arr); + let i; + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; +} + +/** + * It takes a FormData object and returns a JavaScript object + * + * @param {string} formData The FormData object to convert to JSON. + * + * @returns {Object | null} The converted object. + */ +function formDataToJSON(formData) { + function buildPath(path, value, target, index) { + let name = path[index++]; + + if (name === '__proto__') return true; + + const isNumericKey = Number.isFinite(+name); + const isLast = index >= path.length; + name = !name && utils$1.isArray(target) ? target.length : name; + + if (isLast) { + if (utils$1.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + + return !isNumericKey; + } + + if (!target[name] || !utils$1.isObject(target[name])) { + target[name] = []; + } + + const result = buildPath(path, value, target[name], index); + + if (result && utils$1.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + + return !isNumericKey; + } + + if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) { + const obj = {}; + + utils$1.forEachEntry(formData, (name, value) => { + buildPath(parsePropPath(name), value, obj, 0); + }); + + return obj; + } + + return null; +} + +/** + * It takes a string, tries to parse it, and if it fails, it returns the stringified version + * of the input + * + * @param {any} rawValue - The value to be stringified. + * @param {Function} parser - A function that parses a string into a JavaScript object. + * @param {Function} encoder - A function that takes a value and returns a string. + * + * @returns {string} A stringified version of the rawValue. + */ +function stringifySafely(rawValue, parser, encoder) { + if (utils$1.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils$1.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + + return (encoder || JSON.stringify)(rawValue); +} + +const defaults = { + + transitional: transitionalDefaults, + + adapter: ['xhr', 'http', 'fetch'], + + transformRequest: [function transformRequest(data, headers) { + const contentType = headers.getContentType() || ''; + const hasJSONContentType = contentType.indexOf('application/json') > -1; + const isObjectPayload = utils$1.isObject(data); + + if (isObjectPayload && utils$1.isHTMLForm(data)) { + data = new FormData(data); + } + + const isFormData = utils$1.isFormData(data); + + if (isFormData) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + + if (utils$1.isArrayBuffer(data) || + utils$1.isBuffer(data) || + utils$1.isStream(data) || + utils$1.isFile(data) || + utils$1.isBlob(data) || + utils$1.isReadableStream(data) + ) { + return data; + } + if (utils$1.isArrayBufferView(data)) { + return data.buffer; + } + if (utils$1.isURLSearchParams(data)) { + headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); + return data.toString(); + } + + let isFileList; + + if (isObjectPayload) { + if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + + if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) { + const _FormData = this.env && this.env.FormData; + + return toFormData$1( + isFileList ? {'files[]': data} : data, + _FormData && new _FormData(), + this.formSerializer + ); + } + } + + if (isObjectPayload || hasJSONContentType ) { + headers.setContentType('application/json', false); + return stringifySafely(data); + } + + return data; + }], + + transformResponse: [function transformResponse(data) { + const transitional = this.transitional || defaults.transitional; + const forcedJSONParsing = transitional && transitional.forcedJSONParsing; + const JSONRequested = this.responseType === 'json'; + + if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) { + return data; + } + + if (data && utils$1.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { + const silentJSONParsing = transitional && transitional.silentJSONParsing; + const strictJSONParsing = !silentJSONParsing && JSONRequested; + + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError$1.from(e, AxiosError$1.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + + return data; + }], + + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + maxContentLength: -1, + maxBodyLength: -1, + + env: { + FormData: platform.classes.FormData, + Blob: platform.classes.Blob + }, + + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': undefined + } + } +}; + +utils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => { + defaults.headers[method] = {}; +}); + +const defaults$1 = defaults; + +// RawAxiosHeaders whose duplicates are ignored by node +// c.f. https://nodejs.org/api/http.html#http_message_headers +const ignoreDuplicateOf = utils$1.toObjectSet([ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' +]); + +/** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} rawHeaders Headers needing to be parsed + * + * @returns {Object} Headers parsed into an object + */ +const parseHeaders = rawHeaders => { + const parsed = {}; + let key; + let val; + let i; + + rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { + i = line.indexOf(':'); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + + if (!key || (parsed[key] && ignoreDuplicateOf[key])) { + return; + } + + if (key === 'set-cookie') { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + }); + + return parsed; +}; + +const $internals = Symbol('internals'); + +function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); +} + +function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + + return utils$1.isArray(value) ? value.map(normalizeValue) : String(value); +} + +function parseTokens(str) { + const tokens = Object.create(null); + const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + let match; + + while ((match = tokensRE.exec(str))) { + tokens[match[1]] = match[2]; + } + + return tokens; +} + +const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + +function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils$1.isFunction(filter)) { + return filter.call(this, value, header); + } + + if (isHeaderNameFilter) { + value = header; + } + + if (!utils$1.isString(value)) return; + + if (utils$1.isString(filter)) { + return value.indexOf(filter) !== -1; + } + + if (utils$1.isRegExp(filter)) { + return filter.test(value); + } +} + +function formatHeader(header) { + return header.trim() + .toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { + return char.toUpperCase() + str; + }); +} + +function buildAccessors(obj, header) { + const accessorName = utils$1.toCamelCase(' ' + header); + + ['get', 'set', 'has'].forEach(methodName => { + Object.defineProperty(obj, methodName + accessorName, { + value: function(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); +} + +class AxiosHeaders$1 { + constructor(headers) { + headers && this.set(headers); + } + + set(header, valueOrRewrite, rewrite) { + const self = this; + + function setHeader(_value, _header, _rewrite) { + const lHeader = normalizeHeader(_header); + + if (!lHeader) { + throw new Error('header name must be a non-empty string'); + } + + const key = utils$1.findKey(self, lHeader); + + if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) { + self[key || _header] = normalizeValue(_value); + } + } + + const setHeaders = (headers, _rewrite) => + utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); + + if (utils$1.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite); + } else if(utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils$1.isObject(header) && utils$1.isIterable(header)) { + let obj = {}, dest, key; + for (const entry of header) { + if (!utils$1.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + + obj[key = entry[0]] = (dest = obj[key]) ? + (utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1]; + } + + setHeaders(obj, valueOrRewrite); + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + + return this; + } + + get(header, parser) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + if (key) { + const value = this[key]; + + if (!parser) { + return value; + } + + if (parser === true) { + return parseTokens(value); + } + + if (utils$1.isFunction(parser)) { + return parser.call(this, value, key); + } + + if (utils$1.isRegExp(parser)) { + return parser.exec(value); + } + + throw new TypeError('parser must be boolean|regexp|function'); + } + } + } + + has(header, matcher) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + + return false; + } + + delete(header, matcher) { + const self = this; + let deleted = false; + + function deleteHeader(_header) { + _header = normalizeHeader(_header); + + if (_header) { + const key = utils$1.findKey(self, _header); + + if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { + delete self[key]; + + deleted = true; + } + } + } + + if (utils$1.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + + return deleted; + } + + clear(matcher) { + const keys = Object.keys(this); + let i = keys.length; + let deleted = false; + + while (i--) { + const key = keys[i]; + if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + + return deleted; + } + + normalize(format) { + const self = this; + const headers = {}; + + utils$1.forEach(this, (value, header) => { + const key = utils$1.findKey(headers, header); + + if (key) { + self[key] = normalizeValue(value); + delete self[header]; + return; + } + + const normalized = format ? formatHeader(header) : String(header).trim(); + + if (normalized !== header) { + delete self[header]; + } + + self[normalized] = normalizeValue(value); + + headers[normalized] = true; + }); + + return this; + } + + concat(...targets) { + return this.constructor.concat(this, ...targets); + } + + toJSON(asStrings) { + const obj = Object.create(null); + + utils$1.forEach(this, (value, header) => { + value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(', ') : value); + }); + + return obj; + } + + [Symbol.iterator]() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + + toString() { + return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n'); + } + + getSetCookie() { + return this.get("set-cookie") || []; + } + + get [Symbol.toStringTag]() { + return 'AxiosHeaders'; + } + + static from(thing) { + return thing instanceof this ? thing : new this(thing); + } + + static concat(first, ...targets) { + const computed = new this(first); + + targets.forEach((target) => computed.set(target)); + + return computed; + } + + static accessor(header) { + const internals = this[$internals] = (this[$internals] = { + accessors: {} + }); + + const accessors = internals.accessors; + const prototype = this.prototype; + + function defineAccessor(_header) { + const lHeader = normalizeHeader(_header); + + if (!accessors[lHeader]) { + buildAccessors(prototype, _header); + accessors[lHeader] = true; + } + } + + utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + + return this; + } +} + +AxiosHeaders$1.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); + +// reserved names hotfix +utils$1.reduceDescriptors(AxiosHeaders$1.prototype, ({value}, key) => { + let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` + return { + get: () => value, + set(headerValue) { + this[mapped] = headerValue; + } + } +}); + +utils$1.freezeMethods(AxiosHeaders$1); + +const AxiosHeaders$2 = AxiosHeaders$1; + +/** + * Transform the data for a request or a response + * + * @param {Array|Function} fns A single function or Array of functions + * @param {?Object} response The response object + * + * @returns {*} The resulting transformed data + */ +function transformData(fns, response) { + const config = this || defaults$1; + const context = response || config; + const headers = AxiosHeaders$2.from(context.headers); + let data = context.data; + + utils$1.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); + }); + + headers.normalize(); + + return data; +} + +function isCancel$1(value) { + return !!(value && value.__CANCEL__); +} + +/** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ +function CanceledError$1(message, config, request) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError$1.call(this, message == null ? 'canceled' : message, AxiosError$1.ERR_CANCELED, config, request); + this.name = 'CanceledError'; +} + +utils$1.inherits(CanceledError$1, AxiosError$1, { + __CANCEL__: true +}); + +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + * + * @returns {object} The response. + */ +function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError$1( + 'Request failed with status code ' + response.status, + [AxiosError$1.ERR_BAD_REQUEST, AxiosError$1.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], + response.config, + response.request, + response + )); + } +} + +function parseProtocol(url) { + const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; +} + +/** + * Calculate data maxRate + * @param {Number} [samplesCount= 10] + * @param {Number} [min= 1000] + * @returns {Function} + */ +function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + const bytes = new Array(samplesCount); + const timestamps = new Array(samplesCount); + let head = 0; + let tail = 0; + let firstSampleTS; + + min = min !== undefined ? min : 1000; + + return function push(chunkLength) { + const now = Date.now(); + + const startedAt = timestamps[tail]; + + if (!firstSampleTS) { + firstSampleTS = now; + } + + bytes[head] = chunkLength; + timestamps[head] = now; + + let i = tail; + let bytesCount = 0; + + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + + head = (head + 1) % samplesCount; + + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + + if (now - firstSampleTS < min) { + return; + } + + const passed = startedAt && now - startedAt; + + return passed ? Math.round(bytesCount * 1000 / passed) : undefined; + }; +} + +/** + * Throttle decorator + * @param {Function} fn + * @param {Number} freq + * @return {Function} + */ +function throttle(fn, freq) { + let timestamp = 0; + let threshold = 1000 / freq; + let lastArgs; + let timer; + + const invoke = (args, now = Date.now()) => { + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn(...args); + }; + + const throttled = (...args) => { + const now = Date.now(); + const passed = now - timestamp; + if ( passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(() => { + timer = null; + invoke(lastArgs); + }, threshold - passed); + } + } + }; + + const flush = () => lastArgs && invoke(lastArgs); + + return [throttled, flush]; +} + +const progressEventReducer = (listener, isDownloadStream, freq = 3) => { + let bytesNotified = 0; + const _speedometer = speedometer(50, 250); + + return throttle(e => { + const loaded = e.loaded; + const total = e.lengthComputable ? e.total : undefined; + const progressBytes = loaded - bytesNotified; + const rate = _speedometer(progressBytes); + const inRange = loaded <= total; + + bytesNotified = loaded; + + const data = { + loaded, + total, + progress: total ? (loaded / total) : undefined, + bytes: progressBytes, + rate: rate ? rate : undefined, + estimated: rate && total && inRange ? (total - loaded) / rate : undefined, + event: e, + lengthComputable: total != null, + [isDownloadStream ? 'download' : 'upload']: true + }; + + listener(data); + }, freq); +}; + +const progressEventDecorator = (total, throttled) => { + const lengthComputable = total != null; + + return [(loaded) => throttled[0]({ + lengthComputable, + total, + loaded + }), throttled[1]]; +}; + +const asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args)); + +const isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => { + url = new URL(url, platform.origin); + + return ( + origin.protocol === url.protocol && + origin.host === url.host && + (isMSIE || origin.port === url.port) + ); +})( + new URL(platform.origin), + platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent) +) : () => true; + +const cookies = platform.hasStandardBrowserEnv ? + + // Standard browser envs support document.cookie + { + write(name, value, expires, path, domain, secure) { + const cookie = [name + '=' + encodeURIComponent(value)]; + + utils$1.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString()); + + utils$1.isString(path) && cookie.push('path=' + path); + + utils$1.isString(domain) && cookie.push('domain=' + domain); + + secure === true && cookie.push('secure'); + + document.cookie = cookie.join('; '); + }, + + read(name) { + const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return (match ? decodeURIComponent(match[3]) : null); + }, + + remove(name) { + this.write(name, '', Date.now() - 86400000); + } + } + + : + + // Non-standard browser env (web workers, react-native) lack needed support. + { + write() {}, + read() { + return null; + }, + remove() {} + }; + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); +} + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * + * @returns {string} The combined URL + */ +function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; +} + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * + * @returns {string} The combined full path + */ +function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + let isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; +} + +const headersToObject = (thing) => thing instanceof AxiosHeaders$2 ? { ...thing } : thing; + +/** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * + * @returns {Object} New object resulting from merging config2 to config1 + */ +function mergeConfig$1(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + const config = {}; + + function getMergedValue(target, source, prop, caseless) { + if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) { + return utils$1.merge.call({caseless}, target, source); + } else if (utils$1.isPlainObject(source)) { + return utils$1.merge({}, source); + } else if (utils$1.isArray(source)) { + return source.slice(); + } + return source; + } + + // eslint-disable-next-line consistent-return + function mergeDeepProperties(a, b, prop , caseless) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(a, b, prop , caseless); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a, prop , caseless); + } + } + + // eslint-disable-next-line consistent-return + function valueFromConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } + } + + // eslint-disable-next-line consistent-return + function defaultToConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a); + } + } + + // eslint-disable-next-line consistent-return + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(undefined, a); + } + } + + const mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true) + }; + + utils$1.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) { + const merge = mergeMap[prop] || mergeDeepProperties; + const configValue = merge(config1[prop], config2[prop], prop); + (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); + }); + + return config; +} + +const resolveConfig = (config) => { + const newConfig = mergeConfig$1({}, config); + + let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig; + + newConfig.headers = headers = AxiosHeaders$2.from(headers); + + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + + // HTTP basic authentication + if (auth) { + headers.set('Authorization', 'Basic ' + + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : '')) + ); + } + + if (utils$1.isFormData(data)) { + if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(undefined); // browser handles it + } else if (utils$1.isFunction(data.getHeaders)) { + // Node.js FormData (like form-data package) + const formHeaders = data.getHeaders(); + // Only set safe headers to avoid overwriting security headers + const allowedHeaders = ['content-type', 'content-length']; + Object.entries(formHeaders).forEach(([key, val]) => { + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + + if (platform.hasStandardBrowserEnv) { + withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + + if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { + // Add xsrf header + const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + + return newConfig; +}; + +const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; + +const xhrAdapter = isXHRAdapterSupported && function (config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + const _config = resolveConfig(config); + let requestData = _config.data; + const requestHeaders = AxiosHeaders$2.from(_config.headers).normalize(); + let {responseType, onUploadProgress, onDownloadProgress} = _config; + let onCanceled; + let uploadThrottled, downloadThrottled; + let flushUpload, flushDownload; + + function done() { + flushUpload && flushUpload(); // flush events + flushDownload && flushDownload(); // flush events + + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + + _config.signal && _config.signal.removeEventListener('abort', onCanceled); + } + + let request = new XMLHttpRequest(); + + request.open(_config.method.toUpperCase(), _config.url, true); + + // Set the request timeout in MS + request.timeout = _config.timeout; + + function onloadend() { + if (!request) { + return; + } + // Prepare the response + const responseHeaders = AxiosHeaders$2.from( + 'getAllResponseHeaders' in request && request.getAllResponseHeaders() + ); + const responseData = !responseType || responseType === 'text' || responseType === 'json' ? + request.responseText : request.response; + const response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config, + request + }; + + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + + // Clean up request + request = null; + } + + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(new AxiosError$1('Request aborted', AxiosError$1.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError(event) { + // Browsers deliver a ProgressEvent in XHR onerror + // (message may be empty; when present, surface it) + // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event + const msg = event && event.message ? event.message : 'Network Error'; + const err = new AxiosError$1(msg, AxiosError$1.ERR_NETWORK, config, request); + // attach the underlying event for consumers who want details + err.event = event || null; + reject(err); + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError$1( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError$1.ETIMEDOUT : AxiosError$1.ECONNABORTED, + config, + request)); + + // Clean up request + request = null; + }; + + // Remove Content-Type if data is undefined + requestData === undefined && requestHeaders.setContentType(null); + + // Add headers to the request + if ('setRequestHeader' in request) { + utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + + // Add withCredentials to request if needed + if (!utils$1.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + + // Add responseType to request if needed + if (responseType && responseType !== 'json') { + request.responseType = _config.responseType; + } + + // Handle progress if needed + if (onDownloadProgress) { + ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true)); + request.addEventListener('progress', downloadThrottled); + } + + // Not all browsers support upload events + if (onUploadProgress && request.upload) { + ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress)); + + request.upload.addEventListener('progress', uploadThrottled); + + request.upload.addEventListener('loadend', flushUpload); + } + + if (_config.cancelToken || _config.signal) { + // Handle cancellation + // eslint-disable-next-line func-names + onCanceled = cancel => { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError$1(null, config, request) : cancel); + request.abort(); + request = null; + }; + + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); + } + } + + const protocol = parseProtocol(_config.url); + + if (protocol && platform.protocols.indexOf(protocol) === -1) { + reject(new AxiosError$1('Unsupported protocol ' + protocol + ':', AxiosError$1.ERR_BAD_REQUEST, config)); + return; + } + + + // Send the request + request.send(requestData || null); + }); +}; + +const composeSignals = (signals, timeout) => { + const {length} = (signals = signals ? signals.filter(Boolean) : []); + + if (timeout || length) { + let controller = new AbortController(); + + let aborted; + + const onabort = function (reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + const err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError$1 ? err : new CanceledError$1(err instanceof Error ? err.message : err)); + } + }; + + let timer = timeout && setTimeout(() => { + timer = null; + onabort(new AxiosError$1(`timeout ${timeout} of ms exceeded`, AxiosError$1.ETIMEDOUT)); + }, timeout); + + const unsubscribe = () => { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach(signal => { + signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); + }); + signals = null; + } + }; + + signals.forEach((signal) => signal.addEventListener('abort', onabort)); + + const {signal} = controller; + + signal.unsubscribe = () => utils$1.asap(unsubscribe); + + return signal; + } +}; + +const composeSignals$1 = composeSignals; + +const streamChunk = function* (chunk, chunkSize) { + let len = chunk.byteLength; + + if (!chunkSize || len < chunkSize) { + yield chunk; + return; + } + + let pos = 0; + let end; + + while (pos < len) { + end = pos + chunkSize; + yield chunk.slice(pos, end); + pos = end; + } +}; + +const readBytes = async function* (iterable, chunkSize) { + for await (const chunk of readStream(iterable)) { + yield* streamChunk(chunk, chunkSize); + } +}; + +const readStream = async function* (stream) { + if (stream[Symbol.asyncIterator]) { + yield* stream; + return; + } + + const reader = stream.getReader(); + try { + for (;;) { + const {done, value} = await reader.read(); + if (done) { + break; + } + yield value; + } + } finally { + await reader.cancel(); + } +}; + +const trackStream = (stream, chunkSize, onProgress, onFinish) => { + const iterator = readBytes(stream, chunkSize); + + let bytes = 0; + let done; + let _onFinish = (e) => { + if (!done) { + done = true; + onFinish && onFinish(e); + } + }; + + return new ReadableStream({ + async pull(controller) { + try { + const {done, value} = await iterator.next(); + + if (done) { + _onFinish(); + controller.close(); + return; + } + + let len = value.byteLength; + if (onProgress) { + let loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + } catch (err) { + _onFinish(err); + throw err; + } + }, + cancel(reason) { + _onFinish(reason); + return iterator.return(); + } + }, { + highWaterMark: 2 + }) +}; + +const DEFAULT_CHUNK_SIZE = 64 * 1024; + +const {isFunction} = utils$1; + +const globalFetchAPI = (({Request, Response}) => ({ + Request, Response +}))(utils$1.global); + +const { + ReadableStream: ReadableStream$1, TextEncoder +} = utils$1.global; + + +const test = (fn, ...args) => { + try { + return !!fn(...args); + } catch (e) { + return false + } +}; + +const factory = (env) => { + env = utils$1.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + + const {fetch: envFetch, Request, Response} = env; + const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; + const isRequestSupported = isFunction(Request); + const isResponseSupported = isFunction(Response); + + if (!isFetchSupported) { + return false; + } + + const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1); + + const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ? + ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) : + async (str) => new Uint8Array(await new Request(str).arrayBuffer()) + ); + + const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { + let duplexAccessed = false; + + const hasContentType = new Request(platform.origin, { + body: new ReadableStream$1(), + method: 'POST', + get duplex() { + duplexAccessed = true; + return 'half'; + }, + }).headers.has('Content-Type'); + + return duplexAccessed && !hasContentType; + }); + + const supportsResponseStream = isResponseSupported && isReadableStreamSupported && + test(() => utils$1.isReadableStream(new Response('').body)); + + const resolvers = { + stream: supportsResponseStream && ((res) => res.body) + }; + + isFetchSupported && ((() => { + ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => { + !resolvers[type] && (resolvers[type] = (res, config) => { + let method = res && res[type]; + + if (method) { + return method.call(res); + } + + throw new AxiosError$1(`Response type '${type}' is not supported`, AxiosError$1.ERR_NOT_SUPPORT, config); + }); + }); + })()); + + const getBodyLength = async (body) => { + if (body == null) { + return 0; + } + + if (utils$1.isBlob(body)) { + return body.size; + } + + if (utils$1.isSpecCompliantForm(body)) { + const _request = new Request(platform.origin, { + method: 'POST', + body, + }); + return (await _request.arrayBuffer()).byteLength; + } + + if (utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body)) { + return body.byteLength; + } + + if (utils$1.isURLSearchParams(body)) { + body = body + ''; + } + + if (utils$1.isString(body)) { + return (await encodeText(body)).byteLength; + } + }; + + const resolveBodyLength = async (headers, body) => { + const length = utils$1.toFiniteNumber(headers.getContentLength()); + + return length == null ? getBodyLength(body) : length; + }; + + return async (config) => { + let { + url, + method, + data, + signal, + cancelToken, + timeout, + onDownloadProgress, + onUploadProgress, + responseType, + headers, + withCredentials = 'same-origin', + fetchOptions + } = resolveConfig(config); + + let _fetch = envFetch || fetch; + + responseType = responseType ? (responseType + '').toLowerCase() : 'text'; + + let composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + + let request = null; + + const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { + composedSignal.unsubscribe(); + }); + + let requestContentLength; + + try { + if ( + onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && + (requestContentLength = await resolveBodyLength(headers, data)) !== 0 + ) { + let _request = new Request(url, { + method: 'POST', + body: data, + duplex: "half" + }); + + let contentTypeHeader; + + if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { + headers.setContentType(contentTypeHeader); + } + + if (_request.body) { + const [onProgress, flush] = progressEventDecorator( + requestContentLength, + progressEventReducer(asyncDecorator(onUploadProgress)) + ); + + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + } + + if (!utils$1.isString(withCredentials)) { + withCredentials = withCredentials ? 'include' : 'omit'; + } + + // Cloudflare Workers throws when credentials are defined + // see https://github.com/cloudflare/workerd/issues/902 + const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + + const resolvedOptions = { + ...fetchOptions, + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : undefined + }; + + request = isRequestSupported && new Request(url, resolvedOptions); + + let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions)); + + const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); + + if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) { + const options = {}; + + ['status', 'statusText', 'headers'].forEach(prop => { + options[prop] = response[prop]; + }); + + const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length')); + + const [onProgress, flush] = onDownloadProgress && progressEventDecorator( + responseContentLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true) + ) || []; + + response = new Response( + trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => { + flush && flush(); + unsubscribe && unsubscribe(); + }), + options + ); + } + + responseType = responseType || 'text'; + + let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config); + + !isStreamResponse && unsubscribe && unsubscribe(); + + return await new Promise((resolve, reject) => { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders$2.from(response.headers), + status: response.status, + statusText: response.statusText, + config, + request + }); + }) + } catch (err) { + unsubscribe && unsubscribe(); + + if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) { + throw Object.assign( + new AxiosError$1('Network Error', AxiosError$1.ERR_NETWORK, config, request), + { + cause: err.cause || err + } + ) + } + + throw AxiosError$1.from(err, err && err.code, config, request); + } + } +}; + +const seedCache = new Map(); + +const getFetch = (config) => { + let env = config ? config.env : {}; + const {fetch, Request, Response} = env; + const seeds = [ + Request, Response, fetch + ]; + + let len = seeds.length, i = len, + seed, target, map = seedCache; + + while (i--) { + seed = seeds[i]; + target = map.get(seed); + + target === undefined && map.set(seed, target = (i ? new Map() : factory(env))); + + map = target; + } + + return target; +}; + +getFetch(); + +const knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: getFetch, + } +}; + +utils$1.forEach(knownAdapters, (fn, value) => { + if (fn) { + try { + Object.defineProperty(fn, 'name', {value}); + } catch (e) { + // eslint-disable-next-line no-empty + } + Object.defineProperty(fn, 'adapterName', {value}); + } +}); + +const renderReason = (reason) => `- ${reason}`; + +const isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false; + +const adapters = { + getAdapter: (adapters, config) => { + adapters = utils$1.isArray(adapters) ? adapters : [adapters]; + + const {length} = adapters; + let nameOrAdapter; + let adapter; + + const rejectedReasons = {}; + + for (let i = 0; i < length; i++) { + nameOrAdapter = adapters[i]; + let id; + + adapter = nameOrAdapter; + + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + + if (adapter === undefined) { + throw new AxiosError$1(`Unknown adapter '${id}'`); + } + } + + if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + + rejectedReasons[id || '#' + i] = adapter; + } + + if (!adapter) { + + const reasons = Object.entries(rejectedReasons) + .map(([id, state]) => `adapter ${id} ` + + (state === false ? 'is not supported by the environment' : 'is not available in the build') + ); + + let s = length ? + (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) : + 'as no adapter specified'; + + throw new AxiosError$1( + `There is no suitable adapter to dispatch the request ` + s, + 'ERR_NOT_SUPPORT' + ); + } + + return adapter; + }, + adapters: knownAdapters +}; + +/** + * Throws a `CanceledError` if cancellation has been requested. + * + * @param {Object} config The config that is to be used for the request + * + * @returns {void} + */ +function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + + if (config.signal && config.signal.aborted) { + throw new CanceledError$1(null, config); + } +} + +/** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * + * @returns {Promise} The Promise to be fulfilled + */ +function dispatchRequest(config) { + throwIfCancellationRequested(config); + + config.headers = AxiosHeaders$2.from(config.headers); + + // Transform request data + config.data = transformData.call( + config, + config.transformRequest + ); + + if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { + config.headers.setContentType('application/x-www-form-urlencoded', false); + } + + const adapter = adapters.getAdapter(config.adapter || defaults$1.adapter, config); + + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData.call( + config, + config.transformResponse, + response + ); + + response.headers = AxiosHeaders$2.from(response.headers); + + return response; + }, function onAdapterRejection(reason) { + if (!isCancel$1(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData.call( + config, + config.transformResponse, + reason.response + ); + reason.response.headers = AxiosHeaders$2.from(reason.response.headers); + } + } + + return Promise.reject(reason); + }); +} + +const VERSION$1 = "1.12.2"; + +const validators$1 = {}; + +// eslint-disable-next-line func-names +['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => { + validators$1[type] = function validator(thing) { + return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; +}); + +const deprecatedWarnings = {}; + +/** + * Transitional option validator + * + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * + * @returns {function} + */ +validators$1.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION$1 + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return (value, opt, opts) => { + if (validator === false) { + throw new AxiosError$1( + formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), + AxiosError$1.ERR_DEPRECATED + ); + } + + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn( + formatMessage( + opt, + ' has been deprecated since v' + version + ' and will be removed in the near future' + ) + ); + } + + return validator ? validator(value, opt, opts) : true; + }; +}; + +validators$1.spelling = function spelling(correctSpelling) { + return (value, opt) => { + // eslint-disable-next-line no-console + console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); + return true; + } +}; + +/** + * Assert object's properties type + * + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + * + * @returns {object} + */ + +function assertOptions(options, schema, allowUnknown) { + if (typeof options !== 'object') { + throw new AxiosError$1('options must be an object', AxiosError$1.ERR_BAD_OPTION_VALUE); + } + const keys = Object.keys(options); + let i = keys.length; + while (i-- > 0) { + const opt = keys[i]; + const validator = schema[opt]; + if (validator) { + const value = options[opt]; + const result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError$1('option ' + opt + ' must be ' + result, AxiosError$1.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError$1('Unknown option ' + opt, AxiosError$1.ERR_BAD_OPTION); + } + } +} + +const validator = { + assertOptions, + validators: validators$1 +}; + +const validators = validator.validators; + +/** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + * + * @return {Axios} A new instance of Axios + */ +class Axios$1 { + constructor(instanceConfig) { + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager$1(), + response: new InterceptorManager$1() + }; + } + + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + async request(configOrUrl, config) { + try { + return await this._request(configOrUrl, config); + } catch (err) { + if (err instanceof Error) { + let dummy = {}; + + Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error()); + + // slice off the Error: ... line + const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : ''; + try { + if (!err.stack) { + err.stack = stack; + // match without the 2 top stack lines + } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\n.+\n/, ''))) { + err.stack += '\n' + stack; + } + } catch (e) { + // ignore the case where "stack" is an un-writable property + } + } + + throw err; + } + } + + _request(configOrUrl, config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof configOrUrl === 'string') { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + + config = mergeConfig$1(this.defaults, config); + + const {transitional, paramsSerializer, headers} = config; + + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean) + }, false); + } + + if (paramsSerializer != null) { + if (utils$1.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + }; + } else { + validator.assertOptions(paramsSerializer, { + encode: validators.function, + serialize: validators.function + }, true); + } + } + + // Set config.allowAbsoluteUrls + if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + + validator.assertOptions(config, { + baseUrl: validators.spelling('baseURL'), + withXsrfToken: validators.spelling('withXSRFToken') + }, true); + + // Set config.method + config.method = (config.method || this.defaults.method || 'get').toLowerCase(); + + // Flatten headers + let contextHeaders = headers && utils$1.merge( + headers.common, + headers[config.method] + ); + + headers && utils$1.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + (method) => { + delete headers[method]; + } + ); + + config.headers = AxiosHeaders$2.concat(contextHeaders, headers); + + // filter out skipped interceptors + const requestInterceptorChain = []; + let synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + + const responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + + let promise; + let i = 0; + let len; + + if (!synchronousRequestInterceptors) { + const chain = [dispatchRequest.bind(this), undefined]; + chain.unshift(...requestInterceptorChain); + chain.push(...responseInterceptorChain); + len = chain.length; + + promise = Promise.resolve(config); + + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + + return promise; + } + + len = requestInterceptorChain.length; + + let newConfig = config; + + while (i < len) { + const onFulfilled = requestInterceptorChain[i++]; + const onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + + i = 0; + len = responseInterceptorChain.length; + + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + + return promise; + } + + getUri(config) { + config = mergeConfig$1(this.defaults, config); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } +} + +// Provide aliases for supported request methods +utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios$1.prototype[method] = function(url, config) { + return this.request(mergeConfig$1(config || {}, { + method, + url, + data: (config || {}).data + })); + }; +}); + +utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig$1(config || {}, { + method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url, + data + })); + }; + } + + Axios$1.prototype[method] = generateHTTPMethod(); + + Axios$1.prototype[method + 'Form'] = generateHTTPMethod(true); +}); + +const Axios$2 = Axios$1; + +/** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @param {Function} executor The executor function. + * + * @returns {CancelToken} + */ +class CancelToken$1 { + constructor(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + + let resolvePromise; + + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + + const token = this; + + // eslint-disable-next-line func-names + this.promise.then(cancel => { + if (!token._listeners) return; + + let i = token._listeners.length; + + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = onfulfilled => { + let _resolve; + // eslint-disable-next-line func-names + const promise = new Promise(resolve => { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + + return promise; + }; + + executor(function cancel(message, config, request) { + if (token.reason) { + // Cancellation has already been requested + return; + } + + token.reason = new CanceledError$1(message, config, request); + resolvePromise(token.reason); + }); + } + + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + + /** + * Subscribe to the cancel signal + */ + + subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + + /** + * Unsubscribe from the cancel signal + */ + + unsubscribe(listener) { + if (!this._listeners) { + return; + } + const index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + + toAbortSignal() { + const controller = new AbortController(); + + const abort = (err) => { + controller.abort(err); + }; + + this.subscribe(abort); + + controller.signal.unsubscribe = () => this.unsubscribe(abort); + + return controller.signal; + } + + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + static source() { + let cancel; + const token = new CancelToken$1(function executor(c) { + cancel = c; + }); + return { + token, + cancel + }; + } +} + +const CancelToken$2 = CancelToken$1; + +/** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * + * @returns {Function} + */ +function spread$1(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; +} + +/** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ +function isAxiosError$1(payload) { + return utils$1.isObject(payload) && (payload.isAxiosError === true); +} + +const HttpStatusCode$1 = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511, +}; + +Object.entries(HttpStatusCode$1).forEach(([key, value]) => { + HttpStatusCode$1[value] = key; +}); + +const HttpStatusCode$2 = HttpStatusCode$1; + +/** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * + * @returns {Axios} A new instance of Axios + */ +function createInstance(defaultConfig) { + const context = new Axios$2(defaultConfig); + const instance = bind(Axios$2.prototype.request, context); + + // Copy axios.prototype to instance + utils$1.extend(instance, Axios$2.prototype, context, {allOwnKeys: true}); + + // Copy context to instance + utils$1.extend(instance, context, null, {allOwnKeys: true}); + + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig$1(defaultConfig, instanceConfig)); + }; + + return instance; +} + +// Create the default instance to be exported +const axios = createInstance(defaults$1); + +// Expose Axios class to allow class inheritance +axios.Axios = Axios$2; + +// Expose Cancel & CancelToken +axios.CanceledError = CanceledError$1; +axios.CancelToken = CancelToken$2; +axios.isCancel = isCancel$1; +axios.VERSION = VERSION$1; +axios.toFormData = toFormData$1; + +// Expose AxiosError class +axios.AxiosError = AxiosError$1; + +// alias for CanceledError for backward compatibility +axios.Cancel = axios.CanceledError; + +// Expose all/spread +axios.all = function all(promises) { + return Promise.all(promises); +}; + +axios.spread = spread$1; + +// Expose isAxiosError +axios.isAxiosError = isAxiosError$1; + +// Expose mergeConfig +axios.mergeConfig = mergeConfig$1; + +axios.AxiosHeaders = AxiosHeaders$2; + +axios.formToJSON = thing => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing); + +axios.getAdapter = adapters.getAdapter; + +axios.HttpStatusCode = HttpStatusCode$2; + +axios.default = axios; + +// this module should only have a default export +const axios$1 = axios; + +// This module is intended to unwrap Axios default export as named. +// Keep top-level export same with static properties +// so that it can keep same with es module or cjs +const { + Axios, + AxiosError, + CanceledError, + isCancel, + CancelToken, + VERSION, + all, + Cancel, + isAxiosError, + spread, + toFormData, + AxiosHeaders, + HttpStatusCode, + formToJSON, + getAdapter, + mergeConfig +} = axios$1; + +export { Axios, AxiosError, AxiosHeaders, Cancel, CancelToken, CanceledError, HttpStatusCode, VERSION, all, axios$1 as default, formToJSON, getAdapter, isAxiosError, isCancel, mergeConfig, spread, toFormData }; +//# sourceMappingURL=axios.js.map diff --git a/node_modules/axios/dist/esm/axios.js.map b/node_modules/axios/dist/esm/axios.js.map new file mode 100644 index 0000000..81c1bb0 --- /dev/null +++ b/node_modules/axios/dist/esm/axios.js.map @@ -0,0 +1 @@ +{"version":3,"file":"axios.js","sources":["../../lib/helpers/bind.js","../../lib/utils.js","../../lib/core/AxiosError.js","../../lib/helpers/null.js","../../lib/helpers/toFormData.js","../../lib/helpers/AxiosURLSearchParams.js","../../lib/helpers/buildURL.js","../../lib/core/InterceptorManager.js","../../lib/defaults/transitional.js","../../lib/platform/browser/classes/URLSearchParams.js","../../lib/platform/browser/classes/FormData.js","../../lib/platform/browser/classes/Blob.js","../../lib/platform/browser/index.js","../../lib/platform/common/utils.js","../../lib/platform/index.js","../../lib/helpers/toURLEncodedForm.js","../../lib/helpers/formDataToJSON.js","../../lib/defaults/index.js","../../lib/helpers/parseHeaders.js","../../lib/core/AxiosHeaders.js","../../lib/core/transformData.js","../../lib/cancel/isCancel.js","../../lib/cancel/CanceledError.js","../../lib/core/settle.js","../../lib/helpers/parseProtocol.js","../../lib/helpers/speedometer.js","../../lib/helpers/throttle.js","../../lib/helpers/progressEventReducer.js","../../lib/helpers/isURLSameOrigin.js","../../lib/helpers/cookies.js","../../lib/helpers/isAbsoluteURL.js","../../lib/helpers/combineURLs.js","../../lib/core/buildFullPath.js","../../lib/core/mergeConfig.js","../../lib/helpers/resolveConfig.js","../../lib/adapters/xhr.js","../../lib/helpers/composeSignals.js","../../lib/helpers/trackStream.js","../../lib/adapters/fetch.js","../../lib/adapters/adapters.js","../../lib/core/dispatchRequest.js","../../lib/env/data.js","../../lib/helpers/validator.js","../../lib/core/Axios.js","../../lib/cancel/CancelToken.js","../../lib/helpers/spread.js","../../lib/helpers/isAxiosError.js","../../lib/helpers/HttpStatusCode.js","../../lib/axios.js","../../index.js"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n // Early return for non-objects or Buffers to prevent RangeError\n if (!isObject(val) || isBuffer(val)) {\n return false;\n }\n\n try {\n return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n } catch (e) {\n // Fallback for any other objects that might cause RangeError with Object.keys()\n return false;\n }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Buffer check\n if (isBuffer(obj)) {\n return;\n }\n\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n if (isBuffer(obj)){\n return null;\n }\n\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else if (!skipUndefined || !isUndefined(val)) {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n //Buffer check\n if (isBuffer(source)) {\n return source;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isEmptyObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n const msg = error && error.message ? error.message : 'Error';\n\n // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n const errCode = code == null && error ? error.code : code;\n AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n if (error && axiosError.cause == null) {\n Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n }\n\n axiosError.name = (error && error.name) || 'Error';\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), {\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n },\n ...options\n });\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data, this.parseReviver);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn(...args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // browser handles it\n } else if (utils.isFunction(data.getHeaders)) {\n // Node.js FormData (like form-data package)\n const formHeaders = data.getHeaders();\n // Only set safe headers to avoid overwriting security headers\n const allowedHeaders = ['content-type', 'content-length'];\n Object.entries(formHeaders).forEach(([key, val]) => {\n if (allowedHeaders.includes(key.toLowerCase())) {\n headers.set(key, val);\n }\n });\n }\n } \n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError(event) {\n // Browsers deliver a ProgressEvent in XHR onerror\n // (message may be empty; when present, surface it)\n // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n const msg = event && event.message ? event.message : 'Network Error';\n const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n // attach the underlying event for consumers who want details\n err.event = event || null;\n reject(err);\n request = null;\n };\n \n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n Request, Response\n}))(utils.global);\n\nconst {\n ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst factory = (env) => {\n env = utils.merge.call({\n skipUndefined: true\n }, globalFetchAPI, env);\n\n const {fetch: envFetch, Request, Response} = env;\n const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n const isRequestSupported = isFunction(Request);\n const isResponseSupported = isFunction(Response);\n\n if (!isFetchSupported) {\n return false;\n }\n\n const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n );\n\n const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n });\n\n const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n const resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n };\n\n isFetchSupported && ((() => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = (res, config) => {\n let method = res && res[type];\n\n if (method) {\n return method.call(res);\n }\n\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n })());\n\n const getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if (utils.isBlob(body)) {\n return body.size;\n }\n\n if (utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if (utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if (utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n }\n\n const resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n }\n\n return async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n let _fetch = envFetch || fetch;\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request = null;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n const resolvedOptions = {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n };\n\n request = isRequestSupported && new Request(url, resolvedOptions);\n\n let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n let env = config ? config.env : {};\n const {fetch, Request, Response} = env;\n const seeds = [\n Request, Response, fetch\n ];\n\n let len = seeds.length, i = len,\n seed, target, map = seedCache;\n\n while (i--) {\n seed = seeds[i];\n target = map.get(seed);\n\n target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n map = target;\n }\n\n return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: {\n get: fetchAdapter.getFetch,\n }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters, config) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift(...requestInterceptorChain);\n chain.push(...responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","import axios from './lib/axios.js';\n\n// This module is intended to unwrap Axios default export as named.\n// Keep top-level export same with static properties\n// so that it can keep same with es module or cjs\nconst {\n Axios,\n AxiosError,\n CanceledError,\n isCancel,\n CancelToken,\n VERSION,\n all,\n Cancel,\n isAxiosError,\n spread,\n toFormData,\n AxiosHeaders,\n HttpStatusCode,\n formToJSON,\n getAdapter,\n mergeConfig\n} = axios;\n\nexport {\n axios as default,\n Axios,\n AxiosError,\n CanceledError,\n isCancel,\n CancelToken,\n VERSION,\n all,\n Cancel,\n isAxiosError,\n spread,\n toFormData,\n AxiosHeaders,\n HttpStatusCode,\n formToJSON,\n getAdapter,\n mergeConfig\n}\n"],"names":["isFunction","AxiosError","utils","prototype","toFormData","encode","URLSearchParams","FormData","Blob","platform","AxiosHeaders","defaults","isCancel","CanceledError","mergeConfig","ReadableStream","composeSignals","fetchAdapter.getFetch","VERSION","validators","Axios","InterceptorManager","CancelToken","spread","isAxiosError","HttpStatusCode","axios"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/axios/dist/esm/axios.min.js b/node_modules/axios/dist/esm/axios.min.js new file mode 100644 index 0000000..1efef1d --- /dev/null +++ b/node_modules/axios/dist/esm/axios.min.js @@ -0,0 +1,3 @@ +/*! Axios v1.12.2 Copyright (c) 2025 Matt Zabriskie and contributors */ +function e(e,t){return function(){return e.apply(t,arguments)}}const{toString:t}=Object.prototype,{getPrototypeOf:n}=Object,{iterator:r,toStringTag:o}=Symbol,s=(i=Object.create(null),e=>{const n=t.call(e);return i[n]||(i[n]=n.slice(8,-1).toLowerCase())});var i;const a=e=>(e=e.toLowerCase(),t=>s(t)===e),c=e=>t=>typeof t===e,{isArray:l}=Array,u=c("undefined");function f(e){return null!==e&&!u(e)&&null!==e.constructor&&!u(e.constructor)&&p(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const d=a("ArrayBuffer");const h=c("string"),p=c("function"),m=c("number"),b=e=>null!==e&&"object"==typeof e,y=e=>{if("object"!==s(e))return!1;const t=n(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||o in e||r in e)},g=a("Date"),w=a("File"),E=a("Blob"),O=a("FileList"),R=a("URLSearchParams"),[S,T,A,v]=["ReadableStream","Request","Response","Headers"].map(a);function x(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),l(e))for(r=0,o=e.length;r0;)if(r=n[o],t===r.toLowerCase())return r;return null}const j="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:global,N=e=>!u(e)&&e!==j;const U=(P="undefined"!=typeof Uint8Array&&n(Uint8Array),e=>P&&e instanceof P);var P;const F=a("HTMLFormElement"),_=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),L=a("RegExp"),k=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};x(n,((n,o)=>{let s;!1!==(s=t(n,o,e))&&(r[o]=s||n)})),Object.defineProperties(e,r)};const B=a("AsyncFunction"),D=(q="function"==typeof setImmediate,M=p(j.postMessage),q?setImmediate:M?(I=`axios@${Math.random()}`,z=[],j.addEventListener("message",(({source:e,data:t})=>{e===j&&t===I&&z.length&&z.shift()()}),!1),e=>{z.push(e),j.postMessage(I,"*")}):e=>setTimeout(e));var q,M,I,z;const H="undefined"!=typeof queueMicrotask?queueMicrotask.bind(j):"undefined"!=typeof process&&process.nextTick||D,J={isArray:l,isArrayBuffer:d,isBuffer:f,isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||p(e.append)&&("formdata"===(t=s(e))||"object"===t&&p(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&d(e.buffer),t},isString:h,isNumber:m,isBoolean:e=>!0===e||!1===e,isObject:b,isPlainObject:y,isEmptyObject:e=>{if(!b(e)||f(e))return!1;try{return 0===Object.keys(e).length&&Object.getPrototypeOf(e)===Object.prototype}catch(e){return!1}},isReadableStream:S,isRequest:T,isResponse:A,isHeaders:v,isUndefined:u,isDate:g,isFile:w,isBlob:E,isRegExp:L,isFunction:p,isStream:e=>b(e)&&p(e.pipe),isURLSearchParams:R,isTypedArray:U,isFileList:O,forEach:x,merge:function e(){const{caseless:t,skipUndefined:n}=N(this)&&this||{},r={},o=(o,s)=>{const i=t&&C(r,s)||s;y(r[i])&&y(o)?r[i]=e(r[i],o):y(o)?r[i]=e({},o):l(o)?r[i]=o.slice():n&&u(o)||(r[i]=o)};for(let e=0,t=arguments.length;e(x(n,((n,o)=>{r&&p(n)?t[o]=e(n,r):t[o]=n}),{allOwnKeys:o}),t),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,r,o)=>{let s,i,a;const c={};if(t=t||{},null==e)return t;do{for(s=Object.getOwnPropertyNames(e),i=s.length;i-- >0;)a=s[i],o&&!o(a,e,t)||c[a]||(t[a]=e[a],c[a]=!0);e=!1!==r&&n(e)}while(e&&(!r||r(e,t))&&e!==Object.prototype);return t},kindOf:s,kindOfTest:a,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(l(e))return e;let t=e.length;if(!m(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[r]).call(e);let o;for(;(o=n.next())&&!o.done;){const n=o.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:F,hasOwnProperty:_,hasOwnProp:_,reduceDescriptors:k,freezeMethods:e=>{k(e,((t,n)=>{if(p(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=e[n];p(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))}))},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach((e=>{n[e]=!0}))};return l(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,(function(e,t,n){return t.toUpperCase()+n})),noop:()=>{},toFiniteNumber:(e,t)=>null!=e&&Number.isFinite(e=+e)?e:t,findKey:C,global:j,isContextDefined:N,isSpecCompliantForm:function(e){return!!(e&&p(e.append)&&"FormData"===e[o]&&e[r])},toJSONObject:e=>{const t=new Array(10),n=(e,r)=>{if(b(e)){if(t.indexOf(e)>=0)return;if(f(e))return e;if(!("toJSON"in e)){t[r]=e;const o=l(e)?[]:{};return x(e,((e,t)=>{const s=n(e,r+1);!u(s)&&(o[t]=s)})),t[r]=void 0,o}}return e};return n(e,0)},isAsyncFn:B,isThenable:e=>e&&(b(e)||p(e))&&p(e.then)&&p(e.catch),setImmediate:D,asap:H,isIterable:e=>null!=e&&p(e[r])};function W(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o,this.status=o.status?o.status:null)}J.inherits(W,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:J.toJSONObject(this.config),code:this.code,status:this.status}}});const K=W.prototype,V={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach((e=>{V[e]={value:e}})),Object.defineProperties(W,V),Object.defineProperty(K,"isAxiosError",{value:!0}),W.from=(e,t,n,r,o,s)=>{const i=Object.create(K);J.toFlatObject(e,i,(function(e){return e!==Error.prototype}),(e=>"isAxiosError"!==e));const a=e&&e.message?e.message:"Error",c=null==t&&e?e.code:t;return W.call(i,a,c,n,r,o),e&&null==i.cause&&Object.defineProperty(i,"cause",{value:e,configurable:!0}),i.name=e&&e.name||"Error",s&&Object.assign(i,s),i};function $(e){return J.isPlainObject(e)||J.isArray(e)}function X(e){return J.endsWith(e,"[]")?e.slice(0,-2):e}function G(e,t,n){return e?e.concat(t).map((function(e,t){return e=X(e),!n&&t?"["+e+"]":e})).join(n?".":""):t}const Q=J.toFlatObject(J,{},null,(function(e){return/^is[A-Z]/.test(e)}));function Z(e,t,n){if(!J.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const r=(n=J.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,(function(e,t){return!J.isUndefined(t[e])}))).metaTokens,o=n.visitor||l,s=n.dots,i=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&J.isSpecCompliantForm(t);if(!J.isFunction(o))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(J.isDate(e))return e.toISOString();if(J.isBoolean(e))return e.toString();if(!a&&J.isBlob(e))throw new W("Blob is not supported. Use a Buffer instead.");return J.isArrayBuffer(e)||J.isTypedArray(e)?a&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function l(e,n,o){let a=e;if(e&&!o&&"object"==typeof e)if(J.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(J.isArray(e)&&function(e){return J.isArray(e)&&!e.some($)}(e)||(J.isFileList(e)||J.endsWith(n,"[]"))&&(a=J.toArray(e)))return n=X(n),a.forEach((function(e,r){!J.isUndefined(e)&&null!==e&&t.append(!0===i?G([n],r,s):null===i?n:n+"[]",c(e))})),!1;return!!$(e)||(t.append(G(o,n,s),c(e)),!1)}const u=[],f=Object.assign(Q,{defaultVisitor:l,convertValue:c,isVisitable:$});if(!J.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!J.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+r.join("."));u.push(n),J.forEach(n,(function(n,s){!0===(!(J.isUndefined(n)||null===n)&&o.call(t,n,J.isString(s)?s.trim():s,r,f))&&e(n,r?r.concat(s):[s])})),u.pop()}}(e),t}function Y(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,(function(e){return t[e]}))}function ee(e,t){this._pairs=[],e&&Z(e,this,t)}const te=ee.prototype;function ne(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function re(e,t,n){if(!t)return e;const r=n&&n.encode||ne;J.isFunction(n)&&(n={serialize:n});const o=n&&n.serialize;let s;if(s=o?o(t,n):J.isURLSearchParams(t)?t.toString():new ee(t,n).toString(r),s){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+s}return e}te.append=function(e,t){this._pairs.push([e,t])},te.toString=function(e){const t=e?function(t){return e.call(this,t,Y)}:Y;return this._pairs.map((function(e){return t(e[0])+"="+t(e[1])}),"").join("&")};const oe=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){J.forEach(this.handlers,(function(t){null!==t&&e(t)}))}},se={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},ie={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:ee,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]},ae="undefined"!=typeof window&&"undefined"!=typeof document,ce="object"==typeof navigator&&navigator||void 0,le=ae&&(!ce||["ReactNative","NativeScript","NS"].indexOf(ce.product)<0),ue="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,fe=ae&&window.location.href||"http://localhost",de={...Object.freeze({__proto__:null,hasBrowserEnv:ae,hasStandardBrowserWebWorkerEnv:ue,hasStandardBrowserEnv:le,navigator:ce,origin:fe}),...ie};function he(e){function t(e,n,r,o){let s=e[o++];if("__proto__"===s)return!0;const i=Number.isFinite(+s),a=o>=e.length;if(s=!s&&J.isArray(r)?r.length:s,a)return J.hasOwnProp(r,s)?r[s]=[r[s],n]:r[s]=n,!i;r[s]&&J.isObject(r[s])||(r[s]=[]);return t(e,n,r[s],o)&&J.isArray(r[s])&&(r[s]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let s;for(r=0;r{t(function(e){return J.matchAll(/\w+|\[(\w*)]/g,e).map((e=>"[]"===e[0]?"":e[1]||e[0]))}(e),r,n,0)})),n}return null}const pe={transitional:se,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=J.isObject(e);o&&J.isHTMLForm(e)&&(e=new FormData(e));if(J.isFormData(e))return r?JSON.stringify(he(e)):e;if(J.isArrayBuffer(e)||J.isBuffer(e)||J.isStream(e)||J.isFile(e)||J.isBlob(e)||J.isReadableStream(e))return e;if(J.isArrayBufferView(e))return e.buffer;if(J.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let s;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return Z(e,new de.classes.URLSearchParams,{visitor:function(e,t,n,r){return de.isNode&&J.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)},...t})}(e,this.formSerializer).toString();if((s=J.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return Z(s?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e,t,n){if(J.isString(e))try{return(t||JSON.parse)(e),J.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(n||JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||pe.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(J.isResponse(e)||J.isReadableStream(e))return e;if(e&&J.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e,this.parseReviver)}catch(e){if(n){if("SyntaxError"===e.name)throw W.from(e,W.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:de.classes.FormData,Blob:de.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};J.forEach(["delete","get","head","post","put","patch"],(e=>{pe.headers[e]={}}));const me=pe,be=J.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),ye=Symbol("internals");function ge(e){return e&&String(e).trim().toLowerCase()}function we(e){return!1===e||null==e?e:J.isArray(e)?e.map(we):String(e)}function Ee(e,t,n,r,o){return J.isFunction(r)?r.call(this,t,n):(o&&(t=n),J.isString(t)?J.isString(r)?-1!==t.indexOf(r):J.isRegExp(r)?r.test(t):void 0:void 0)}class Oe{constructor(e){e&&this.set(e)}set(e,t,n){const r=this;function o(e,t,n){const o=ge(t);if(!o)throw new Error("header name must be a non-empty string");const s=J.findKey(r,o);(!s||void 0===r[s]||!0===n||void 0===n&&!1!==r[s])&&(r[s||t]=we(e))}const s=(e,t)=>J.forEach(e,((e,n)=>o(e,n,t)));if(J.isPlainObject(e)||e instanceof this.constructor)s(e,t);else if(J.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))s((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach((function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&be[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)})),t})(e),t);else if(J.isObject(e)&&J.isIterable(e)){let n,r,o={};for(const t of e){if(!J.isArray(t))throw TypeError("Object iterator must return a key-value pair");o[r=t[0]]=(n=o[r])?J.isArray(n)?[...n,t[1]]:[n,t[1]]:t[1]}s(o,t)}else null!=e&&o(t,e,n);return this}get(e,t){if(e=ge(e)){const n=J.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(J.isFunction(t))return t.call(this,e,n);if(J.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=ge(e)){const n=J.findKey(this,e);return!(!n||void 0===this[n]||t&&!Ee(0,this[n],n,t))}return!1}delete(e,t){const n=this;let r=!1;function o(e){if(e=ge(e)){const o=J.findKey(n,e);!o||t&&!Ee(0,n[o],o,t)||(delete n[o],r=!0)}}return J.isArray(e)?e.forEach(o):o(e),r}clear(e){const t=Object.keys(this);let n=t.length,r=!1;for(;n--;){const o=t[n];e&&!Ee(0,this[o],o,e,!0)||(delete this[o],r=!0)}return r}normalize(e){const t=this,n={};return J.forEach(this,((r,o)=>{const s=J.findKey(n,o);if(s)return t[s]=we(r),void delete t[o];const i=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,((e,t,n)=>t.toUpperCase()+n))}(o):String(o).trim();i!==o&&delete t[o],t[i]=we(r),n[i]=!0})),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return J.forEach(this,((n,r)=>{null!=n&&!1!==n&&(t[r]=e&&J.isArray(n)?n.join(", "):n)})),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map((([e,t])=>e+": "+t)).join("\n")}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach((e=>n.set(e))),n}static accessor(e){const t=(this[ye]=this[ye]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=ge(e);t[r]||(!function(e,t){const n=J.toCamelCase(" "+t);["get","set","has"].forEach((r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})}))}(n,e),t[r]=!0)}return J.isArray(e)?e.forEach(r):r(e),this}}Oe.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),J.reduceDescriptors(Oe.prototype,(({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}})),J.freezeMethods(Oe);const Re=Oe;function Se(e,t){const n=this||me,r=t||n,o=Re.from(r.headers);let s=r.data;return J.forEach(e,(function(e){s=e.call(n,s,o.normalize(),t?t.status:void 0)})),o.normalize(),s}function Te(e){return!(!e||!e.__CANCEL__)}function Ae(e,t,n){W.call(this,null==e?"canceled":e,W.ERR_CANCELED,t,n),this.name="CanceledError"}function ve(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new W("Request failed with status code "+n.status,[W.ERR_BAD_REQUEST,W.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}J.inherits(Ae,W,{__CANCEL__:!0});const xe=(e,t,n=3)=>{let r=0;const o=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,s=0,i=0;return t=void 0!==t?t:1e3,function(a){const c=Date.now(),l=r[i];o||(o=c),n[s]=a,r[s]=c;let u=i,f=0;for(;u!==s;)f+=n[u++],u%=e;if(s=(s+1)%e,s===i&&(i=(i+1)%e),c-o{o=s,n=null,r&&(clearTimeout(r),r=null),e(...t)};return[(...e)=>{const t=Date.now(),a=t-o;a>=s?i(e,t):(n=e,r||(r=setTimeout((()=>{r=null,i(n)}),s-a)))},()=>n&&i(n)]}((n=>{const s=n.loaded,i=n.lengthComputable?n.total:void 0,a=s-r,c=o(a);r=s;e({loaded:s,total:i,progress:i?s/i:void 0,bytes:a,rate:c||void 0,estimated:c&&i&&s<=i?(i-s)/c:void 0,event:n,lengthComputable:null!=i,[t?"download":"upload"]:!0})}),n)},Ce=(e,t)=>{const n=null!=e;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},je=e=>(...t)=>J.asap((()=>e(...t))),Ne=de.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,de.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(de.origin),de.navigator&&/(msie|trident)/i.test(de.navigator.userAgent)):()=>!0,Ue=de.hasStandardBrowserEnv?{write(e,t,n,r,o,s){const i=[e+"="+encodeURIComponent(t)];J.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),J.isString(r)&&i.push("path="+r),J.isString(o)&&i.push("domain="+o),!0===s&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read:()=>null,remove(){}};function Pe(e,t,n){let r=!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t);return e&&(r||0==n)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const Fe=e=>e instanceof Re?{...e}:e;function _e(e,t){t=t||{};const n={};function r(e,t,n,r){return J.isPlainObject(e)&&J.isPlainObject(t)?J.merge.call({caseless:r},e,t):J.isPlainObject(t)?J.merge({},t):J.isArray(t)?t.slice():t}function o(e,t,n,o){return J.isUndefined(t)?J.isUndefined(e)?void 0:r(void 0,e,0,o):r(e,t,0,o)}function s(e,t){if(!J.isUndefined(t))return r(void 0,t)}function i(e,t){return J.isUndefined(t)?J.isUndefined(e)?void 0:r(void 0,e):r(void 0,t)}function a(n,o,s){return s in t?r(n,o):s in e?r(void 0,n):void 0}const c={url:s,method:s,data:s,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(e,t,n)=>o(Fe(e),Fe(t),0,!0)};return J.forEach(Object.keys({...e,...t}),(function(r){const s=c[r]||o,i=s(e[r],t[r],r);J.isUndefined(i)&&s!==a||(n[r]=i)})),n}const Le=e=>{const t=_e({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:o,xsrfCookieName:s,headers:i,auth:a}=t;if(t.headers=i=Re.from(i),t.url=re(Pe(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),J.isFormData(n))if(de.hasStandardBrowserEnv||de.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if(J.isFunction(n.getHeaders)){const e=n.getHeaders(),t=["content-type","content-length"];Object.entries(e).forEach((([e,n])=>{t.includes(e.toLowerCase())&&i.set(e,n)}))}if(de.hasStandardBrowserEnv&&(r&&J.isFunction(r)&&(r=r(t)),r||!1!==r&&Ne(t.url))){const e=o&&s&&Ue.read(s);e&&i.set(o,e)}return t},ke="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise((function(t,n){const r=Le(e);let o=r.data;const s=Re.from(r.headers).normalize();let i,a,c,l,u,{responseType:f,onUploadProgress:d,onDownloadProgress:h}=r;function p(){l&&l(),u&&u(),r.cancelToken&&r.cancelToken.unsubscribe(i),r.signal&&r.signal.removeEventListener("abort",i)}let m=new XMLHttpRequest;function b(){if(!m)return;const r=Re.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());ve((function(e){t(e),p()}),(function(e){n(e),p()}),{data:f&&"text"!==f&&"json"!==f?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:r,config:e,request:m}),m=null}m.open(r.method.toUpperCase(),r.url,!0),m.timeout=r.timeout,"onloadend"in m?m.onloadend=b:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(b)},m.onabort=function(){m&&(n(new W("Request aborted",W.ECONNABORTED,e,m)),m=null)},m.onerror=function(t){const r=new W(t&&t.message?t.message:"Network Error",W.ERR_NETWORK,e,m);r.event=t||null,n(r),m=null},m.ontimeout=function(){let t=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const o=r.transitional||se;r.timeoutErrorMessage&&(t=r.timeoutErrorMessage),n(new W(t,o.clarifyTimeoutError?W.ETIMEDOUT:W.ECONNABORTED,e,m)),m=null},void 0===o&&s.setContentType(null),"setRequestHeader"in m&&J.forEach(s.toJSON(),(function(e,t){m.setRequestHeader(t,e)})),J.isUndefined(r.withCredentials)||(m.withCredentials=!!r.withCredentials),f&&"json"!==f&&(m.responseType=r.responseType),h&&([c,u]=xe(h,!0),m.addEventListener("progress",c)),d&&m.upload&&([a,l]=xe(d),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",l)),(r.cancelToken||r.signal)&&(i=t=>{m&&(n(!t||t.type?new Ae(null,e,m):t),m.abort(),m=null)},r.cancelToken&&r.cancelToken.subscribe(i),r.signal&&(r.signal.aborted?i():r.signal.addEventListener("abort",i)));const y=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(r.url);y&&-1===de.protocols.indexOf(y)?n(new W("Unsupported protocol "+y+":",W.ERR_BAD_REQUEST,e)):m.send(o||null)}))},Be=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let n,r=new AbortController;const o=function(e){if(!n){n=!0,i();const t=e instanceof Error?e:this.reason;r.abort(t instanceof W?t:new Ae(t instanceof Error?t.message:t))}};let s=t&&setTimeout((()=>{s=null,o(new W(`timeout ${t} of ms exceeded`,W.ETIMEDOUT))}),t);const i=()=>{e&&(s&&clearTimeout(s),s=null,e.forEach((e=>{e.unsubscribe?e.unsubscribe(o):e.removeEventListener("abort",o)})),e=null)};e.forEach((e=>e.addEventListener("abort",o)));const{signal:a}=r;return a.unsubscribe=()=>J.asap(i),a}},De=function*(e,t){let n=e.byteLength;if(!t||n{const o=async function*(e,t){for await(const n of qe(e))yield*De(n,t)}(e,t);let s,i=0,a=e=>{s||(s=!0,r&&r(e))};return new ReadableStream({async pull(e){try{const{done:t,value:r}=await o.next();if(t)return a(),void e.close();let s=r.byteLength;if(n){let e=i+=s;n(e)}e.enqueue(new Uint8Array(r))}catch(e){throw a(e),e}},cancel:e=>(a(e),o.return())},{highWaterMark:2})},{isFunction:Ie}=J,ze=(({Request:e,Response:t})=>({Request:e,Response:t}))(J.global),{ReadableStream:He,TextEncoder:Je}=J.global,We=(e,...t)=>{try{return!!e(...t)}catch(e){return!1}},Ke=e=>{e=J.merge.call({skipUndefined:!0},ze,e);const{fetch:t,Request:n,Response:r}=e,o=t?Ie(t):"function"==typeof fetch,s=Ie(n),i=Ie(r);if(!o)return!1;const a=o&&Ie(He),c=o&&("function"==typeof Je?(l=new Je,e=>l.encode(e)):async e=>new Uint8Array(await new n(e).arrayBuffer()));var l;const u=s&&a&&We((()=>{let e=!1;const t=new n(de.origin,{body:new He,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t})),f=i&&a&&We((()=>J.isReadableStream(new r("").body))),d={stream:f&&(e=>e.body)};o&&["text","arrayBuffer","blob","formData","stream"].forEach((e=>{!d[e]&&(d[e]=(t,n)=>{let r=t&&t[e];if(r)return r.call(t);throw new W(`Response type '${e}' is not supported`,W.ERR_NOT_SUPPORT,n)})}));const h=async(e,t)=>{const r=J.toFiniteNumber(e.getContentLength());return null==r?(async e=>{if(null==e)return 0;if(J.isBlob(e))return e.size;if(J.isSpecCompliantForm(e)){const t=new n(de.origin,{method:"POST",body:e});return(await t.arrayBuffer()).byteLength}return J.isArrayBufferView(e)||J.isArrayBuffer(e)?e.byteLength:(J.isURLSearchParams(e)&&(e+=""),J.isString(e)?(await c(e)).byteLength:void 0)})(t):r};return async e=>{let{url:o,method:i,data:a,signal:c,cancelToken:l,timeout:p,onDownloadProgress:m,onUploadProgress:b,responseType:y,headers:g,withCredentials:w="same-origin",fetchOptions:E}=Le(e),O=t||fetch;y=y?(y+"").toLowerCase():"text";let R=Be([c,l&&l.toAbortSignal()],p),S=null;const T=R&&R.unsubscribe&&(()=>{R.unsubscribe()});let A;try{if(b&&u&&"get"!==i&&"head"!==i&&0!==(A=await h(g,a))){let e,t=new n(o,{method:"POST",body:a,duplex:"half"});if(J.isFormData(a)&&(e=t.headers.get("content-type"))&&g.setContentType(e),t.body){const[e,n]=Ce(A,xe(je(b)));a=Me(t.body,65536,e,n)}}J.isString(w)||(w=w?"include":"omit");const t=s&&"credentials"in n.prototype,c={...E,signal:R,method:i.toUpperCase(),headers:g.normalize().toJSON(),body:a,duplex:"half",credentials:t?w:void 0};S=s&&new n(o,c);let l=await(s?O(S,E):O(o,c));const p=f&&("stream"===y||"response"===y);if(f&&(m||p&&T)){const e={};["status","statusText","headers"].forEach((t=>{e[t]=l[t]}));const t=J.toFiniteNumber(l.headers.get("content-length")),[n,o]=m&&Ce(t,xe(je(m),!0))||[];l=new r(Me(l.body,65536,n,(()=>{o&&o(),T&&T()})),e)}y=y||"text";let v=await d[J.findKey(d,y)||"text"](l,e);return!p&&T&&T(),await new Promise(((t,n)=>{ve(t,n,{data:v,headers:Re.from(l.headers),status:l.status,statusText:l.statusText,config:e,request:S})}))}catch(t){if(T&&T(),t&&"TypeError"===t.name&&/Load failed|fetch/i.test(t.message))throw Object.assign(new W("Network Error",W.ERR_NETWORK,e,S),{cause:t.cause||t});throw W.from(t,t&&t.code,e,S)}}},Ve=new Map,$e=e=>{let t=e?e.env:{};const{fetch:n,Request:r,Response:o}=t,s=[r,o,n];let i,a,c=s.length,l=Ve;for(;c--;)i=s[c],a=l.get(i),void 0===a&&l.set(i,a=c?new Map:Ke(t)),l=a;return a};$e();const Xe={http:null,xhr:ke,fetch:{get:$e}};J.forEach(Xe,((e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}}));const Ge=e=>`- ${e}`,Qe=e=>J.isFunction(e)||null===e||!1===e,Ze=(e,t)=>{e=J.isArray(e)?e:[e];const{length:n}=e;let r,o;const s={};for(let i=0;i`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build")));throw new W("There is no suitable adapter to dispatch the request "+(n?e.length>1?"since :\n"+e.map(Ge).join("\n"):" "+Ge(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return o};function Ye(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new Ae(null,e)}function et(e){Ye(e),e.headers=Re.from(e.headers),e.data=Se.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1);return Ze(e.adapter||me.adapter,e)(e).then((function(t){return Ye(e),t.data=Se.call(e,e.transformResponse,t),t.headers=Re.from(t.headers),t}),(function(t){return Te(t)||(Ye(e),t&&t.response&&(t.response.data=Se.call(e,e.transformResponse,t.response),t.response.headers=Re.from(t.response.headers))),Promise.reject(t)}))}const tt={};["object","boolean","number","function","string","symbol"].forEach(((e,t)=>{tt[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}}));const nt={};tt.transitional=function(e,t,n){function r(e,t){return"[Axios v1.12.2] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,s)=>{if(!1===e)throw new W(r(o," has been removed"+(t?" in "+t:"")),W.ERR_DEPRECATED);return t&&!nt[o]&&(nt[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,s)}},tt.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};const rt={assertOptions:function(e,t,n){if("object"!=typeof e)throw new W("options must be an object",W.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const s=r[o],i=t[s];if(i){const t=e[s],n=void 0===t||i(t,s,e);if(!0!==n)throw new W("option "+s+" must be "+n,W.ERR_BAD_OPTION_VALUE)}else if(!0!==n)throw new W("Unknown option "+s,W.ERR_BAD_OPTION)}},validators:tt},ot=rt.validators;class st{constructor(e){this.defaults=e||{},this.interceptors={request:new oe,response:new oe}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";try{e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}catch(e){}}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=_e(this.defaults,t);const{transitional:n,paramsSerializer:r,headers:o}=t;void 0!==n&&rt.assertOptions(n,{silentJSONParsing:ot.transitional(ot.boolean),forcedJSONParsing:ot.transitional(ot.boolean),clarifyTimeoutError:ot.transitional(ot.boolean)},!1),null!=r&&(J.isFunction(r)?t.paramsSerializer={serialize:r}:rt.assertOptions(r,{encode:ot.function,serialize:ot.function},!0)),void 0!==t.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),rt.assertOptions(t,{baseUrl:ot.spelling("baseURL"),withXsrfToken:ot.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let s=o&&J.merge(o.common,o[t.method]);o&&J.forEach(["delete","get","head","post","put","patch","common"],(e=>{delete o[e]})),t.headers=Re.concat(s,o);const i=[];let a=!0;this.interceptors.request.forEach((function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,i.unshift(e.fulfilled,e.rejected))}));const c=[];let l;this.interceptors.response.forEach((function(e){c.push(e.fulfilled,e.rejected)}));let u,f=0;if(!a){const e=[et.bind(this),void 0];for(e.unshift(...i),e.push(...c),u=e.length,l=Promise.resolve(t);f{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null})),this.promise.then=e=>{let t;const r=new Promise((e=>{n.subscribe(e),t=e})).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e((function(e,r,o){n.reason||(n.reason=new Ae(e,r,o),t(n.reason))}))}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}toAbortSignal(){const e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let e;return{token:new at((function(t){e=t})),cancel:e}}}const ct=at;const lt={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(lt).forEach((([e,t])=>{lt[t]=e}));const ut=lt;const ft=function t(n){const r=new it(n),o=e(it.prototype.request,r);return J.extend(o,it.prototype,r,{allOwnKeys:!0}),J.extend(o,r,null,{allOwnKeys:!0}),o.create=function(e){return t(_e(n,e))},o}(me);ft.Axios=it,ft.CanceledError=Ae,ft.CancelToken=ct,ft.isCancel=Te,ft.VERSION="1.12.2",ft.toFormData=Z,ft.AxiosError=W,ft.Cancel=ft.CanceledError,ft.all=function(e){return Promise.all(e)},ft.spread=function(e){return function(t){return e.apply(null,t)}},ft.isAxiosError=function(e){return J.isObject(e)&&!0===e.isAxiosError},ft.mergeConfig=_e,ft.AxiosHeaders=Re,ft.formToJSON=e=>he(J.isHTMLForm(e)?new FormData(e):e),ft.getAdapter=Ze,ft.HttpStatusCode=ut,ft.default=ft;const dt=ft,{Axios:ht,AxiosError:pt,CanceledError:mt,isCancel:bt,CancelToken:yt,VERSION:gt,all:wt,Cancel:Et,isAxiosError:Ot,spread:Rt,toFormData:St,AxiosHeaders:Tt,HttpStatusCode:At,formToJSON:vt,getAdapter:xt,mergeConfig:Ct}=dt;export{ht as Axios,pt as AxiosError,Tt as AxiosHeaders,Et as Cancel,yt as CancelToken,mt as CanceledError,At as HttpStatusCode,gt as VERSION,wt as all,dt as default,vt as formToJSON,xt as getAdapter,Ot as isAxiosError,bt as isCancel,Ct as mergeConfig,Rt as spread,St as toFormData}; +//# sourceMappingURL=axios.min.js.map diff --git a/node_modules/axios/dist/esm/axios.min.js.map b/node_modules/axios/dist/esm/axios.min.js.map new file mode 100644 index 0000000..8c9c177 --- /dev/null +++ b/node_modules/axios/dist/esm/axios.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"axios.min.js","sources":["../../lib/helpers/bind.js","../../lib/utils.js","../../lib/core/AxiosError.js","../../lib/helpers/toFormData.js","../../lib/helpers/AxiosURLSearchParams.js","../../lib/helpers/buildURL.js","../../lib/core/InterceptorManager.js","../../lib/defaults/transitional.js","../../lib/platform/browser/index.js","../../lib/platform/browser/classes/URLSearchParams.js","../../lib/platform/browser/classes/FormData.js","../../lib/platform/browser/classes/Blob.js","../../lib/platform/common/utils.js","../../lib/platform/index.js","../../lib/helpers/formDataToJSON.js","../../lib/defaults/index.js","../../lib/helpers/toURLEncodedForm.js","../../lib/helpers/parseHeaders.js","../../lib/core/AxiosHeaders.js","../../lib/core/transformData.js","../../lib/cancel/isCancel.js","../../lib/cancel/CanceledError.js","../../lib/core/settle.js","../../lib/helpers/progressEventReducer.js","../../lib/helpers/speedometer.js","../../lib/helpers/throttle.js","../../lib/helpers/isURLSameOrigin.js","../../lib/helpers/cookies.js","../../lib/core/buildFullPath.js","../../lib/helpers/isAbsoluteURL.js","../../lib/helpers/combineURLs.js","../../lib/core/mergeConfig.js","../../lib/helpers/resolveConfig.js","../../lib/adapters/xhr.js","../../lib/helpers/parseProtocol.js","../../lib/helpers/composeSignals.js","../../lib/helpers/trackStream.js","../../lib/adapters/fetch.js","../../lib/adapters/adapters.js","../../lib/helpers/null.js","../../lib/core/dispatchRequest.js","../../lib/env/data.js","../../lib/helpers/validator.js","../../lib/core/Axios.js","../../lib/cancel/CancelToken.js","../../lib/helpers/HttpStatusCode.js","../../lib/axios.js","../../lib/helpers/spread.js","../../lib/helpers/isAxiosError.js","../../index.js"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n // Early return for non-objects or Buffers to prevent RangeError\n if (!isObject(val) || isBuffer(val)) {\n return false;\n }\n\n try {\n return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n } catch (e) {\n // Fallback for any other objects that might cause RangeError with Object.keys()\n return false;\n }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Buffer check\n if (isBuffer(obj)) {\n return;\n }\n\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n if (isBuffer(obj)){\n return null;\n }\n\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else if (!skipUndefined || !isUndefined(val)) {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n //Buffer check\n if (isBuffer(source)) {\n return source;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isEmptyObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n const msg = error && error.message ? error.message : 'Error';\n\n // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n const errCode = code == null && error ? error.code : code;\n AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n if (error && axiosError.cause == null) {\n Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n }\n\n axiosError.name = (error && error.name) || 'Error';\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","import URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\nimport Blob from './classes/Blob.js'\n\nexport default {\n isBrowser: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob\n },\n protocols: ['http', 'https', 'file', 'blob', 'url', 'data']\n};\n","'use strict';\n\nimport AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js';\nexport default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams;\n","'use strict';\n\nexport default typeof FormData !== 'undefined' ? FormData : null;\n","'use strict'\n\nexport default typeof Blob !== 'undefined' ? Blob : null\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data, this.parseReviver);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), {\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n },\n ...options\n });\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn(...args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // browser handles it\n } else if (utils.isFunction(data.getHeaders)) {\n // Node.js FormData (like form-data package)\n const formHeaders = data.getHeaders();\n // Only set safe headers to avoid overwriting security headers\n const allowedHeaders = ['content-type', 'content-length'];\n Object.entries(formHeaders).forEach(([key, val]) => {\n if (allowedHeaders.includes(key.toLowerCase())) {\n headers.set(key, val);\n }\n });\n }\n } \n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError(event) {\n // Browsers deliver a ProgressEvent in XHR onerror\n // (message may be empty; when present, surface it)\n // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n const msg = event && event.message ? event.message : 'Network Error';\n const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n // attach the underlying event for consumers who want details\n err.event = event || null;\n reject(err);\n request = null;\n };\n \n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n Request, Response\n}))(utils.global);\n\nconst {\n ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst factory = (env) => {\n env = utils.merge.call({\n skipUndefined: true\n }, globalFetchAPI, env);\n\n const {fetch: envFetch, Request, Response} = env;\n const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n const isRequestSupported = isFunction(Request);\n const isResponseSupported = isFunction(Response);\n\n if (!isFetchSupported) {\n return false;\n }\n\n const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n );\n\n const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n });\n\n const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n const resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n };\n\n isFetchSupported && ((() => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = (res, config) => {\n let method = res && res[type];\n\n if (method) {\n return method.call(res);\n }\n\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n })());\n\n const getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if (utils.isBlob(body)) {\n return body.size;\n }\n\n if (utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if (utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if (utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n }\n\n const resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n }\n\n return async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n let _fetch = envFetch || fetch;\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request = null;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n const resolvedOptions = {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n };\n\n request = isRequestSupported && new Request(url, resolvedOptions);\n\n let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n let env = config ? config.env : {};\n const {fetch, Request, Response} = env;\n const seeds = [\n Request, Response, fetch\n ];\n\n let len = seeds.length, i = len,\n seed, target, map = seedCache;\n\n while (i--) {\n seed = seeds[i];\n target = map.get(seed);\n\n target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n map = target;\n }\n\n return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: {\n get: fetchAdapter.getFetch,\n }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters, config) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","// eslint-disable-next-line strict\nexport default null;\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift(...requestInterceptorChain);\n chain.push(...responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","import axios from './lib/axios.js';\n\n// This module is intended to unwrap Axios default export as named.\n// Keep top-level export same with static properties\n// so that it can keep same with es module or cjs\nconst {\n Axios,\n AxiosError,\n CanceledError,\n isCancel,\n CancelToken,\n VERSION,\n all,\n Cancel,\n isAxiosError,\n spread,\n toFormData,\n AxiosHeaders,\n HttpStatusCode,\n formToJSON,\n getAdapter,\n mergeConfig\n} = axios;\n\nexport {\n axios as default,\n Axios,\n AxiosError,\n CanceledError,\n isCancel,\n CancelToken,\n VERSION,\n all,\n Cancel,\n isAxiosError,\n spread,\n toFormData,\n AxiosHeaders,\n HttpStatusCode,\n formToJSON,\n getAdapter,\n mergeConfig\n}\n"],"names":["bind","fn","thisArg","apply","arguments","toString","Object","prototype","getPrototypeOf","iterator","toStringTag","Symbol","kindOf","cache","create","thing","str","call","slice","toLowerCase","kindOfTest","type","typeOfTest","isArray","Array","isUndefined","isBuffer","val","constructor","isFunction","isArrayBuffer","isString","isNumber","isObject","isPlainObject","isDate","isFile","isBlob","isFileList","isURLSearchParams","isReadableStream","isRequest","isResponse","isHeaders","map","forEach","obj","allOwnKeys","i","l","length","keys","getOwnPropertyNames","len","key","findKey","_key","_global","globalThis","self","window","global","isContextDefined","context","isTypedArray","TypedArray","Uint8Array","isHTMLForm","hasOwnProperty","prop","isRegExp","reduceDescriptors","reducer","descriptors","getOwnPropertyDescriptors","reducedDescriptors","descriptor","name","ret","defineProperties","isAsyncFn","_setImmediate","setImmediateSupported","setImmediate","postMessageSupported","postMessage","token","Math","random","callbacks","addEventListener","source","data","shift","cb","push","setTimeout","asap","queueMicrotask","process","nextTick","utils$1","isFormData","kind","FormData","append","isArrayBufferView","result","ArrayBuffer","isView","buffer","isBoolean","isEmptyObject","e","isStream","pipe","merge","caseless","skipUndefined","this","assignValue","targetKey","extend","a","b","trim","replace","stripBOM","content","charCodeAt","inherits","superConstructor","props","defineProperty","value","assign","toFlatObject","sourceObj","destObj","filter","propFilter","merged","endsWith","searchString","position","String","undefined","lastIndex","indexOf","toArray","arr","forEachEntry","_iterator","next","done","pair","matchAll","regExp","matches","exec","hasOwnProp","freezeMethods","enumerable","writable","set","Error","toObjectSet","arrayOrString","delimiter","define","split","toCamelCase","m","p1","p2","toUpperCase","noop","toFiniteNumber","defaultValue","Number","isFinite","isSpecCompliantForm","toJSONObject","stack","visit","target","reducedValue","isThenable","then","catch","isIterable","AxiosError","message","code","config","request","response","captureStackTrace","status","utils","toJSON","description","number","fileName","lineNumber","columnNumber","from","error","customProps","axiosError","msg","errCode","cause","configurable","isVisitable","removeBrackets","renderKey","path","dots","concat","join","predicates","test","toFormData","formData","options","TypeError","metaTokens","indexes","option","visitor","defaultVisitor","useBlob","Blob","convertValue","toISOString","Buffer","JSON","stringify","some","isFlatArray","el","index","exposedHelpers","build","pop","encode","charMap","encodeURIComponent","match","AxiosURLSearchParams","params","_pairs","buildURL","url","_encode","serialize","serializeFn","serializedParams","hashmarkIndex","encoder","InterceptorManager$1","handlers","use","fulfilled","rejected","synchronous","runWhen","eject","id","clear","h","transitionalDefaults","silentJSONParsing","forcedJSONParsing","clarifyTimeoutError","platform$1","isBrowser","classes","URLSearchParams","protocols","hasBrowserEnv","document","_navigator","navigator","hasStandardBrowserEnv","product","hasStandardBrowserWebWorkerEnv","WorkerGlobalScope","importScripts","origin","location","href","platform","formDataToJSON","buildPath","isNumericKey","isLast","arrayToObject","entries","parsePropPath","defaults","transitional","adapter","transformRequest","headers","contentType","getContentType","hasJSONContentType","isObjectPayload","setContentType","helpers","isNode","toURLEncodedForm","formSerializer","_FormData","env","rawValue","parser","parse","stringifySafely","transformResponse","JSONRequested","responseType","strictJSONParsing","parseReviver","ERR_BAD_RESPONSE","timeout","xsrfCookieName","xsrfHeaderName","maxContentLength","maxBodyLength","validateStatus","common","Accept","method","defaults$1","ignoreDuplicateOf","$internals","normalizeHeader","header","normalizeValue","matchHeaderValue","isHeaderNameFilter","AxiosHeaders","valueOrRewrite","rewrite","setHeader","_value","_header","_rewrite","lHeader","setHeaders","rawHeaders","parsed","line","substring","parseHeaders","dest","entry","get","tokens","tokensRE","parseTokens","has","matcher","delete","deleted","deleteHeader","normalize","format","normalized","w","char","formatHeader","targets","asStrings","getSetCookie","static","first","computed","accessors","defineAccessor","accessorName","methodName","arg1","arg2","arg3","buildAccessors","accessor","mapped","headerValue","AxiosHeaders$2","transformData","fns","isCancel","__CANCEL__","CanceledError","ERR_CANCELED","settle","resolve","reject","ERR_BAD_REQUEST","floor","progressEventReducer","listener","isDownloadStream","freq","bytesNotified","_speedometer","samplesCount","min","bytes","timestamps","firstSampleTS","head","tail","chunkLength","now","Date","startedAt","bytesCount","passed","round","speedometer","lastArgs","timer","timestamp","threshold","invoke","args","clearTimeout","throttle","loaded","total","lengthComputable","progressBytes","rate","progress","estimated","event","progressEventDecorator","throttled","asyncDecorator","isURLSameOrigin","isMSIE","URL","protocol","host","port","userAgent","cookies","write","expires","domain","secure","cookie","toGMTString","read","RegExp","decodeURIComponent","remove","buildFullPath","baseURL","requestedURL","allowAbsoluteUrls","isRelativeUrl","relativeURL","combineURLs","headersToObject","mergeConfig","config1","config2","getMergedValue","mergeDeepProperties","valueFromConfig2","defaultToConfig2","mergeDirectKeys","mergeMap","paramsSerializer","timeoutMessage","withCredentials","withXSRFToken","onUploadProgress","onDownloadProgress","decompress","beforeRedirect","transport","httpAgent","httpsAgent","cancelToken","socketPath","responseEncoding","configValue","resolveConfig","newConfig","auth","btoa","username","password","unescape","getHeaders","formHeaders","allowedHeaders","includes","xsrfValue","xhrAdapter","XMLHttpRequest","Promise","_config","requestData","requestHeaders","onCanceled","uploadThrottled","downloadThrottled","flushUpload","flushDownload","unsubscribe","signal","removeEventListener","onloadend","responseHeaders","getAllResponseHeaders","err","responseText","statusText","open","onreadystatechange","readyState","responseURL","onabort","ECONNABORTED","onerror","ERR_NETWORK","ontimeout","timeoutErrorMessage","ETIMEDOUT","setRequestHeader","upload","cancel","abort","subscribe","aborted","parseProtocol","send","composeSignals$1","signals","Boolean","controller","AbortController","reason","streamChunk","chunk","chunkSize","byteLength","end","pos","readStream","async","stream","asyncIterator","reader","getReader","trackStream","onProgress","onFinish","iterable","readBytes","_onFinish","ReadableStream","close","loadedBytes","enqueue","return","highWaterMark","globalFetchAPI","Request","Response","TextEncoder","factory","fetch","envFetch","isFetchSupported","isRequestSupported","isResponseSupported","isReadableStreamSupported","encodeText","arrayBuffer","supportsRequestStream","duplexAccessed","hasContentType","body","duplex","supportsResponseStream","resolvers","res","ERR_NOT_SUPPORT","resolveBodyLength","getContentLength","size","_request","getBodyLength","fetchOptions","_fetch","composedSignal","composeSignals","toAbortSignal","requestContentLength","contentTypeHeader","flush","isCredentialsSupported","resolvedOptions","credentials","isStreamResponse","responseContentLength","responseData","seedCache","Map","getFetch","seeds","seed","knownAdapters","http","xhr","fetchAdapter.getFetch","renderReason","isResolvedHandle","adapters","nameOrAdapter","rejectedReasons","reasons","state","throwIfCancellationRequested","throwIfRequested","dispatchRequest","validators","deprecatedWarnings","validator","version","formatMessage","opt","desc","opts","ERR_DEPRECATED","console","warn","spelling","correctSpelling","assertOptions","schema","allowUnknown","ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","Axios","instanceConfig","interceptors","InterceptorManager","configOrUrl","dummy","boolean","function","baseUrl","withXsrfToken","contextHeaders","requestInterceptorChain","synchronousRequestInterceptors","interceptor","unshift","responseInterceptorChain","promise","chain","onFulfilled","onRejected","getUri","generateHTTPMethod","isForm","Axios$2","CancelToken","executor","resolvePromise","_listeners","onfulfilled","_resolve","splice","c","CancelToken$2","HttpStatusCode","Continue","SwitchingProtocols","Processing","EarlyHints","Ok","Created","Accepted","NonAuthoritativeInformation","NoContent","ResetContent","PartialContent","MultiStatus","AlreadyReported","ImUsed","MultipleChoices","MovedPermanently","Found","SeeOther","NotModified","UseProxy","Unused","TemporaryRedirect","PermanentRedirect","BadRequest","Unauthorized","PaymentRequired","Forbidden","NotFound","MethodNotAllowed","NotAcceptable","ProxyAuthenticationRequired","RequestTimeout","Conflict","Gone","LengthRequired","PreconditionFailed","PayloadTooLarge","UriTooLong","UnsupportedMediaType","RangeNotSatisfiable","ExpectationFailed","ImATeapot","MisdirectedRequest","UnprocessableEntity","Locked","FailedDependency","TooEarly","UpgradeRequired","PreconditionRequired","TooManyRequests","RequestHeaderFieldsTooLarge","UnavailableForLegalReasons","InternalServerError","NotImplemented","BadGateway","ServiceUnavailable","GatewayTimeout","HttpVersionNotSupported","VariantAlsoNegotiates","InsufficientStorage","LoopDetected","NotExtended","NetworkAuthenticationRequired","HttpStatusCode$2","axios","createInstance","defaultConfig","instance","VERSION","Cancel","all","promises","spread","callback","isAxiosError","payload","formToJSON","getAdapter","default","axios$1"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/axios/dist/node/axios.cjs b/node_modules/axios/dist/node/axios.cjs new file mode 100644 index 0000000..0e8b6ac --- /dev/null +++ b/node_modules/axios/dist/node/axios.cjs @@ -0,0 +1,4988 @@ +/*! Axios v1.12.2 Copyright (c) 2025 Matt Zabriskie and contributors */ +'use strict'; + +const FormData$1 = require('form-data'); +const crypto = require('crypto'); +const url = require('url'); +const proxyFromEnv = require('proxy-from-env'); +const http = require('http'); +const https = require('https'); +const util = require('util'); +const followRedirects = require('follow-redirects'); +const zlib = require('zlib'); +const stream = require('stream'); +const events = require('events'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +const FormData__default = /*#__PURE__*/_interopDefaultLegacy(FormData$1); +const crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto); +const url__default = /*#__PURE__*/_interopDefaultLegacy(url); +const proxyFromEnv__default = /*#__PURE__*/_interopDefaultLegacy(proxyFromEnv); +const http__default = /*#__PURE__*/_interopDefaultLegacy(http); +const https__default = /*#__PURE__*/_interopDefaultLegacy(https); +const util__default = /*#__PURE__*/_interopDefaultLegacy(util); +const followRedirects__default = /*#__PURE__*/_interopDefaultLegacy(followRedirects); +const zlib__default = /*#__PURE__*/_interopDefaultLegacy(zlib); +const stream__default = /*#__PURE__*/_interopDefaultLegacy(stream); + +function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; +} + +// utils is a library of generic helper functions non-specific to axios + +const {toString} = Object.prototype; +const {getPrototypeOf} = Object; +const {iterator, toStringTag} = Symbol; + +const kindOf = (cache => thing => { + const str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); +})(Object.create(null)); + +const kindOfTest = (type) => { + type = type.toLowerCase(); + return (thing) => kindOf(thing) === type +}; + +const typeOfTest = type => thing => typeof thing === type; + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * + * @returns {boolean} True if value is an Array, otherwise false + */ +const {isArray} = Array; + +/** + * Determine if a value is undefined + * + * @param {*} val The value to test + * + * @returns {boolean} True if the value is undefined, otherwise false + */ +const isUndefined = typeOfTest('undefined'); + +/** + * Determine if a value is a Buffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Buffer, otherwise false + */ +function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && isFunction$1(val.constructor.isBuffer) && val.constructor.isBuffer(val); +} + +/** + * Determine if a value is an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ +const isArrayBuffer = kindOfTest('ArrayBuffer'); + + +/** + * Determine if a value is a view on an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ +function isArrayBufferView(val) { + let result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); + } + return result; +} + +/** + * Determine if a value is a String + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a String, otherwise false + */ +const isString = typeOfTest('string'); + +/** + * Determine if a value is a Function + * + * @param {*} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ +const isFunction$1 = typeOfTest('function'); + +/** + * Determine if a value is a Number + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Number, otherwise false + */ +const isNumber = typeOfTest('number'); + +/** + * Determine if a value is an Object + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an Object, otherwise false + */ +const isObject = (thing) => thing !== null && typeof thing === 'object'; + +/** + * Determine if a value is a Boolean + * + * @param {*} thing The value to test + * @returns {boolean} True if value is a Boolean, otherwise false + */ +const isBoolean = thing => thing === true || thing === false; + +/** + * Determine if a value is a plain Object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a plain Object, otherwise false + */ +const isPlainObject = (val) => { + if (kindOf(val) !== 'object') { + return false; + } + + const prototype = getPrototypeOf(val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); +}; + +/** + * Determine if a value is an empty object (safely handles Buffers) + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an empty object, otherwise false + */ +const isEmptyObject = (val) => { + // Early return for non-objects or Buffers to prevent RangeError + if (!isObject(val) || isBuffer(val)) { + return false; + } + + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + // Fallback for any other objects that might cause RangeError with Object.keys() + return false; + } +}; + +/** + * Determine if a value is a Date + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Date, otherwise false + */ +const isDate = kindOfTest('Date'); + +/** + * Determine if a value is a File + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFile = kindOfTest('File'); + +/** + * Determine if a value is a Blob + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Blob, otherwise false + */ +const isBlob = kindOfTest('Blob'); + +/** + * Determine if a value is a FileList + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFileList = kindOfTest('FileList'); + +/** + * Determine if a value is a Stream + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Stream, otherwise false + */ +const isStream = (val) => isObject(val) && isFunction$1(val.pipe); + +/** + * Determine if a value is a FormData + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an FormData, otherwise false + */ +const isFormData = (thing) => { + let kind; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || ( + isFunction$1(thing.append) && ( + (kind = kindOf(thing)) === 'formdata' || + // detect form-data instance + (kind === 'object' && isFunction$1(thing.toString) && thing.toString() === '[object FormData]') + ) + ) + ) +}; + +/** + * Determine if a value is a URLSearchParams object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +const isURLSearchParams = kindOfTest('URLSearchParams'); + +const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest); + +/** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * + * @returns {String} The String freed of excess whitespace + */ +const trim = (str) => str.trim ? + str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + * + * @param {Boolean} [allOwnKeys = false] + * @returns {any} + */ +function forEach(obj, fn, {allOwnKeys = false} = {}) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + + let i; + let l; + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + + if (isArray(obj)) { + // Iterate over array values + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Buffer check + if (isBuffer(obj)) { + return; + } + + // Iterate over object keys + const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + const len = keys.length; + let key; + + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } +} + +function findKey(obj, key) { + if (isBuffer(obj)){ + return null; + } + + key = key.toLowerCase(); + const keys = Object.keys(obj); + let i = keys.length; + let _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; +} + +const _global = (() => { + /*eslint no-undef:0*/ + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : global) +})(); + +const isContextDefined = (context) => !isUndefined(context) && context !== _global; + +/** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * + * @returns {Object} Result of all merge properties + */ +function merge(/* obj1, obj2, obj3, ... */) { + const {caseless, skipUndefined} = isContextDefined(this) && this || {}; + const result = {}; + const assignValue = (val, key) => { + const targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + }; + + for (let i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * + * @param {Boolean} [allOwnKeys] + * @returns {Object} The resulting value of object a + */ +const extend = (a, b, thisArg, {allOwnKeys}= {}) => { + forEach(b, (val, key) => { + if (thisArg && isFunction$1(val)) { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }, {allOwnKeys}); + return a; +}; + +/** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * + * @returns {string} content value without BOM + */ +const stripBOM = (content) => { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; +}; + +/** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + * + * @returns {void} + */ +const inherits = (constructor, superConstructor, props, descriptors) => { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + Object.defineProperty(constructor, 'super', { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); +}; + +/** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function|Boolean} [filter] + * @param {Function} [propFilter] + * + * @returns {Object} + */ +const toFlatObject = (sourceObj, destObj, filter, propFilter) => { + let props; + let i; + let prop; + const merged = {}; + + destObj = destObj || {}; + // eslint-disable-next-line no-eq-null,eqeqeq + if (sourceObj == null) return destObj; + + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + + return destObj; +}; + +/** + * Determines whether a string ends with the characters of a specified string + * + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * + * @returns {boolean} + */ +const endsWith = (str, searchString, position) => { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + const lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; +}; + + +/** + * Returns new array from array like object or null if failed + * + * @param {*} [thing] + * + * @returns {?Array} + */ +const toArray = (thing) => { + if (!thing) return null; + if (isArray(thing)) return thing; + let i = thing.length; + if (!isNumber(i)) return null; + const arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; +}; + +/** + * Checking if the Uint8Array exists and if it does, it returns a function that checks if the + * thing passed in is an instance of Uint8Array + * + * @param {TypedArray} + * + * @returns {Array} + */ +// eslint-disable-next-line func-names +const isTypedArray = (TypedArray => { + // eslint-disable-next-line func-names + return thing => { + return TypedArray && thing instanceof TypedArray; + }; +})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); + +/** + * For each entry in the object, call the function with the key and value. + * + * @param {Object} obj - The object to iterate over. + * @param {Function} fn - The function to call for each entry. + * + * @returns {void} + */ +const forEachEntry = (obj, fn) => { + const generator = obj && obj[iterator]; + + const _iterator = generator.call(obj); + + let result; + + while ((result = _iterator.next()) && !result.done) { + const pair = result.value; + fn.call(obj, pair[0], pair[1]); + } +}; + +/** + * It takes a regular expression and a string, and returns an array of all the matches + * + * @param {string} regExp - The regular expression to match against. + * @param {string} str - The string to search. + * + * @returns {Array} + */ +const matchAll = (regExp, str) => { + let matches; + const arr = []; + + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + + return arr; +}; + +/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ +const isHTMLForm = kindOfTest('HTMLFormElement'); + +const toCamelCase = str => { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, + function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + } + ); +}; + +/* Creating a function that will check if an object has a property. */ +const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype); + +/** + * Determine if a value is a RegExp object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a RegExp object, otherwise false + */ +const isRegExp = kindOfTest('RegExp'); + +const reduceDescriptors = (obj, reducer) => { + const descriptors = Object.getOwnPropertyDescriptors(obj); + const reducedDescriptors = {}; + + forEach(descriptors, (descriptor, name) => { + let ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + + Object.defineProperties(obj, reducedDescriptors); +}; + +/** + * Makes all methods read-only + * @param {Object} obj + */ + +const freezeMethods = (obj) => { + reduceDescriptors(obj, (descriptor, name) => { + // skip restricted props in strict mode + if (isFunction$1(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { + return false; + } + + const value = obj[name]; + + if (!isFunction$1(value)) return; + + descriptor.enumerable = false; + + if ('writable' in descriptor) { + descriptor.writable = false; + return; + } + + if (!descriptor.set) { + descriptor.set = () => { + throw Error('Can not rewrite read-only method \'' + name + '\''); + }; + } + }); +}; + +const toObjectSet = (arrayOrString, delimiter) => { + const obj = {}; + + const define = (arr) => { + arr.forEach(value => { + obj[value] = true; + }); + }; + + isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); + + return obj; +}; + +const noop = () => {}; + +const toFiniteNumber = (value, defaultValue) => { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; +}; + + + +/** + * If the thing is a FormData object, return true, otherwise return false. + * + * @param {unknown} thing - The thing to check. + * + * @returns {boolean} + */ +function isSpecCompliantForm(thing) { + return !!(thing && isFunction$1(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); +} + +const toJSONObject = (obj) => { + const stack = new Array(10); + + const visit = (source, i) => { + + if (isObject(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + + //Buffer check + if (isBuffer(source)) { + return source; + } + + if(!('toJSON' in source)) { + stack[i] = source; + const target = isArray(source) ? [] : {}; + + forEach(source, (value, key) => { + const reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + + stack[i] = undefined; + + return target; + } + } + + return source; + }; + + return visit(obj, 0); +}; + +const isAsyncFn = kindOfTest('AsyncFunction'); + +const isThenable = (thing) => + thing && (isObject(thing) || isFunction$1(thing)) && isFunction$1(thing.then) && isFunction$1(thing.catch); + +// original code +// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 + +const _setImmediate = ((setImmediateSupported, postMessageSupported) => { + if (setImmediateSupported) { + return setImmediate; + } + + return postMessageSupported ? ((token, callbacks) => { + _global.addEventListener("message", ({source, data}) => { + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + + return (cb) => { + callbacks.push(cb); + _global.postMessage(token, "*"); + } + })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); +})( + typeof setImmediate === 'function', + isFunction$1(_global.postMessage) +); + +const asap = typeof queueMicrotask !== 'undefined' ? + queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate); + +// ********************* + + +const isIterable = (thing) => thing != null && isFunction$1(thing[iterator]); + + +const utils$1 = { + isArray, + isArrayBuffer, + isBuffer, + isFormData, + isArrayBufferView, + isString, + isNumber, + isBoolean, + isObject, + isPlainObject, + isEmptyObject, + isReadableStream, + isRequest, + isResponse, + isHeaders, + isUndefined, + isDate, + isFile, + isBlob, + isRegExp, + isFunction: isFunction$1, + isStream, + isURLSearchParams, + isTypedArray, + isFileList, + forEach, + merge, + extend, + trim, + stripBOM, + inherits, + toFlatObject, + kindOf, + kindOfTest, + endsWith, + toArray, + forEachEntry, + matchAll, + isHTMLForm, + hasOwnProperty, + hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors, + freezeMethods, + toObjectSet, + toCamelCase, + noop, + toFiniteNumber, + findKey, + global: _global, + isContextDefined, + isSpecCompliantForm, + toJSONObject, + isAsyncFn, + isThenable, + setImmediate: _setImmediate, + asap, + isIterable +}; + +/** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ +function AxiosError(message, code, config, request, response) { + Error.call(this); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = (new Error()).stack; + } + + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status ? response.status : null; + } +} + +utils$1.inherits(AxiosError, Error, { + toJSON: function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils$1.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } +}); + +const prototype$1 = AxiosError.prototype; +const descriptors = {}; + +[ + 'ERR_BAD_OPTION_VALUE', + 'ERR_BAD_OPTION', + 'ECONNABORTED', + 'ETIMEDOUT', + 'ERR_NETWORK', + 'ERR_FR_TOO_MANY_REDIRECTS', + 'ERR_DEPRECATED', + 'ERR_BAD_RESPONSE', + 'ERR_BAD_REQUEST', + 'ERR_CANCELED', + 'ERR_NOT_SUPPORT', + 'ERR_INVALID_URL' +// eslint-disable-next-line func-names +].forEach(code => { + descriptors[code] = {value: code}; +}); + +Object.defineProperties(AxiosError, descriptors); +Object.defineProperty(prototype$1, 'isAxiosError', {value: true}); + +// eslint-disable-next-line func-names +AxiosError.from = (error, code, config, request, response, customProps) => { + const axiosError = Object.create(prototype$1); + + utils$1.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }, prop => { + return prop !== 'isAxiosError'; + }); + + const msg = error && error.message ? error.message : 'Error'; + + // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED) + const errCode = code == null && error ? error.code : code; + AxiosError.call(axiosError, msg, errCode, config, request, response); + + // Chain the original error on the standard field; non-enumerable to avoid JSON noise + if (error && axiosError.cause == null) { + Object.defineProperty(axiosError, 'cause', { value: error, configurable: true }); + } + + axiosError.name = (error && error.name) || 'Error'; + + customProps && Object.assign(axiosError, customProps); + + return axiosError; +}; + +/** + * Determines if the given thing is a array or js object. + * + * @param {string} thing - The object or array to be visited. + * + * @returns {boolean} + */ +function isVisitable(thing) { + return utils$1.isPlainObject(thing) || utils$1.isArray(thing); +} + +/** + * It removes the brackets from the end of a string + * + * @param {string} key - The key of the parameter. + * + * @returns {string} the key without the brackets. + */ +function removeBrackets(key) { + return utils$1.endsWith(key, '[]') ? key.slice(0, -2) : key; +} + +/** + * It takes a path, a key, and a boolean, and returns a string + * + * @param {string} path - The path to the current key. + * @param {string} key - The key of the current object being iterated over. + * @param {string} dots - If true, the key will be rendered with dots instead of brackets. + * + * @returns {string} The path to the current key. + */ +function renderKey(path, key, dots) { + if (!path) return key; + return path.concat(key).map(function each(token, i) { + // eslint-disable-next-line no-param-reassign + token = removeBrackets(token); + return !dots && i ? '[' + token + ']' : token; + }).join(dots ? '.' : ''); +} + +/** + * If the array is an array and none of its elements are visitable, then it's a flat array. + * + * @param {Array} arr - The array to check + * + * @returns {boolean} + */ +function isFlatArray(arr) { + return utils$1.isArray(arr) && !arr.some(isVisitable); +} + +const predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); +}); + +/** + * Convert a data object to FormData + * + * @param {Object} obj + * @param {?Object} [formData] + * @param {?Object} [options] + * @param {Function} [options.visitor] + * @param {Boolean} [options.metaTokens = true] + * @param {Boolean} [options.dots = false] + * @param {?Boolean} [options.indexes = false] + * + * @returns {Object} + **/ + +/** + * It converts an object into a FormData object + * + * @param {Object} obj - The object to convert to form data. + * @param {string} formData - The FormData object to append to. + * @param {Object} options + * + * @returns + */ +function toFormData(obj, formData, options) { + if (!utils$1.isObject(obj)) { + throw new TypeError('target must be an object'); + } + + // eslint-disable-next-line no-param-reassign + formData = formData || new (FormData__default["default"] || FormData)(); + + // eslint-disable-next-line no-param-reassign + options = utils$1.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + // eslint-disable-next-line no-eq-null,eqeqeq + return !utils$1.isUndefined(source[option]); + }); + + const metaTokens = options.metaTokens; + // eslint-disable-next-line no-use-before-define + const visitor = options.visitor || defaultVisitor; + const dots = options.dots; + const indexes = options.indexes; + const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob; + const useBlob = _Blob && utils$1.isSpecCompliantForm(formData); + + if (!utils$1.isFunction(visitor)) { + throw new TypeError('visitor must be a function'); + } + + function convertValue(value) { + if (value === null) return ''; + + if (utils$1.isDate(value)) { + return value.toISOString(); + } + + if (utils$1.isBoolean(value)) { + return value.toString(); + } + + if (!useBlob && utils$1.isBlob(value)) { + throw new AxiosError('Blob is not supported. Use a Buffer instead.'); + } + + if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) { + return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + + return value; + } + + /** + * Default visitor. + * + * @param {*} value + * @param {String|Number} key + * @param {Array} path + * @this {FormData} + * + * @returns {boolean} return true to visit the each prop of the value recursively + */ + function defaultVisitor(value, key, path) { + let arr = value; + + if (value && !path && typeof value === 'object') { + if (utils$1.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + key = metaTokens ? key : key.slice(0, -2); + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if ( + (utils$1.isArray(value) && isFlatArray(value)) || + ((utils$1.isFileList(value) || utils$1.endsWith(key, '[]')) && (arr = utils$1.toArray(value)) + )) { + // eslint-disable-next-line no-param-reassign + key = removeBrackets(key); + + arr.forEach(function each(el, index) { + !(utils$1.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'), + convertValue(el) + ); + }); + return false; + } + } + + if (isVisitable(value)) { + return true; + } + + formData.append(renderKey(path, key, dots), convertValue(value)); + + return false; + } + + const stack = []; + + const exposedHelpers = Object.assign(predicates, { + defaultVisitor, + convertValue, + isVisitable + }); + + function build(value, path) { + if (utils$1.isUndefined(value)) return; + + if (stack.indexOf(value) !== -1) { + throw Error('Circular reference detected in ' + path.join('.')); + } + + stack.push(value); + + utils$1.forEach(value, function each(el, key) { + const result = !(utils$1.isUndefined(el) || el === null) && visitor.call( + formData, el, utils$1.isString(key) ? key.trim() : key, path, exposedHelpers + ); + + if (result === true) { + build(el, path ? path.concat(key) : [key]); + } + }); + + stack.pop(); + } + + if (!utils$1.isObject(obj)) { + throw new TypeError('data must be an object'); + } + + build(obj); + + return formData; +} + +/** + * It encodes a string by replacing all characters that are not in the unreserved set with + * their percent-encoded equivalents + * + * @param {string} str - The string to encode. + * + * @returns {string} The encoded string. + */ +function encode$1(str) { + const charMap = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); +} + +/** + * It takes a params object and converts it to a FormData object + * + * @param {Object} params - The parameters to be converted to a FormData object. + * @param {Object} options - The options object passed to the Axios constructor. + * + * @returns {void} + */ +function AxiosURLSearchParams(params, options) { + this._pairs = []; + + params && toFormData(params, this, options); +} + +const prototype = AxiosURLSearchParams.prototype; + +prototype.append = function append(name, value) { + this._pairs.push([name, value]); +}; + +prototype.toString = function toString(encoder) { + const _encode = encoder ? function(value) { + return encoder.call(this, value, encode$1); + } : encode$1; + + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + '=' + _encode(pair[1]); + }, '').join('&'); +}; + +/** + * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their + * URI encoded counterparts + * + * @param {string} val The value to be encoded. + * + * @returns {string} The encoded value. + */ +function encode(val) { + return encodeURIComponent(val). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'); +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @param {?(object|Function)} options + * + * @returns {string} The formatted url + */ +function buildURL(url, params, options) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + + const _encode = options && options.encode || encode; + + if (utils$1.isFunction(options)) { + options = { + serialize: options + }; + } + + const serializeFn = options && options.serialize; + + let serializedParams; + + if (serializeFn) { + serializedParams = serializeFn(params, options); + } else { + serializedParams = utils$1.isURLSearchParams(params) ? + params.toString() : + new AxiosURLSearchParams(params, options).toString(_encode); + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf("#"); + + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + + return url; +} + +class InterceptorManager { + constructor() { + this.handlers = []; + } + + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ + use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled, + rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise + */ + eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + clear() { + if (this.handlers) { + this.handlers = []; + } + } + + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + forEach(fn) { + utils$1.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } +} + +const InterceptorManager$1 = InterceptorManager; + +const transitionalDefaults = { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false +}; + +const URLSearchParams = url__default["default"].URLSearchParams; + +const ALPHA = 'abcdefghijklmnopqrstuvwxyz'; + +const DIGIT = '0123456789'; + +const ALPHABET = { + DIGIT, + ALPHA, + ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT +}; + +const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => { + let str = ''; + const {length} = alphabet; + const randomValues = new Uint32Array(size); + crypto__default["default"].randomFillSync(randomValues); + for (let i = 0; i < size; i++) { + str += alphabet[randomValues[i] % length]; + } + + return str; +}; + + +const platform$1 = { + isNode: true, + classes: { + URLSearchParams, + FormData: FormData__default["default"], + Blob: typeof Blob !== 'undefined' && Blob || null + }, + ALPHABET, + generateString, + protocols: [ 'http', 'https', 'file', 'data' ] +}; + +const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; + +const _navigator = typeof navigator === 'object' && navigator || undefined; + +/** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + * + * @returns {boolean} + */ +const hasStandardBrowserEnv = hasBrowserEnv && + (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); + +/** + * Determine if we're running in a standard browser webWorker environment + * + * Although the `isStandardBrowserEnv` method indicates that + * `allows axios to run in a web worker`, the WebWorker will still be + * filtered out due to its judgment standard + * `typeof window !== 'undefined' && typeof document !== 'undefined'`. + * This leads to a problem when axios post `FormData` in webWorker + */ +const hasStandardBrowserWebWorkerEnv = (() => { + return ( + typeof WorkerGlobalScope !== 'undefined' && + // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && + typeof self.importScripts === 'function' + ); +})(); + +const origin = hasBrowserEnv && window.location.href || 'http://localhost'; + +const utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + hasBrowserEnv: hasBrowserEnv, + hasStandardBrowserWebWorkerEnv: hasStandardBrowserWebWorkerEnv, + hasStandardBrowserEnv: hasStandardBrowserEnv, + navigator: _navigator, + origin: origin +}); + +const platform = { + ...utils, + ...platform$1 +}; + +function toURLEncodedForm(data, options) { + return toFormData(data, new platform.classes.URLSearchParams(), { + visitor: function(value, key, path, helpers) { + if (platform.isNode && utils$1.isBuffer(value)) { + this.append(key, value.toString('base64')); + return false; + } + + return helpers.defaultVisitor.apply(this, arguments); + }, + ...options + }); +} + +/** + * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] + * + * @param {string} name - The name of the property to get. + * + * @returns An array of strings. + */ +function parsePropPath(name) { + // foo[x][y][z] + // foo.x.y.z + // foo-x-y-z + // foo x y z + return utils$1.matchAll(/\w+|\[(\w*)]/g, name).map(match => { + return match[0] === '[]' ? '' : match[1] || match[0]; + }); +} + +/** + * Convert an array to an object. + * + * @param {Array} arr - The array to convert to an object. + * + * @returns An object with the same keys and values as the array. + */ +function arrayToObject(arr) { + const obj = {}; + const keys = Object.keys(arr); + let i; + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; +} + +/** + * It takes a FormData object and returns a JavaScript object + * + * @param {string} formData The FormData object to convert to JSON. + * + * @returns {Object | null} The converted object. + */ +function formDataToJSON(formData) { + function buildPath(path, value, target, index) { + let name = path[index++]; + + if (name === '__proto__') return true; + + const isNumericKey = Number.isFinite(+name); + const isLast = index >= path.length; + name = !name && utils$1.isArray(target) ? target.length : name; + + if (isLast) { + if (utils$1.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + + return !isNumericKey; + } + + if (!target[name] || !utils$1.isObject(target[name])) { + target[name] = []; + } + + const result = buildPath(path, value, target[name], index); + + if (result && utils$1.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + + return !isNumericKey; + } + + if (utils$1.isFormData(formData) && utils$1.isFunction(formData.entries)) { + const obj = {}; + + utils$1.forEachEntry(formData, (name, value) => { + buildPath(parsePropPath(name), value, obj, 0); + }); + + return obj; + } + + return null; +} + +/** + * It takes a string, tries to parse it, and if it fails, it returns the stringified version + * of the input + * + * @param {any} rawValue - The value to be stringified. + * @param {Function} parser - A function that parses a string into a JavaScript object. + * @param {Function} encoder - A function that takes a value and returns a string. + * + * @returns {string} A stringified version of the rawValue. + */ +function stringifySafely(rawValue, parser, encoder) { + if (utils$1.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils$1.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + + return (encoder || JSON.stringify)(rawValue); +} + +const defaults = { + + transitional: transitionalDefaults, + + adapter: ['xhr', 'http', 'fetch'], + + transformRequest: [function transformRequest(data, headers) { + const contentType = headers.getContentType() || ''; + const hasJSONContentType = contentType.indexOf('application/json') > -1; + const isObjectPayload = utils$1.isObject(data); + + if (isObjectPayload && utils$1.isHTMLForm(data)) { + data = new FormData(data); + } + + const isFormData = utils$1.isFormData(data); + + if (isFormData) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + + if (utils$1.isArrayBuffer(data) || + utils$1.isBuffer(data) || + utils$1.isStream(data) || + utils$1.isFile(data) || + utils$1.isBlob(data) || + utils$1.isReadableStream(data) + ) { + return data; + } + if (utils$1.isArrayBufferView(data)) { + return data.buffer; + } + if (utils$1.isURLSearchParams(data)) { + headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); + return data.toString(); + } + + let isFileList; + + if (isObjectPayload) { + if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + + if ((isFileList = utils$1.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) { + const _FormData = this.env && this.env.FormData; + + return toFormData( + isFileList ? {'files[]': data} : data, + _FormData && new _FormData(), + this.formSerializer + ); + } + } + + if (isObjectPayload || hasJSONContentType ) { + headers.setContentType('application/json', false); + return stringifySafely(data); + } + + return data; + }], + + transformResponse: [function transformResponse(data) { + const transitional = this.transitional || defaults.transitional; + const forcedJSONParsing = transitional && transitional.forcedJSONParsing; + const JSONRequested = this.responseType === 'json'; + + if (utils$1.isResponse(data) || utils$1.isReadableStream(data)) { + return data; + } + + if (data && utils$1.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { + const silentJSONParsing = transitional && transitional.silentJSONParsing; + const strictJSONParsing = !silentJSONParsing && JSONRequested; + + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + + return data; + }], + + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + maxContentLength: -1, + maxBodyLength: -1, + + env: { + FormData: platform.classes.FormData, + Blob: platform.classes.Blob + }, + + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': undefined + } + } +}; + +utils$1.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => { + defaults.headers[method] = {}; +}); + +const defaults$1 = defaults; + +// RawAxiosHeaders whose duplicates are ignored by node +// c.f. https://nodejs.org/api/http.html#http_message_headers +const ignoreDuplicateOf = utils$1.toObjectSet([ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' +]); + +/** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} rawHeaders Headers needing to be parsed + * + * @returns {Object} Headers parsed into an object + */ +const parseHeaders = rawHeaders => { + const parsed = {}; + let key; + let val; + let i; + + rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { + i = line.indexOf(':'); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + + if (!key || (parsed[key] && ignoreDuplicateOf[key])) { + return; + } + + if (key === 'set-cookie') { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + }); + + return parsed; +}; + +const $internals = Symbol('internals'); + +function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); +} + +function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + + return utils$1.isArray(value) ? value.map(normalizeValue) : String(value); +} + +function parseTokens(str) { + const tokens = Object.create(null); + const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + let match; + + while ((match = tokensRE.exec(str))) { + tokens[match[1]] = match[2]; + } + + return tokens; +} + +const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + +function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils$1.isFunction(filter)) { + return filter.call(this, value, header); + } + + if (isHeaderNameFilter) { + value = header; + } + + if (!utils$1.isString(value)) return; + + if (utils$1.isString(filter)) { + return value.indexOf(filter) !== -1; + } + + if (utils$1.isRegExp(filter)) { + return filter.test(value); + } +} + +function formatHeader(header) { + return header.trim() + .toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { + return char.toUpperCase() + str; + }); +} + +function buildAccessors(obj, header) { + const accessorName = utils$1.toCamelCase(' ' + header); + + ['get', 'set', 'has'].forEach(methodName => { + Object.defineProperty(obj, methodName + accessorName, { + value: function(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); +} + +class AxiosHeaders { + constructor(headers) { + headers && this.set(headers); + } + + set(header, valueOrRewrite, rewrite) { + const self = this; + + function setHeader(_value, _header, _rewrite) { + const lHeader = normalizeHeader(_header); + + if (!lHeader) { + throw new Error('header name must be a non-empty string'); + } + + const key = utils$1.findKey(self, lHeader); + + if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) { + self[key || _header] = normalizeValue(_value); + } + } + + const setHeaders = (headers, _rewrite) => + utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); + + if (utils$1.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite); + } else if(utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils$1.isObject(header) && utils$1.isIterable(header)) { + let obj = {}, dest, key; + for (const entry of header) { + if (!utils$1.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + + obj[key = entry[0]] = (dest = obj[key]) ? + (utils$1.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1]; + } + + setHeaders(obj, valueOrRewrite); + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + + return this; + } + + get(header, parser) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + if (key) { + const value = this[key]; + + if (!parser) { + return value; + } + + if (parser === true) { + return parseTokens(value); + } + + if (utils$1.isFunction(parser)) { + return parser.call(this, value, key); + } + + if (utils$1.isRegExp(parser)) { + return parser.exec(value); + } + + throw new TypeError('parser must be boolean|regexp|function'); + } + } + } + + has(header, matcher) { + header = normalizeHeader(header); + + if (header) { + const key = utils$1.findKey(this, header); + + return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + + return false; + } + + delete(header, matcher) { + const self = this; + let deleted = false; + + function deleteHeader(_header) { + _header = normalizeHeader(_header); + + if (_header) { + const key = utils$1.findKey(self, _header); + + if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { + delete self[key]; + + deleted = true; + } + } + } + + if (utils$1.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + + return deleted; + } + + clear(matcher) { + const keys = Object.keys(this); + let i = keys.length; + let deleted = false; + + while (i--) { + const key = keys[i]; + if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + + return deleted; + } + + normalize(format) { + const self = this; + const headers = {}; + + utils$1.forEach(this, (value, header) => { + const key = utils$1.findKey(headers, header); + + if (key) { + self[key] = normalizeValue(value); + delete self[header]; + return; + } + + const normalized = format ? formatHeader(header) : String(header).trim(); + + if (normalized !== header) { + delete self[header]; + } + + self[normalized] = normalizeValue(value); + + headers[normalized] = true; + }); + + return this; + } + + concat(...targets) { + return this.constructor.concat(this, ...targets); + } + + toJSON(asStrings) { + const obj = Object.create(null); + + utils$1.forEach(this, (value, header) => { + value != null && value !== false && (obj[header] = asStrings && utils$1.isArray(value) ? value.join(', ') : value); + }); + + return obj; + } + + [Symbol.iterator]() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + + toString() { + return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n'); + } + + getSetCookie() { + return this.get("set-cookie") || []; + } + + get [Symbol.toStringTag]() { + return 'AxiosHeaders'; + } + + static from(thing) { + return thing instanceof this ? thing : new this(thing); + } + + static concat(first, ...targets) { + const computed = new this(first); + + targets.forEach((target) => computed.set(target)); + + return computed; + } + + static accessor(header) { + const internals = this[$internals] = (this[$internals] = { + accessors: {} + }); + + const accessors = internals.accessors; + const prototype = this.prototype; + + function defineAccessor(_header) { + const lHeader = normalizeHeader(_header); + + if (!accessors[lHeader]) { + buildAccessors(prototype, _header); + accessors[lHeader] = true; + } + } + + utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + + return this; + } +} + +AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); + +// reserved names hotfix +utils$1.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => { + let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` + return { + get: () => value, + set(headerValue) { + this[mapped] = headerValue; + } + } +}); + +utils$1.freezeMethods(AxiosHeaders); + +const AxiosHeaders$1 = AxiosHeaders; + +/** + * Transform the data for a request or a response + * + * @param {Array|Function} fns A single function or Array of functions + * @param {?Object} response The response object + * + * @returns {*} The resulting transformed data + */ +function transformData(fns, response) { + const config = this || defaults$1; + const context = response || config; + const headers = AxiosHeaders$1.from(context.headers); + let data = context.data; + + utils$1.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); + }); + + headers.normalize(); + + return data; +} + +function isCancel(value) { + return !!(value && value.__CANCEL__); +} + +/** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ +function CanceledError(message, config, request) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); + this.name = 'CanceledError'; +} + +utils$1.inherits(CanceledError, AxiosError, { + __CANCEL__: true +}); + +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + * + * @returns {object} The response. + */ +function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError( + 'Request failed with status code ' + response.status, + [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], + response.config, + response.request, + response + )); + } +} + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); +} + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * + * @returns {string} The combined URL + */ +function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; +} + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * + * @returns {string} The combined full path + */ +function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + let isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; +} + +const VERSION = "1.12.2"; + +function parseProtocol(url) { + const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; +} + +const DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/; + +/** + * Parse data uri to a Buffer or Blob + * + * @param {String} uri + * @param {?Boolean} asBlob + * @param {?Object} options + * @param {?Function} options.Blob + * + * @returns {Buffer|Blob} + */ +function fromDataURI(uri, asBlob, options) { + const _Blob = options && options.Blob || platform.classes.Blob; + const protocol = parseProtocol(uri); + + if (asBlob === undefined && _Blob) { + asBlob = true; + } + + if (protocol === 'data') { + uri = protocol.length ? uri.slice(protocol.length + 1) : uri; + + const match = DATA_URL_PATTERN.exec(uri); + + if (!match) { + throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL); + } + + const mime = match[1]; + const isBase64 = match[2]; + const body = match[3]; + const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8'); + + if (asBlob) { + if (!_Blob) { + throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT); + } + + return new _Blob([buffer], {type: mime}); + } + + return buffer; + } + + throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT); +} + +const kInternals = Symbol('internals'); + +class AxiosTransformStream extends stream__default["default"].Transform{ + constructor(options) { + options = utils$1.toFlatObject(options, { + maxRate: 0, + chunkSize: 64 * 1024, + minChunkSize: 100, + timeWindow: 500, + ticksRate: 2, + samplesCount: 15 + }, null, (prop, source) => { + return !utils$1.isUndefined(source[prop]); + }); + + super({ + readableHighWaterMark: options.chunkSize + }); + + const internals = this[kInternals] = { + timeWindow: options.timeWindow, + chunkSize: options.chunkSize, + maxRate: options.maxRate, + minChunkSize: options.minChunkSize, + bytesSeen: 0, + isCaptured: false, + notifiedBytesLoaded: 0, + ts: Date.now(), + bytes: 0, + onReadCallback: null + }; + + this.on('newListener', event => { + if (event === 'progress') { + if (!internals.isCaptured) { + internals.isCaptured = true; + } + } + }); + } + + _read(size) { + const internals = this[kInternals]; + + if (internals.onReadCallback) { + internals.onReadCallback(); + } + + return super._read(size); + } + + _transform(chunk, encoding, callback) { + const internals = this[kInternals]; + const maxRate = internals.maxRate; + + const readableHighWaterMark = this.readableHighWaterMark; + + const timeWindow = internals.timeWindow; + + const divider = 1000 / timeWindow; + const bytesThreshold = (maxRate / divider); + const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0; + + const pushChunk = (_chunk, _callback) => { + const bytes = Buffer.byteLength(_chunk); + internals.bytesSeen += bytes; + internals.bytes += bytes; + + internals.isCaptured && this.emit('progress', internals.bytesSeen); + + if (this.push(_chunk)) { + process.nextTick(_callback); + } else { + internals.onReadCallback = () => { + internals.onReadCallback = null; + process.nextTick(_callback); + }; + } + }; + + const transformChunk = (_chunk, _callback) => { + const chunkSize = Buffer.byteLength(_chunk); + let chunkRemainder = null; + let maxChunkSize = readableHighWaterMark; + let bytesLeft; + let passed = 0; + + if (maxRate) { + const now = Date.now(); + + if (!internals.ts || (passed = (now - internals.ts)) >= timeWindow) { + internals.ts = now; + bytesLeft = bytesThreshold - internals.bytes; + internals.bytes = bytesLeft < 0 ? -bytesLeft : 0; + passed = 0; + } + + bytesLeft = bytesThreshold - internals.bytes; + } + + if (maxRate) { + if (bytesLeft <= 0) { + // next time window + return setTimeout(() => { + _callback(null, _chunk); + }, timeWindow - passed); + } + + if (bytesLeft < maxChunkSize) { + maxChunkSize = bytesLeft; + } + } + + if (maxChunkSize && chunkSize > maxChunkSize && (chunkSize - maxChunkSize) > minChunkSize) { + chunkRemainder = _chunk.subarray(maxChunkSize); + _chunk = _chunk.subarray(0, maxChunkSize); + } + + pushChunk(_chunk, chunkRemainder ? () => { + process.nextTick(_callback, null, chunkRemainder); + } : _callback); + }; + + transformChunk(chunk, function transformNextChunk(err, _chunk) { + if (err) { + return callback(err); + } + + if (_chunk) { + transformChunk(_chunk, transformNextChunk); + } else { + callback(null); + } + }); + } +} + +const AxiosTransformStream$1 = AxiosTransformStream; + +const {asyncIterator} = Symbol; + +const readBlob = async function* (blob) { + if (blob.stream) { + yield* blob.stream(); + } else if (blob.arrayBuffer) { + yield await blob.arrayBuffer(); + } else if (blob[asyncIterator]) { + yield* blob[asyncIterator](); + } else { + yield blob; + } +}; + +const readBlob$1 = readBlob; + +const BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_'; + +const textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util__default["default"].TextEncoder(); + +const CRLF = '\r\n'; +const CRLF_BYTES = textEncoder.encode(CRLF); +const CRLF_BYTES_COUNT = 2; + +class FormDataPart { + constructor(name, value) { + const {escapeName} = this.constructor; + const isStringValue = utils$1.isString(value); + + let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${ + !isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : '' + }${CRLF}`; + + if (isStringValue) { + value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF)); + } else { + headers += `Content-Type: ${value.type || "application/octet-stream"}${CRLF}`; + } + + this.headers = textEncoder.encode(headers + CRLF); + + this.contentLength = isStringValue ? value.byteLength : value.size; + + this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT; + + this.name = name; + this.value = value; + } + + async *encode(){ + yield this.headers; + + const {value} = this; + + if(utils$1.isTypedArray(value)) { + yield value; + } else { + yield* readBlob$1(value); + } + + yield CRLF_BYTES; + } + + static escapeName(name) { + return String(name).replace(/[\r\n"]/g, (match) => ({ + '\r' : '%0D', + '\n' : '%0A', + '"' : '%22', + }[match])); + } +} + +const formDataToStream = (form, headersHandler, options) => { + const { + tag = 'form-data-boundary', + size = 25, + boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET) + } = options || {}; + + if(!utils$1.isFormData(form)) { + throw TypeError('FormData instance required'); + } + + if (boundary.length < 1 || boundary.length > 70) { + throw Error('boundary must be 10-70 characters long') + } + + const boundaryBytes = textEncoder.encode('--' + boundary + CRLF); + const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF); + let contentLength = footerBytes.byteLength; + + const parts = Array.from(form.entries()).map(([name, value]) => { + const part = new FormDataPart(name, value); + contentLength += part.size; + return part; + }); + + contentLength += boundaryBytes.byteLength * parts.length; + + contentLength = utils$1.toFiniteNumber(contentLength); + + const computedHeaders = { + 'Content-Type': `multipart/form-data; boundary=${boundary}` + }; + + if (Number.isFinite(contentLength)) { + computedHeaders['Content-Length'] = contentLength; + } + + headersHandler && headersHandler(computedHeaders); + + return stream.Readable.from((async function *() { + for(const part of parts) { + yield boundaryBytes; + yield* part.encode(); + } + + yield footerBytes; + })()); +}; + +const formDataToStream$1 = formDataToStream; + +class ZlibHeaderTransformStream extends stream__default["default"].Transform { + __transform(chunk, encoding, callback) { + this.push(chunk); + callback(); + } + + _transform(chunk, encoding, callback) { + if (chunk.length !== 0) { + this._transform = this.__transform; + + // Add Default Compression headers if no zlib headers are present + if (chunk[0] !== 120) { // Hex: 78 + const header = Buffer.alloc(2); + header[0] = 120; // Hex: 78 + header[1] = 156; // Hex: 9C + this.push(header, encoding); + } + } + + this.__transform(chunk, encoding, callback); + } +} + +const ZlibHeaderTransformStream$1 = ZlibHeaderTransformStream; + +const callbackify = (fn, reducer) => { + return utils$1.isAsyncFn(fn) ? function (...args) { + const cb = args.pop(); + fn.apply(this, args).then((value) => { + try { + reducer ? cb(null, ...reducer(value)) : cb(null, value); + } catch (err) { + cb(err); + } + }, cb); + } : fn; +}; + +const callbackify$1 = callbackify; + +/** + * Calculate data maxRate + * @param {Number} [samplesCount= 10] + * @param {Number} [min= 1000] + * @returns {Function} + */ +function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + const bytes = new Array(samplesCount); + const timestamps = new Array(samplesCount); + let head = 0; + let tail = 0; + let firstSampleTS; + + min = min !== undefined ? min : 1000; + + return function push(chunkLength) { + const now = Date.now(); + + const startedAt = timestamps[tail]; + + if (!firstSampleTS) { + firstSampleTS = now; + } + + bytes[head] = chunkLength; + timestamps[head] = now; + + let i = tail; + let bytesCount = 0; + + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + + head = (head + 1) % samplesCount; + + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + + if (now - firstSampleTS < min) { + return; + } + + const passed = startedAt && now - startedAt; + + return passed ? Math.round(bytesCount * 1000 / passed) : undefined; + }; +} + +/** + * Throttle decorator + * @param {Function} fn + * @param {Number} freq + * @return {Function} + */ +function throttle(fn, freq) { + let timestamp = 0; + let threshold = 1000 / freq; + let lastArgs; + let timer; + + const invoke = (args, now = Date.now()) => { + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn(...args); + }; + + const throttled = (...args) => { + const now = Date.now(); + const passed = now - timestamp; + if ( passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(() => { + timer = null; + invoke(lastArgs); + }, threshold - passed); + } + } + }; + + const flush = () => lastArgs && invoke(lastArgs); + + return [throttled, flush]; +} + +const progressEventReducer = (listener, isDownloadStream, freq = 3) => { + let bytesNotified = 0; + const _speedometer = speedometer(50, 250); + + return throttle(e => { + const loaded = e.loaded; + const total = e.lengthComputable ? e.total : undefined; + const progressBytes = loaded - bytesNotified; + const rate = _speedometer(progressBytes); + const inRange = loaded <= total; + + bytesNotified = loaded; + + const data = { + loaded, + total, + progress: total ? (loaded / total) : undefined, + bytes: progressBytes, + rate: rate ? rate : undefined, + estimated: rate && total && inRange ? (total - loaded) / rate : undefined, + event: e, + lengthComputable: total != null, + [isDownloadStream ? 'download' : 'upload']: true + }; + + listener(data); + }, freq); +}; + +const progressEventDecorator = (total, throttled) => { + const lengthComputable = total != null; + + return [(loaded) => throttled[0]({ + lengthComputable, + total, + loaded + }), throttled[1]]; +}; + +const asyncDecorator = (fn) => (...args) => utils$1.asap(() => fn(...args)); + +/** + * Estimate decoded byte length of a data:// URL *without* allocating large buffers. + * - For base64: compute exact decoded size using length and padding; + * handle %XX at the character-count level (no string allocation). + * - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound. + * + * @param {string} url + * @returns {number} + */ +function estimateDataURLDecodedBytes(url) { + if (!url || typeof url !== 'string') return 0; + if (!url.startsWith('data:')) return 0; + + const comma = url.indexOf(','); + if (comma < 0) return 0; + + const meta = url.slice(5, comma); + const body = url.slice(comma + 1); + const isBase64 = /;base64/i.test(meta); + + if (isBase64) { + let effectiveLen = body.length; + const len = body.length; // cache length + + for (let i = 0; i < len; i++) { + if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) { + const a = body.charCodeAt(i + 1); + const b = body.charCodeAt(i + 2); + const isHex = + ((a >= 48 && a <= 57) || (a >= 65 && a <= 70) || (a >= 97 && a <= 102)) && + ((b >= 48 && b <= 57) || (b >= 65 && b <= 70) || (b >= 97 && b <= 102)); + + if (isHex) { + effectiveLen -= 2; + i += 2; + } + } + } + + let pad = 0; + let idx = len - 1; + + const tailIsPct3D = (j) => + j >= 2 && + body.charCodeAt(j - 2) === 37 && // '%' + body.charCodeAt(j - 1) === 51 && // '3' + (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd' + + if (idx >= 0) { + if (body.charCodeAt(idx) === 61 /* '=' */) { + pad++; + idx--; + } else if (tailIsPct3D(idx)) { + pad++; + idx -= 3; + } + } + + if (pad === 1 && idx >= 0) { + if (body.charCodeAt(idx) === 61 /* '=' */) { + pad++; + } else if (tailIsPct3D(idx)) { + pad++; + } + } + + const groups = Math.floor(effectiveLen / 4); + const bytes = groups * 3 - (pad || 0); + return bytes > 0 ? bytes : 0; + } + + return Buffer.byteLength(body, 'utf8'); +} + +const zlibOptions = { + flush: zlib__default["default"].constants.Z_SYNC_FLUSH, + finishFlush: zlib__default["default"].constants.Z_SYNC_FLUSH +}; + +const brotliOptions = { + flush: zlib__default["default"].constants.BROTLI_OPERATION_FLUSH, + finishFlush: zlib__default["default"].constants.BROTLI_OPERATION_FLUSH +}; + +const isBrotliSupported = utils$1.isFunction(zlib__default["default"].createBrotliDecompress); + +const {http: httpFollow, https: httpsFollow} = followRedirects__default["default"]; + +const isHttps = /https:?/; + +const supportedProtocols = platform.protocols.map(protocol => { + return protocol + ':'; +}); + + +const flushOnFinish = (stream, [throttled, flush]) => { + stream + .on('end', flush) + .on('error', flush); + + return throttled; +}; + + +/** + * If the proxy or config beforeRedirects functions are defined, call them with the options + * object. + * + * @param {Object} options - The options object that was passed to the request. + * + * @returns {Object} + */ +function dispatchBeforeRedirect(options, responseDetails) { + if (options.beforeRedirects.proxy) { + options.beforeRedirects.proxy(options); + } + if (options.beforeRedirects.config) { + options.beforeRedirects.config(options, responseDetails); + } +} + +/** + * If the proxy or config afterRedirects functions are defined, call them with the options + * + * @param {http.ClientRequestArgs} options + * @param {AxiosProxyConfig} configProxy configuration from Axios options object + * @param {string} location + * + * @returns {http.ClientRequestArgs} + */ +function setProxy(options, configProxy, location) { + let proxy = configProxy; + if (!proxy && proxy !== false) { + const proxyUrl = proxyFromEnv__default["default"].getProxyForUrl(location); + if (proxyUrl) { + proxy = new URL(proxyUrl); + } + } + if (proxy) { + // Basic proxy authorization + if (proxy.username) { + proxy.auth = (proxy.username || '') + ':' + (proxy.password || ''); + } + + if (proxy.auth) { + // Support proxy auth object form + if (proxy.auth.username || proxy.auth.password) { + proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || ''); + } + const base64 = Buffer + .from(proxy.auth, 'utf8') + .toString('base64'); + options.headers['Proxy-Authorization'] = 'Basic ' + base64; + } + + options.headers.host = options.hostname + (options.port ? ':' + options.port : ''); + const proxyHost = proxy.hostname || proxy.host; + options.hostname = proxyHost; + // Replace 'host' since options is not a URL object + options.host = proxyHost; + options.port = proxy.port; + options.path = location; + if (proxy.protocol) { + options.protocol = proxy.protocol.includes(':') ? proxy.protocol : `${proxy.protocol}:`; + } + } + + options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) { + // Configure proxy for redirected request, passing the original config proxy to apply + // the exact same logic as if the redirected request was performed by axios directly. + setProxy(redirectOptions, configProxy, redirectOptions.href); + }; +} + +const isHttpAdapterSupported = typeof process !== 'undefined' && utils$1.kindOf(process) === 'process'; + +// temporary hotfix + +const wrapAsync = (asyncExecutor) => { + return new Promise((resolve, reject) => { + let onDone; + let isDone; + + const done = (value, isRejected) => { + if (isDone) return; + isDone = true; + onDone && onDone(value, isRejected); + }; + + const _resolve = (value) => { + done(value); + resolve(value); + }; + + const _reject = (reason) => { + done(reason, true); + reject(reason); + }; + + asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject); + }) +}; + +const resolveFamily = ({address, family}) => { + if (!utils$1.isString(address)) { + throw TypeError('address must be a string'); + } + return ({ + address, + family: family || (address.indexOf('.') < 0 ? 6 : 4) + }); +}; + +const buildAddressEntry = (address, family) => resolveFamily(utils$1.isObject(address) ? address : {address, family}); + +/*eslint consistent-return:0*/ +const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) { + return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) { + let {data, lookup, family} = config; + const {responseType, responseEncoding} = config; + const method = config.method.toUpperCase(); + let isDone; + let rejected = false; + let req; + + if (lookup) { + const _lookup = callbackify$1(lookup, (value) => utils$1.isArray(value) ? value : [value]); + // hotfix to support opt.all option which is required for node 20.x + lookup = (hostname, opt, cb) => { + _lookup(hostname, opt, (err, arg0, arg1) => { + if (err) { + return cb(err); + } + + const addresses = utils$1.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)]; + + opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family); + }); + }; + } + + // temporary internal emitter until the AxiosRequest class will be implemented + const emitter = new events.EventEmitter(); + + const onFinished = () => { + if (config.cancelToken) { + config.cancelToken.unsubscribe(abort); + } + + if (config.signal) { + config.signal.removeEventListener('abort', abort); + } + + emitter.removeAllListeners(); + }; + + onDone((value, isRejected) => { + isDone = true; + if (isRejected) { + rejected = true; + onFinished(); + } + }); + + function abort(reason) { + emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason); + } + + emitter.once('abort', reject); + + if (config.cancelToken || config.signal) { + config.cancelToken && config.cancelToken.subscribe(abort); + if (config.signal) { + config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort); + } + } + + // Parse url + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined); + const protocol = parsed.protocol || supportedProtocols[0]; + + if (protocol === 'data:') { + // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set. + if (config.maxContentLength > -1) { + // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed. + const dataUrl = String(config.url || fullPath || ''); + const estimated = estimateDataURLDecodedBytes(dataUrl); + + if (estimated > config.maxContentLength) { + return reject(new AxiosError( + 'maxContentLength size of ' + config.maxContentLength + ' exceeded', + AxiosError.ERR_BAD_RESPONSE, + config + )); + } + } + + let convertedData; + + if (method !== 'GET') { + return settle(resolve, reject, { + status: 405, + statusText: 'method not allowed', + headers: {}, + config + }); + } + + try { + convertedData = fromDataURI(config.url, responseType === 'blob', { + Blob: config.env && config.env.Blob + }); + } catch (err) { + throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config); + } + + if (responseType === 'text') { + convertedData = convertedData.toString(responseEncoding); + + if (!responseEncoding || responseEncoding === 'utf8') { + convertedData = utils$1.stripBOM(convertedData); + } + } else if (responseType === 'stream') { + convertedData = stream__default["default"].Readable.from(convertedData); + } + + return settle(resolve, reject, { + data: convertedData, + status: 200, + statusText: 'OK', + headers: new AxiosHeaders$1(), + config + }); + } + + if (supportedProtocols.indexOf(protocol) === -1) { + return reject(new AxiosError( + 'Unsupported protocol ' + protocol, + AxiosError.ERR_BAD_REQUEST, + config + )); + } + + const headers = AxiosHeaders$1.from(config.headers).normalize(); + + // Set User-Agent (required by some servers) + // See https://github.com/axios/axios/issues/69 + // User-Agent is specified; handle case where no UA header is desired + // Only set header if it hasn't been set in config + headers.set('User-Agent', 'axios/' + VERSION, false); + + const {onUploadProgress, onDownloadProgress} = config; + const maxRate = config.maxRate; + let maxUploadRate = undefined; + let maxDownloadRate = undefined; + + // support for spec compliant FormData objects + if (utils$1.isSpecCompliantForm(data)) { + const userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i); + + data = formDataToStream$1(data, (formHeaders) => { + headers.set(formHeaders); + }, { + tag: `axios-${VERSION}-boundary`, + boundary: userBoundary && userBoundary[1] || undefined + }); + // support for https://www.npmjs.com/package/form-data api + } else if (utils$1.isFormData(data) && utils$1.isFunction(data.getHeaders)) { + headers.set(data.getHeaders()); + + if (!headers.hasContentLength()) { + try { + const knownLength = await util__default["default"].promisify(data.getLength).call(data); + Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength); + /*eslint no-empty:0*/ + } catch (e) { + } + } + } else if (utils$1.isBlob(data) || utils$1.isFile(data)) { + data.size && headers.setContentType(data.type || 'application/octet-stream'); + headers.setContentLength(data.size || 0); + data = stream__default["default"].Readable.from(readBlob$1(data)); + } else if (data && !utils$1.isStream(data)) { + if (Buffer.isBuffer(data)) ; else if (utils$1.isArrayBuffer(data)) { + data = Buffer.from(new Uint8Array(data)); + } else if (utils$1.isString(data)) { + data = Buffer.from(data, 'utf-8'); + } else { + return reject(new AxiosError( + 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream', + AxiosError.ERR_BAD_REQUEST, + config + )); + } + + // Add Content-Length header if data exists + headers.setContentLength(data.length, false); + + if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) { + return reject(new AxiosError( + 'Request body larger than maxBodyLength limit', + AxiosError.ERR_BAD_REQUEST, + config + )); + } + } + + const contentLength = utils$1.toFiniteNumber(headers.getContentLength()); + + if (utils$1.isArray(maxRate)) { + maxUploadRate = maxRate[0]; + maxDownloadRate = maxRate[1]; + } else { + maxUploadRate = maxDownloadRate = maxRate; + } + + if (data && (onUploadProgress || maxUploadRate)) { + if (!utils$1.isStream(data)) { + data = stream__default["default"].Readable.from(data, {objectMode: false}); + } + + data = stream__default["default"].pipeline([data, new AxiosTransformStream$1({ + maxRate: utils$1.toFiniteNumber(maxUploadRate) + })], utils$1.noop); + + onUploadProgress && data.on('progress', flushOnFinish( + data, + progressEventDecorator( + contentLength, + progressEventReducer(asyncDecorator(onUploadProgress), false, 3) + ) + )); + } + + // HTTP basic authentication + let auth = undefined; + if (config.auth) { + const username = config.auth.username || ''; + const password = config.auth.password || ''; + auth = username + ':' + password; + } + + if (!auth && parsed.username) { + const urlUsername = parsed.username; + const urlPassword = parsed.password; + auth = urlUsername + ':' + urlPassword; + } + + auth && headers.delete('authorization'); + + let path; + + try { + path = buildURL( + parsed.pathname + parsed.search, + config.params, + config.paramsSerializer + ).replace(/^\?/, ''); + } catch (err) { + const customErr = new Error(err.message); + customErr.config = config; + customErr.url = config.url; + customErr.exists = true; + return reject(customErr); + } + + headers.set( + 'Accept-Encoding', + 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false + ); + + const options = { + path, + method: method, + headers: headers.toJSON(), + agents: { http: config.httpAgent, https: config.httpsAgent }, + auth, + protocol, + family, + beforeRedirect: dispatchBeforeRedirect, + beforeRedirects: {} + }; + + // cacheable-lookup integration hotfix + !utils$1.isUndefined(lookup) && (options.lookup = lookup); + + if (config.socketPath) { + options.socketPath = config.socketPath; + } else { + options.hostname = parsed.hostname.startsWith("[") ? parsed.hostname.slice(1, -1) : parsed.hostname; + options.port = parsed.port; + setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path); + } + + let transport; + const isHttpsRequest = isHttps.test(options.protocol); + options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; + if (config.transport) { + transport = config.transport; + } else if (config.maxRedirects === 0) { + transport = isHttpsRequest ? https__default["default"] : http__default["default"]; + } else { + if (config.maxRedirects) { + options.maxRedirects = config.maxRedirects; + } + if (config.beforeRedirect) { + options.beforeRedirects.config = config.beforeRedirect; + } + transport = isHttpsRequest ? httpsFollow : httpFollow; + } + + if (config.maxBodyLength > -1) { + options.maxBodyLength = config.maxBodyLength; + } else { + // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited + options.maxBodyLength = Infinity; + } + + if (config.insecureHTTPParser) { + options.insecureHTTPParser = config.insecureHTTPParser; + } + + // Create the request + req = transport.request(options, function handleResponse(res) { + if (req.destroyed) return; + + const streams = [res]; + + const responseLength = +res.headers['content-length']; + + if (onDownloadProgress || maxDownloadRate) { + const transformStream = new AxiosTransformStream$1({ + maxRate: utils$1.toFiniteNumber(maxDownloadRate) + }); + + onDownloadProgress && transformStream.on('progress', flushOnFinish( + transformStream, + progressEventDecorator( + responseLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true, 3) + ) + )); + + streams.push(transformStream); + } + + // decompress the response body transparently if required + let responseStream = res; + + // return the last request in case of redirects + const lastRequest = res.req || req; + + // if decompress disabled we should not decompress + if (config.decompress !== false && res.headers['content-encoding']) { + // if no content, but headers still say that it is encoded, + // remove the header not confuse downstream operations + if (method === 'HEAD' || res.statusCode === 204) { + delete res.headers['content-encoding']; + } + + switch ((res.headers['content-encoding'] || '').toLowerCase()) { + /*eslint default-case:0*/ + case 'gzip': + case 'x-gzip': + case 'compress': + case 'x-compress': + // add the unzipper to the body stream processing pipeline + streams.push(zlib__default["default"].createUnzip(zlibOptions)); + + // remove the content-encoding in order to not confuse downstream operations + delete res.headers['content-encoding']; + break; + case 'deflate': + streams.push(new ZlibHeaderTransformStream$1()); + + // add the unzipper to the body stream processing pipeline + streams.push(zlib__default["default"].createUnzip(zlibOptions)); + + // remove the content-encoding in order to not confuse downstream operations + delete res.headers['content-encoding']; + break; + case 'br': + if (isBrotliSupported) { + streams.push(zlib__default["default"].createBrotliDecompress(brotliOptions)); + delete res.headers['content-encoding']; + } + } + } + + responseStream = streams.length > 1 ? stream__default["default"].pipeline(streams, utils$1.noop) : streams[0]; + + const offListeners = stream__default["default"].finished(responseStream, () => { + offListeners(); + onFinished(); + }); + + const response = { + status: res.statusCode, + statusText: res.statusMessage, + headers: new AxiosHeaders$1(res.headers), + config, + request: lastRequest + }; + + if (responseType === 'stream') { + response.data = responseStream; + settle(resolve, reject, response); + } else { + const responseBuffer = []; + let totalResponseBytes = 0; + + responseStream.on('data', function handleStreamData(chunk) { + responseBuffer.push(chunk); + totalResponseBytes += chunk.length; + + // make sure the content length is not over the maxContentLength if specified + if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) { + // stream.destroy() emit aborted event before calling reject() on Node.js v16 + rejected = true; + responseStream.destroy(); + reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded', + AxiosError.ERR_BAD_RESPONSE, config, lastRequest)); + } + }); + + responseStream.on('aborted', function handlerStreamAborted() { + if (rejected) { + return; + } + + const err = new AxiosError( + 'stream has been aborted', + AxiosError.ERR_BAD_RESPONSE, + config, + lastRequest + ); + responseStream.destroy(err); + reject(err); + }); + + responseStream.on('error', function handleStreamError(err) { + if (req.destroyed) return; + reject(AxiosError.from(err, null, config, lastRequest)); + }); + + responseStream.on('end', function handleStreamEnd() { + try { + let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer); + if (responseType !== 'arraybuffer') { + responseData = responseData.toString(responseEncoding); + if (!responseEncoding || responseEncoding === 'utf8') { + responseData = utils$1.stripBOM(responseData); + } + } + response.data = responseData; + } catch (err) { + return reject(AxiosError.from(err, null, config, response.request, response)); + } + settle(resolve, reject, response); + }); + } + + emitter.once('abort', err => { + if (!responseStream.destroyed) { + responseStream.emit('error', err); + responseStream.destroy(); + } + }); + }); + + emitter.once('abort', err => { + reject(err); + req.destroy(err); + }); + + // Handle errors + req.on('error', function handleRequestError(err) { + // @todo remove + // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return; + reject(AxiosError.from(err, null, config, req)); + }); + + // set tcp keep alive to prevent drop connection by peer + req.on('socket', function handleRequestSocket(socket) { + // default interval of sending ack packet is 1 minute + socket.setKeepAlive(true, 1000 * 60); + }); + + // Handle request timeout + if (config.timeout) { + // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types. + const timeout = parseInt(config.timeout, 10); + + if (Number.isNaN(timeout)) { + reject(new AxiosError( + 'error trying to parse `config.timeout` to int', + AxiosError.ERR_BAD_OPTION_VALUE, + config, + req + )); + + return; + } + + // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system. + // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET. + // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up. + // And then these socket which be hang up will devouring CPU little by little. + // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect. + req.setTimeout(timeout, function handleRequestTimeout() { + if (isDone) return; + let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = config.transitional || transitionalDefaults; + if (config.timeoutErrorMessage) { + timeoutErrorMessage = config.timeoutErrorMessage; + } + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + req + )); + abort(); + }); + } + + + // Send the request + if (utils$1.isStream(data)) { + let ended = false; + let errored = false; + + data.on('end', () => { + ended = true; + }); + + data.once('error', err => { + errored = true; + req.destroy(err); + }); + + data.on('close', () => { + if (!ended && !errored) { + abort(new CanceledError('Request stream has been aborted', config, req)); + } + }); + + data.pipe(req); + } else { + req.end(data); + } + }); +}; + +const isURLSameOrigin = platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => { + url = new URL(url, platform.origin); + + return ( + origin.protocol === url.protocol && + origin.host === url.host && + (isMSIE || origin.port === url.port) + ); +})( + new URL(platform.origin), + platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent) +) : () => true; + +const cookies = platform.hasStandardBrowserEnv ? + + // Standard browser envs support document.cookie + { + write(name, value, expires, path, domain, secure) { + const cookie = [name + '=' + encodeURIComponent(value)]; + + utils$1.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString()); + + utils$1.isString(path) && cookie.push('path=' + path); + + utils$1.isString(domain) && cookie.push('domain=' + domain); + + secure === true && cookie.push('secure'); + + document.cookie = cookie.join('; '); + }, + + read(name) { + const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return (match ? decodeURIComponent(match[3]) : null); + }, + + remove(name) { + this.write(name, '', Date.now() - 86400000); + } + } + + : + + // Non-standard browser env (web workers, react-native) lack needed support. + { + write() {}, + read() { + return null; + }, + remove() {} + }; + +const headersToObject = (thing) => thing instanceof AxiosHeaders$1 ? { ...thing } : thing; + +/** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * + * @returns {Object} New object resulting from merging config2 to config1 + */ +function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + const config = {}; + + function getMergedValue(target, source, prop, caseless) { + if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) { + return utils$1.merge.call({caseless}, target, source); + } else if (utils$1.isPlainObject(source)) { + return utils$1.merge({}, source); + } else if (utils$1.isArray(source)) { + return source.slice(); + } + return source; + } + + // eslint-disable-next-line consistent-return + function mergeDeepProperties(a, b, prop , caseless) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(a, b, prop , caseless); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a, prop , caseless); + } + } + + // eslint-disable-next-line consistent-return + function valueFromConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } + } + + // eslint-disable-next-line consistent-return + function defaultToConfig2(a, b) { + if (!utils$1.isUndefined(b)) { + return getMergedValue(undefined, b); + } else if (!utils$1.isUndefined(a)) { + return getMergedValue(undefined, a); + } + } + + // eslint-disable-next-line consistent-return + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(undefined, a); + } + } + + const mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true) + }; + + utils$1.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) { + const merge = mergeMap[prop] || mergeDeepProperties; + const configValue = merge(config1[prop], config2[prop], prop); + (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); + }); + + return config; +} + +const resolveConfig = (config) => { + const newConfig = mergeConfig({}, config); + + let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig; + + newConfig.headers = headers = AxiosHeaders$1.from(headers); + + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + + // HTTP basic authentication + if (auth) { + headers.set('Authorization', 'Basic ' + + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : '')) + ); + } + + if (utils$1.isFormData(data)) { + if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(undefined); // browser handles it + } else if (utils$1.isFunction(data.getHeaders)) { + // Node.js FormData (like form-data package) + const formHeaders = data.getHeaders(); + // Only set safe headers to avoid overwriting security headers + const allowedHeaders = ['content-type', 'content-length']; + Object.entries(formHeaders).forEach(([key, val]) => { + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + + if (platform.hasStandardBrowserEnv) { + withXSRFToken && utils$1.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + + if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { + // Add xsrf header + const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + + return newConfig; +}; + +const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; + +const xhrAdapter = isXHRAdapterSupported && function (config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + const _config = resolveConfig(config); + let requestData = _config.data; + const requestHeaders = AxiosHeaders$1.from(_config.headers).normalize(); + let {responseType, onUploadProgress, onDownloadProgress} = _config; + let onCanceled; + let uploadThrottled, downloadThrottled; + let flushUpload, flushDownload; + + function done() { + flushUpload && flushUpload(); // flush events + flushDownload && flushDownload(); // flush events + + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + + _config.signal && _config.signal.removeEventListener('abort', onCanceled); + } + + let request = new XMLHttpRequest(); + + request.open(_config.method.toUpperCase(), _config.url, true); + + // Set the request timeout in MS + request.timeout = _config.timeout; + + function onloadend() { + if (!request) { + return; + } + // Prepare the response + const responseHeaders = AxiosHeaders$1.from( + 'getAllResponseHeaders' in request && request.getAllResponseHeaders() + ); + const responseData = !responseType || responseType === 'text' || responseType === 'json' ? + request.responseText : request.response; + const response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config, + request + }; + + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + + // Clean up request + request = null; + } + + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError(event) { + // Browsers deliver a ProgressEvent in XHR onerror + // (message may be empty; when present, surface it) + // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event + const msg = event && event.message ? event.message : 'Network Error'; + const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); + // attach the underlying event for consumers who want details + err.event = event || null; + reject(err); + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + request)); + + // Clean up request + request = null; + }; + + // Remove Content-Type if data is undefined + requestData === undefined && requestHeaders.setContentType(null); + + // Add headers to the request + if ('setRequestHeader' in request) { + utils$1.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + + // Add withCredentials to request if needed + if (!utils$1.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + + // Add responseType to request if needed + if (responseType && responseType !== 'json') { + request.responseType = _config.responseType; + } + + // Handle progress if needed + if (onDownloadProgress) { + ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true)); + request.addEventListener('progress', downloadThrottled); + } + + // Not all browsers support upload events + if (onUploadProgress && request.upload) { + ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress)); + + request.upload.addEventListener('progress', uploadThrottled); + + request.upload.addEventListener('loadend', flushUpload); + } + + if (_config.cancelToken || _config.signal) { + // Handle cancellation + // eslint-disable-next-line func-names + onCanceled = cancel => { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); + request.abort(); + request = null; + }; + + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); + } + } + + const protocol = parseProtocol(_config.url); + + if (protocol && platform.protocols.indexOf(protocol) === -1) { + reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config)); + return; + } + + + // Send the request + request.send(requestData || null); + }); +}; + +const composeSignals = (signals, timeout) => { + const {length} = (signals = signals ? signals.filter(Boolean) : []); + + if (timeout || length) { + let controller = new AbortController(); + + let aborted; + + const onabort = function (reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + const err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err)); + } + }; + + let timer = timeout && setTimeout(() => { + timer = null; + onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT)); + }, timeout); + + const unsubscribe = () => { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach(signal => { + signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); + }); + signals = null; + } + }; + + signals.forEach((signal) => signal.addEventListener('abort', onabort)); + + const {signal} = controller; + + signal.unsubscribe = () => utils$1.asap(unsubscribe); + + return signal; + } +}; + +const composeSignals$1 = composeSignals; + +const streamChunk = function* (chunk, chunkSize) { + let len = chunk.byteLength; + + if (!chunkSize || len < chunkSize) { + yield chunk; + return; + } + + let pos = 0; + let end; + + while (pos < len) { + end = pos + chunkSize; + yield chunk.slice(pos, end); + pos = end; + } +}; + +const readBytes = async function* (iterable, chunkSize) { + for await (const chunk of readStream(iterable)) { + yield* streamChunk(chunk, chunkSize); + } +}; + +const readStream = async function* (stream) { + if (stream[Symbol.asyncIterator]) { + yield* stream; + return; + } + + const reader = stream.getReader(); + try { + for (;;) { + const {done, value} = await reader.read(); + if (done) { + break; + } + yield value; + } + } finally { + await reader.cancel(); + } +}; + +const trackStream = (stream, chunkSize, onProgress, onFinish) => { + const iterator = readBytes(stream, chunkSize); + + let bytes = 0; + let done; + let _onFinish = (e) => { + if (!done) { + done = true; + onFinish && onFinish(e); + } + }; + + return new ReadableStream({ + async pull(controller) { + try { + const {done, value} = await iterator.next(); + + if (done) { + _onFinish(); + controller.close(); + return; + } + + let len = value.byteLength; + if (onProgress) { + let loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + } catch (err) { + _onFinish(err); + throw err; + } + }, + cancel(reason) { + _onFinish(reason); + return iterator.return(); + } + }, { + highWaterMark: 2 + }) +}; + +const DEFAULT_CHUNK_SIZE = 64 * 1024; + +const {isFunction} = utils$1; + +const globalFetchAPI = (({Request, Response}) => ({ + Request, Response +}))(utils$1.global); + +const { + ReadableStream: ReadableStream$1, TextEncoder: TextEncoder$1 +} = utils$1.global; + + +const test = (fn, ...args) => { + try { + return !!fn(...args); + } catch (e) { + return false + } +}; + +const factory = (env) => { + env = utils$1.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + + const {fetch: envFetch, Request, Response} = env; + const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; + const isRequestSupported = isFunction(Request); + const isResponseSupported = isFunction(Response); + + if (!isFetchSupported) { + return false; + } + + const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream$1); + + const encodeText = isFetchSupported && (typeof TextEncoder$1 === 'function' ? + ((encoder) => (str) => encoder.encode(str))(new TextEncoder$1()) : + async (str) => new Uint8Array(await new Request(str).arrayBuffer()) + ); + + const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { + let duplexAccessed = false; + + const hasContentType = new Request(platform.origin, { + body: new ReadableStream$1(), + method: 'POST', + get duplex() { + duplexAccessed = true; + return 'half'; + }, + }).headers.has('Content-Type'); + + return duplexAccessed && !hasContentType; + }); + + const supportsResponseStream = isResponseSupported && isReadableStreamSupported && + test(() => utils$1.isReadableStream(new Response('').body)); + + const resolvers = { + stream: supportsResponseStream && ((res) => res.body) + }; + + isFetchSupported && ((() => { + ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => { + !resolvers[type] && (resolvers[type] = (res, config) => { + let method = res && res[type]; + + if (method) { + return method.call(res); + } + + throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config); + }); + }); + })()); + + const getBodyLength = async (body) => { + if (body == null) { + return 0; + } + + if (utils$1.isBlob(body)) { + return body.size; + } + + if (utils$1.isSpecCompliantForm(body)) { + const _request = new Request(platform.origin, { + method: 'POST', + body, + }); + return (await _request.arrayBuffer()).byteLength; + } + + if (utils$1.isArrayBufferView(body) || utils$1.isArrayBuffer(body)) { + return body.byteLength; + } + + if (utils$1.isURLSearchParams(body)) { + body = body + ''; + } + + if (utils$1.isString(body)) { + return (await encodeText(body)).byteLength; + } + }; + + const resolveBodyLength = async (headers, body) => { + const length = utils$1.toFiniteNumber(headers.getContentLength()); + + return length == null ? getBodyLength(body) : length; + }; + + return async (config) => { + let { + url, + method, + data, + signal, + cancelToken, + timeout, + onDownloadProgress, + onUploadProgress, + responseType, + headers, + withCredentials = 'same-origin', + fetchOptions + } = resolveConfig(config); + + let _fetch = envFetch || fetch; + + responseType = responseType ? (responseType + '').toLowerCase() : 'text'; + + let composedSignal = composeSignals$1([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + + let request = null; + + const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { + composedSignal.unsubscribe(); + }); + + let requestContentLength; + + try { + if ( + onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && + (requestContentLength = await resolveBodyLength(headers, data)) !== 0 + ) { + let _request = new Request(url, { + method: 'POST', + body: data, + duplex: "half" + }); + + let contentTypeHeader; + + if (utils$1.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { + headers.setContentType(contentTypeHeader); + } + + if (_request.body) { + const [onProgress, flush] = progressEventDecorator( + requestContentLength, + progressEventReducer(asyncDecorator(onUploadProgress)) + ); + + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + } + + if (!utils$1.isString(withCredentials)) { + withCredentials = withCredentials ? 'include' : 'omit'; + } + + // Cloudflare Workers throws when credentials are defined + // see https://github.com/cloudflare/workerd/issues/902 + const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + + const resolvedOptions = { + ...fetchOptions, + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : undefined + }; + + request = isRequestSupported && new Request(url, resolvedOptions); + + let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions)); + + const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); + + if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) { + const options = {}; + + ['status', 'statusText', 'headers'].forEach(prop => { + options[prop] = response[prop]; + }); + + const responseContentLength = utils$1.toFiniteNumber(response.headers.get('content-length')); + + const [onProgress, flush] = onDownloadProgress && progressEventDecorator( + responseContentLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true) + ) || []; + + response = new Response( + trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => { + flush && flush(); + unsubscribe && unsubscribe(); + }), + options + ); + } + + responseType = responseType || 'text'; + + let responseData = await resolvers[utils$1.findKey(resolvers, responseType) || 'text'](response, config); + + !isStreamResponse && unsubscribe && unsubscribe(); + + return await new Promise((resolve, reject) => { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders$1.from(response.headers), + status: response.status, + statusText: response.statusText, + config, + request + }); + }) + } catch (err) { + unsubscribe && unsubscribe(); + + if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) { + throw Object.assign( + new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request), + { + cause: err.cause || err + } + ) + } + + throw AxiosError.from(err, err && err.code, config, request); + } + } +}; + +const seedCache = new Map(); + +const getFetch = (config) => { + let env = config ? config.env : {}; + const {fetch, Request, Response} = env; + const seeds = [ + Request, Response, fetch + ]; + + let len = seeds.length, i = len, + seed, target, map = seedCache; + + while (i--) { + seed = seeds[i]; + target = map.get(seed); + + target === undefined && map.set(seed, target = (i ? new Map() : factory(env))); + + map = target; + } + + return target; +}; + +getFetch(); + +const knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: getFetch, + } +}; + +utils$1.forEach(knownAdapters, (fn, value) => { + if (fn) { + try { + Object.defineProperty(fn, 'name', {value}); + } catch (e) { + // eslint-disable-next-line no-empty + } + Object.defineProperty(fn, 'adapterName', {value}); + } +}); + +const renderReason = (reason) => `- ${reason}`; + +const isResolvedHandle = (adapter) => utils$1.isFunction(adapter) || adapter === null || adapter === false; + +const adapters = { + getAdapter: (adapters, config) => { + adapters = utils$1.isArray(adapters) ? adapters : [adapters]; + + const {length} = adapters; + let nameOrAdapter; + let adapter; + + const rejectedReasons = {}; + + for (let i = 0; i < length; i++) { + nameOrAdapter = adapters[i]; + let id; + + adapter = nameOrAdapter; + + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + + if (adapter === undefined) { + throw new AxiosError(`Unknown adapter '${id}'`); + } + } + + if (adapter && (utils$1.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + + rejectedReasons[id || '#' + i] = adapter; + } + + if (!adapter) { + + const reasons = Object.entries(rejectedReasons) + .map(([id, state]) => `adapter ${id} ` + + (state === false ? 'is not supported by the environment' : 'is not available in the build') + ); + + let s = length ? + (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) : + 'as no adapter specified'; + + throw new AxiosError( + `There is no suitable adapter to dispatch the request ` + s, + 'ERR_NOT_SUPPORT' + ); + } + + return adapter; + }, + adapters: knownAdapters +}; + +/** + * Throws a `CanceledError` if cancellation has been requested. + * + * @param {Object} config The config that is to be used for the request + * + * @returns {void} + */ +function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + + if (config.signal && config.signal.aborted) { + throw new CanceledError(null, config); + } +} + +/** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * + * @returns {Promise} The Promise to be fulfilled + */ +function dispatchRequest(config) { + throwIfCancellationRequested(config); + + config.headers = AxiosHeaders$1.from(config.headers); + + // Transform request data + config.data = transformData.call( + config, + config.transformRequest + ); + + if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { + config.headers.setContentType('application/x-www-form-urlencoded', false); + } + + const adapter = adapters.getAdapter(config.adapter || defaults$1.adapter, config); + + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData.call( + config, + config.transformResponse, + response + ); + + response.headers = AxiosHeaders$1.from(response.headers); + + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData.call( + config, + config.transformResponse, + reason.response + ); + reason.response.headers = AxiosHeaders$1.from(reason.response.headers); + } + } + + return Promise.reject(reason); + }); +} + +const validators$1 = {}; + +// eslint-disable-next-line func-names +['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => { + validators$1[type] = function validator(thing) { + return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; +}); + +const deprecatedWarnings = {}; + +/** + * Transitional option validator + * + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * + * @returns {function} + */ +validators$1.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return (value, opt, opts) => { + if (validator === false) { + throw new AxiosError( + formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), + AxiosError.ERR_DEPRECATED + ); + } + + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn( + formatMessage( + opt, + ' has been deprecated since v' + version + ' and will be removed in the near future' + ) + ); + } + + return validator ? validator(value, opt, opts) : true; + }; +}; + +validators$1.spelling = function spelling(correctSpelling) { + return (value, opt) => { + // eslint-disable-next-line no-console + console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); + return true; + } +}; + +/** + * Assert object's properties type + * + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + * + * @returns {object} + */ + +function assertOptions(options, schema, allowUnknown) { + if (typeof options !== 'object') { + throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE); + } + const keys = Object.keys(options); + let i = keys.length; + while (i-- > 0) { + const opt = keys[i]; + const validator = schema[opt]; + if (validator) { + const value = options[opt]; + const result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION); + } + } +} + +const validator = { + assertOptions, + validators: validators$1 +}; + +const validators = validator.validators; + +/** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + * + * @return {Axios} A new instance of Axios + */ +class Axios { + constructor(instanceConfig) { + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager$1(), + response: new InterceptorManager$1() + }; + } + + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + async request(configOrUrl, config) { + try { + return await this._request(configOrUrl, config); + } catch (err) { + if (err instanceof Error) { + let dummy = {}; + + Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error()); + + // slice off the Error: ... line + const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : ''; + try { + if (!err.stack) { + err.stack = stack; + // match without the 2 top stack lines + } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\n.+\n/, ''))) { + err.stack += '\n' + stack; + } + } catch (e) { + // ignore the case where "stack" is an un-writable property + } + } + + throw err; + } + } + + _request(configOrUrl, config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof configOrUrl === 'string') { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + + config = mergeConfig(this.defaults, config); + + const {transitional, paramsSerializer, headers} = config; + + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean) + }, false); + } + + if (paramsSerializer != null) { + if (utils$1.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + }; + } else { + validator.assertOptions(paramsSerializer, { + encode: validators.function, + serialize: validators.function + }, true); + } + } + + // Set config.allowAbsoluteUrls + if (config.allowAbsoluteUrls !== undefined) ; else if (this.defaults.allowAbsoluteUrls !== undefined) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + + validator.assertOptions(config, { + baseUrl: validators.spelling('baseURL'), + withXsrfToken: validators.spelling('withXSRFToken') + }, true); + + // Set config.method + config.method = (config.method || this.defaults.method || 'get').toLowerCase(); + + // Flatten headers + let contextHeaders = headers && utils$1.merge( + headers.common, + headers[config.method] + ); + + headers && utils$1.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + (method) => { + delete headers[method]; + } + ); + + config.headers = AxiosHeaders$1.concat(contextHeaders, headers); + + // filter out skipped interceptors + const requestInterceptorChain = []; + let synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + + const responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + + let promise; + let i = 0; + let len; + + if (!synchronousRequestInterceptors) { + const chain = [dispatchRequest.bind(this), undefined]; + chain.unshift(...requestInterceptorChain); + chain.push(...responseInterceptorChain); + len = chain.length; + + promise = Promise.resolve(config); + + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + + return promise; + } + + len = requestInterceptorChain.length; + + let newConfig = config; + + while (i < len) { + const onFulfilled = requestInterceptorChain[i++]; + const onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + + i = 0; + len = responseInterceptorChain.length; + + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + + return promise; + } + + getUri(config) { + config = mergeConfig(this.defaults, config); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } +} + +// Provide aliases for supported request methods +utils$1.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, config) { + return this.request(mergeConfig(config || {}, { + method, + url, + data: (config || {}).data + })); + }; +}); + +utils$1.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig(config || {}, { + method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url, + data + })); + }; + } + + Axios.prototype[method] = generateHTTPMethod(); + + Axios.prototype[method + 'Form'] = generateHTTPMethod(true); +}); + +const Axios$1 = Axios; + +/** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @param {Function} executor The executor function. + * + * @returns {CancelToken} + */ +class CancelToken { + constructor(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + + let resolvePromise; + + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + + const token = this; + + // eslint-disable-next-line func-names + this.promise.then(cancel => { + if (!token._listeners) return; + + let i = token._listeners.length; + + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = onfulfilled => { + let _resolve; + // eslint-disable-next-line func-names + const promise = new Promise(resolve => { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + + return promise; + }; + + executor(function cancel(message, config, request) { + if (token.reason) { + // Cancellation has already been requested + return; + } + + token.reason = new CanceledError(message, config, request); + resolvePromise(token.reason); + }); + } + + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + + /** + * Subscribe to the cancel signal + */ + + subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + + /** + * Unsubscribe from the cancel signal + */ + + unsubscribe(listener) { + if (!this._listeners) { + return; + } + const index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + + toAbortSignal() { + const controller = new AbortController(); + + const abort = (err) => { + controller.abort(err); + }; + + this.subscribe(abort); + + controller.signal.unsubscribe = () => this.unsubscribe(abort); + + return controller.signal; + } + + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + static source() { + let cancel; + const token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token, + cancel + }; + } +} + +const CancelToken$1 = CancelToken; + +/** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * + * @returns {Function} + */ +function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; +} + +/** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ +function isAxiosError(payload) { + return utils$1.isObject(payload) && (payload.isAxiosError === true); +} + +const HttpStatusCode = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511, +}; + +Object.entries(HttpStatusCode).forEach(([key, value]) => { + HttpStatusCode[value] = key; +}); + +const HttpStatusCode$1 = HttpStatusCode; + +/** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * + * @returns {Axios} A new instance of Axios + */ +function createInstance(defaultConfig) { + const context = new Axios$1(defaultConfig); + const instance = bind(Axios$1.prototype.request, context); + + // Copy axios.prototype to instance + utils$1.extend(instance, Axios$1.prototype, context, {allOwnKeys: true}); + + // Copy context to instance + utils$1.extend(instance, context, null, {allOwnKeys: true}); + + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + + return instance; +} + +// Create the default instance to be exported +const axios = createInstance(defaults$1); + +// Expose Axios class to allow class inheritance +axios.Axios = Axios$1; + +// Expose Cancel & CancelToken +axios.CanceledError = CanceledError; +axios.CancelToken = CancelToken$1; +axios.isCancel = isCancel; +axios.VERSION = VERSION; +axios.toFormData = toFormData; + +// Expose AxiosError class +axios.AxiosError = AxiosError; + +// alias for CanceledError for backward compatibility +axios.Cancel = axios.CanceledError; + +// Expose all/spread +axios.all = function all(promises) { + return Promise.all(promises); +}; + +axios.spread = spread; + +// Expose isAxiosError +axios.isAxiosError = isAxiosError; + +// Expose mergeConfig +axios.mergeConfig = mergeConfig; + +axios.AxiosHeaders = AxiosHeaders$1; + +axios.formToJSON = thing => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing); + +axios.getAdapter = adapters.getAdapter; + +axios.HttpStatusCode = HttpStatusCode$1; + +axios.default = axios; + +module.exports = axios; +//# sourceMappingURL=axios.cjs.map diff --git a/node_modules/axios/dist/node/axios.cjs.map b/node_modules/axios/dist/node/axios.cjs.map new file mode 100644 index 0000000..b3e2150 --- /dev/null +++ b/node_modules/axios/dist/node/axios.cjs.map @@ -0,0 +1 @@ +{"version":3,"file":"axios.cjs","sources":["../../lib/helpers/bind.js","../../lib/utils.js","../../lib/core/AxiosError.js","../../lib/helpers/toFormData.js","../../lib/helpers/AxiosURLSearchParams.js","../../lib/helpers/buildURL.js","../../lib/core/InterceptorManager.js","../../lib/defaults/transitional.js","../../lib/platform/node/classes/URLSearchParams.js","../../lib/platform/node/index.js","../../lib/platform/common/utils.js","../../lib/platform/index.js","../../lib/helpers/toURLEncodedForm.js","../../lib/helpers/formDataToJSON.js","../../lib/defaults/index.js","../../lib/helpers/parseHeaders.js","../../lib/core/AxiosHeaders.js","../../lib/core/transformData.js","../../lib/cancel/isCancel.js","../../lib/cancel/CanceledError.js","../../lib/core/settle.js","../../lib/helpers/isAbsoluteURL.js","../../lib/helpers/combineURLs.js","../../lib/core/buildFullPath.js","../../lib/env/data.js","../../lib/helpers/parseProtocol.js","../../lib/helpers/fromDataURI.js","../../lib/helpers/AxiosTransformStream.js","../../lib/helpers/readBlob.js","../../lib/helpers/formDataToStream.js","../../lib/helpers/ZlibHeaderTransformStream.js","../../lib/helpers/callbackify.js","../../lib/helpers/speedometer.js","../../lib/helpers/throttle.js","../../lib/helpers/progressEventReducer.js","../../lib/helpers/estimateDataURLDecodedBytes.js","../../lib/adapters/http.js","../../lib/helpers/isURLSameOrigin.js","../../lib/helpers/cookies.js","../../lib/core/mergeConfig.js","../../lib/helpers/resolveConfig.js","../../lib/adapters/xhr.js","../../lib/helpers/composeSignals.js","../../lib/helpers/trackStream.js","../../lib/adapters/fetch.js","../../lib/adapters/adapters.js","../../lib/core/dispatchRequest.js","../../lib/helpers/validator.js","../../lib/core/Axios.js","../../lib/cancel/CancelToken.js","../../lib/helpers/spread.js","../../lib/helpers/isAxiosError.js","../../lib/helpers/HttpStatusCode.js","../../lib/axios.js"],"sourcesContent":["'use strict';\n\nexport default function bind(fn, thisArg) {\n return function wrap() {\n return fn.apply(thisArg, arguments);\n };\n}\n","'use strict';\n\nimport bind from './helpers/bind.js';\n\n// utils is a library of generic helper functions non-specific to axios\n\nconst {toString} = Object.prototype;\nconst {getPrototypeOf} = Object;\nconst {iterator, toStringTag} = Symbol;\n\nconst kindOf = (cache => thing => {\n const str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n})(Object.create(null));\n\nconst kindOfTest = (type) => {\n type = type.toLowerCase();\n return (thing) => kindOf(thing) === type\n}\n\nconst typeOfTest = type => thing => typeof thing === type;\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n *\n * @returns {boolean} True if value is an Array, otherwise false\n */\nconst {isArray} = Array;\n\n/**\n * Determine if a value is undefined\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nconst isUndefined = typeOfTest('undefined');\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nconst isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n let result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a String, otherwise false\n */\nconst isString = typeOfTest('string');\n\n/**\n * Determine if a value is a Function\n *\n * @param {*} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nconst isFunction = typeOfTest('function');\n\n/**\n * Determine if a value is a Number\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Number, otherwise false\n */\nconst isNumber = typeOfTest('number');\n\n/**\n * Determine if a value is an Object\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an Object, otherwise false\n */\nconst isObject = (thing) => thing !== null && typeof thing === 'object';\n\n/**\n * Determine if a value is a Boolean\n *\n * @param {*} thing The value to test\n * @returns {boolean} True if value is a Boolean, otherwise false\n */\nconst isBoolean = thing => thing === true || thing === false;\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a plain Object, otherwise false\n */\nconst isPlainObject = (val) => {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n const prototype = getPrototypeOf(val);\n return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val);\n}\n\n/**\n * Determine if a value is an empty object (safely handles Buffers)\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is an empty object, otherwise false\n */\nconst isEmptyObject = (val) => {\n // Early return for non-objects or Buffers to prevent RangeError\n if (!isObject(val) || isBuffer(val)) {\n return false;\n }\n\n try {\n return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;\n } catch (e) {\n // Fallback for any other objects that might cause RangeError with Object.keys()\n return false;\n }\n}\n\n/**\n * Determine if a value is a Date\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Date, otherwise false\n */\nconst isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nconst isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a File, otherwise false\n */\nconst isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Stream\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nconst isStream = (val) => isObject(val) && isFunction(val.pipe);\n\n/**\n * Determine if a value is a FormData\n *\n * @param {*} thing The value to test\n *\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nconst isFormData = (thing) => {\n let kind;\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) || (\n isFunction(thing.append) && (\n (kind = kindOf(thing)) === 'formdata' ||\n // detect form-data instance\n (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]')\n )\n )\n )\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nconst isURLSearchParams = kindOfTest('URLSearchParams');\n\nconst [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest);\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n *\n * @returns {String} The String freed of excess whitespace\n */\nconst trim = (str) => str.trim ?\n str.trim() : str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, '');\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n *\n * @param {Boolean} [allOwnKeys = false]\n * @returns {any}\n */\nfunction forEach(obj, fn, {allOwnKeys = false} = {}) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n let i;\n let l;\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Buffer check\n if (isBuffer(obj)) {\n return;\n }\n\n // Iterate over object keys\n const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);\n const len = keys.length;\n let key;\n\n for (i = 0; i < len; i++) {\n key = keys[i];\n fn.call(null, obj[key], key, obj);\n }\n }\n}\n\nfunction findKey(obj, key) {\n if (isBuffer(obj)){\n return null;\n }\n\n key = key.toLowerCase();\n const keys = Object.keys(obj);\n let i = keys.length;\n let _key;\n while (i-- > 0) {\n _key = keys[i];\n if (key === _key.toLowerCase()) {\n return _key;\n }\n }\n return null;\n}\n\nconst _global = (() => {\n /*eslint no-undef:0*/\n if (typeof globalThis !== \"undefined\") return globalThis;\n return typeof self !== \"undefined\" ? self : (typeof window !== 'undefined' ? window : global)\n})();\n\nconst isContextDefined = (context) => !isUndefined(context) && context !== _global;\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n *\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n const {caseless, skipUndefined} = isContextDefined(this) && this || {};\n const result = {};\n const assignValue = (val, key) => {\n const targetKey = caseless && findKey(result, key) || key;\n if (isPlainObject(result[targetKey]) && isPlainObject(val)) {\n result[targetKey] = merge(result[targetKey], val);\n } else if (isPlainObject(val)) {\n result[targetKey] = merge({}, val);\n } else if (isArray(val)) {\n result[targetKey] = val.slice();\n } else if (!skipUndefined || !isUndefined(val)) {\n result[targetKey] = val;\n }\n }\n\n for (let i = 0, l = arguments.length; i < l; i++) {\n arguments[i] && forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n *\n * @param {Boolean} [allOwnKeys]\n * @returns {Object} The resulting value of object a\n */\nconst extend = (a, b, thisArg, {allOwnKeys}= {}) => {\n forEach(b, (val, key) => {\n if (thisArg && isFunction(val)) {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n }, {allOwnKeys});\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n *\n * @returns {string} content value without BOM\n */\nconst stripBOM = (content) => {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n *\n * @returns {void}\n */\nconst inherits = (constructor, superConstructor, props, descriptors) => {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n Object.defineProperty(constructor, 'super', {\n value: superConstructor.prototype\n });\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function|Boolean} [filter]\n * @param {Function} [propFilter]\n *\n * @returns {Object}\n */\nconst toFlatObject = (sourceObj, destObj, filter, propFilter) => {\n let props;\n let i;\n let prop;\n const merged = {};\n\n destObj = destObj || {};\n // eslint-disable-next-line no-eq-null,eqeqeq\n if (sourceObj == null) return destObj;\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = filter !== false && getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/**\n * Determines whether a string ends with the characters of a specified string\n *\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n *\n * @returns {boolean}\n */\nconst endsWith = (str, searchString, position) => {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n const lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object or null if failed\n *\n * @param {*} [thing]\n *\n * @returns {?Array}\n */\nconst toArray = (thing) => {\n if (!thing) return null;\n if (isArray(thing)) return thing;\n let i = thing.length;\n if (!isNumber(i)) return null;\n const arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n/**\n * Checking if the Uint8Array exists and if it does, it returns a function that checks if the\n * thing passed in is an instance of Uint8Array\n *\n * @param {TypedArray}\n *\n * @returns {Array}\n */\n// eslint-disable-next-line func-names\nconst isTypedArray = (TypedArray => {\n // eslint-disable-next-line func-names\n return thing => {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array));\n\n/**\n * For each entry in the object, call the function with the key and value.\n *\n * @param {Object} obj - The object to iterate over.\n * @param {Function} fn - The function to call for each entry.\n *\n * @returns {void}\n */\nconst forEachEntry = (obj, fn) => {\n const generator = obj && obj[iterator];\n\n const _iterator = generator.call(obj);\n\n let result;\n\n while ((result = _iterator.next()) && !result.done) {\n const pair = result.value;\n fn.call(obj, pair[0], pair[1]);\n }\n}\n\n/**\n * It takes a regular expression and a string, and returns an array of all the matches\n *\n * @param {string} regExp - The regular expression to match against.\n * @param {string} str - The string to search.\n *\n * @returns {Array}\n */\nconst matchAll = (regExp, str) => {\n let matches;\n const arr = [];\n\n while ((matches = regExp.exec(str)) !== null) {\n arr.push(matches);\n }\n\n return arr;\n}\n\n/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */\nconst isHTMLForm = kindOfTest('HTMLFormElement');\n\nconst toCamelCase = str => {\n return str.toLowerCase().replace(/[-_\\s]([a-z\\d])(\\w*)/g,\n function replacer(m, p1, p2) {\n return p1.toUpperCase() + p2;\n }\n );\n};\n\n/* Creating a function that will check if an object has a property. */\nconst hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype);\n\n/**\n * Determine if a value is a RegExp object\n *\n * @param {*} val The value to test\n *\n * @returns {boolean} True if value is a RegExp object, otherwise false\n */\nconst isRegExp = kindOfTest('RegExp');\n\nconst reduceDescriptors = (obj, reducer) => {\n const descriptors = Object.getOwnPropertyDescriptors(obj);\n const reducedDescriptors = {};\n\n forEach(descriptors, (descriptor, name) => {\n let ret;\n if ((ret = reducer(descriptor, name, obj)) !== false) {\n reducedDescriptors[name] = ret || descriptor;\n }\n });\n\n Object.defineProperties(obj, reducedDescriptors);\n}\n\n/**\n * Makes all methods read-only\n * @param {Object} obj\n */\n\nconst freezeMethods = (obj) => {\n reduceDescriptors(obj, (descriptor, name) => {\n // skip restricted props in strict mode\n if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) {\n return false;\n }\n\n const value = obj[name];\n\n if (!isFunction(value)) return;\n\n descriptor.enumerable = false;\n\n if ('writable' in descriptor) {\n descriptor.writable = false;\n return;\n }\n\n if (!descriptor.set) {\n descriptor.set = () => {\n throw Error('Can not rewrite read-only method \\'' + name + '\\'');\n };\n }\n });\n}\n\nconst toObjectSet = (arrayOrString, delimiter) => {\n const obj = {};\n\n const define = (arr) => {\n arr.forEach(value => {\n obj[value] = true;\n });\n }\n\n isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter));\n\n return obj;\n}\n\nconst noop = () => {}\n\nconst toFiniteNumber = (value, defaultValue) => {\n return value != null && Number.isFinite(value = +value) ? value : defaultValue;\n}\n\n\n\n/**\n * If the thing is a FormData object, return true, otherwise return false.\n *\n * @param {unknown} thing - The thing to check.\n *\n * @returns {boolean}\n */\nfunction isSpecCompliantForm(thing) {\n return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]);\n}\n\nconst toJSONObject = (obj) => {\n const stack = new Array(10);\n\n const visit = (source, i) => {\n\n if (isObject(source)) {\n if (stack.indexOf(source) >= 0) {\n return;\n }\n\n //Buffer check\n if (isBuffer(source)) {\n return source;\n }\n\n if(!('toJSON' in source)) {\n stack[i] = source;\n const target = isArray(source) ? [] : {};\n\n forEach(source, (value, key) => {\n const reducedValue = visit(value, i + 1);\n !isUndefined(reducedValue) && (target[key] = reducedValue);\n });\n\n stack[i] = undefined;\n\n return target;\n }\n }\n\n return source;\n }\n\n return visit(obj, 0);\n}\n\nconst isAsyncFn = kindOfTest('AsyncFunction');\n\nconst isThenable = (thing) =>\n thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch);\n\n// original code\n// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34\n\nconst _setImmediate = ((setImmediateSupported, postMessageSupported) => {\n if (setImmediateSupported) {\n return setImmediate;\n }\n\n return postMessageSupported ? ((token, callbacks) => {\n _global.addEventListener(\"message\", ({source, data}) => {\n if (source === _global && data === token) {\n callbacks.length && callbacks.shift()();\n }\n }, false);\n\n return (cb) => {\n callbacks.push(cb);\n _global.postMessage(token, \"*\");\n }\n })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb);\n})(\n typeof setImmediate === 'function',\n isFunction(_global.postMessage)\n);\n\nconst asap = typeof queueMicrotask !== 'undefined' ?\n queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate);\n\n// *********************\n\n\nconst isIterable = (thing) => thing != null && isFunction(thing[iterator]);\n\n\nexport default {\n isArray,\n isArrayBuffer,\n isBuffer,\n isFormData,\n isArrayBufferView,\n isString,\n isNumber,\n isBoolean,\n isObject,\n isPlainObject,\n isEmptyObject,\n isReadableStream,\n isRequest,\n isResponse,\n isHeaders,\n isUndefined,\n isDate,\n isFile,\n isBlob,\n isRegExp,\n isFunction,\n isStream,\n isURLSearchParams,\n isTypedArray,\n isFileList,\n forEach,\n merge,\n extend,\n trim,\n stripBOM,\n inherits,\n toFlatObject,\n kindOf,\n kindOfTest,\n endsWith,\n toArray,\n forEachEntry,\n matchAll,\n isHTMLForm,\n hasOwnProperty,\n hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection\n reduceDescriptors,\n freezeMethods,\n toObjectSet,\n toCamelCase,\n noop,\n toFiniteNumber,\n findKey,\n global: _global,\n isContextDefined,\n isSpecCompliantForm,\n toJSONObject,\n isAsyncFn,\n isThenable,\n setImmediate: _setImmediate,\n asap,\n isIterable\n};\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n *\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n } else {\n this.stack = (new Error()).stack;\n }\n\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n if (response) {\n this.response = response;\n this.status = response.status ? response.status : null;\n }\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: utils.toJSONObject(this.config),\n code: this.code,\n status: this.status\n };\n }\n});\n\nconst prototype = AxiosError.prototype;\nconst descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED',\n 'ERR_NOT_SUPPORT',\n 'ERR_INVALID_URL'\n// eslint-disable-next-line func-names\n].forEach(code => {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = (error, code, config, request, response, customProps) => {\n const axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n }, prop => {\n return prop !== 'isAxiosError';\n });\n\n const msg = error && error.message ? error.message : 'Error';\n\n // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED)\n const errCode = code == null && error ? error.code : code;\n AxiosError.call(axiosError, msg, errCode, config, request, response);\n\n // Chain the original error on the standard field; non-enumerable to avoid JSON noise\n if (error && axiosError.cause == null) {\n Object.defineProperty(axiosError, 'cause', { value: error, configurable: true });\n }\n\n axiosError.name = (error && error.name) || 'Error';\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nexport default AxiosError;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\n// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored\nimport PlatformFormData from '../platform/node/classes/FormData.js';\n\n/**\n * Determines if the given thing is a array or js object.\n *\n * @param {string} thing - The object or array to be visited.\n *\n * @returns {boolean}\n */\nfunction isVisitable(thing) {\n return utils.isPlainObject(thing) || utils.isArray(thing);\n}\n\n/**\n * It removes the brackets from the end of a string\n *\n * @param {string} key - The key of the parameter.\n *\n * @returns {string} the key without the brackets.\n */\nfunction removeBrackets(key) {\n return utils.endsWith(key, '[]') ? key.slice(0, -2) : key;\n}\n\n/**\n * It takes a path, a key, and a boolean, and returns a string\n *\n * @param {string} path - The path to the current key.\n * @param {string} key - The key of the current object being iterated over.\n * @param {string} dots - If true, the key will be rendered with dots instead of brackets.\n *\n * @returns {string} The path to the current key.\n */\nfunction renderKey(path, key, dots) {\n if (!path) return key;\n return path.concat(key).map(function each(token, i) {\n // eslint-disable-next-line no-param-reassign\n token = removeBrackets(token);\n return !dots && i ? '[' + token + ']' : token;\n }).join(dots ? '.' : '');\n}\n\n/**\n * If the array is an array and none of its elements are visitable, then it's a flat array.\n *\n * @param {Array} arr - The array to check\n *\n * @returns {boolean}\n */\nfunction isFlatArray(arr) {\n return utils.isArray(arr) && !arr.some(isVisitable);\n}\n\nconst predicates = utils.toFlatObject(utils, {}, null, function filter(prop) {\n return /^is[A-Z]/.test(prop);\n});\n\n/**\n * Convert a data object to FormData\n *\n * @param {Object} obj\n * @param {?Object} [formData]\n * @param {?Object} [options]\n * @param {Function} [options.visitor]\n * @param {Boolean} [options.metaTokens = true]\n * @param {Boolean} [options.dots = false]\n * @param {?Boolean} [options.indexes = false]\n *\n * @returns {Object}\n **/\n\n/**\n * It converts an object into a FormData object\n *\n * @param {Object} obj - The object to convert to form data.\n * @param {string} formData - The FormData object to append to.\n * @param {Object} options\n *\n * @returns\n */\nfunction toFormData(obj, formData, options) {\n if (!utils.isObject(obj)) {\n throw new TypeError('target must be an object');\n }\n\n // eslint-disable-next-line no-param-reassign\n formData = formData || new (PlatformFormData || FormData)();\n\n // eslint-disable-next-line no-param-reassign\n options = utils.toFlatObject(options, {\n metaTokens: true,\n dots: false,\n indexes: false\n }, false, function defined(option, source) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n return !utils.isUndefined(source[option]);\n });\n\n const metaTokens = options.metaTokens;\n // eslint-disable-next-line no-use-before-define\n const visitor = options.visitor || defaultVisitor;\n const dots = options.dots;\n const indexes = options.indexes;\n const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob;\n const useBlob = _Blob && utils.isSpecCompliantForm(formData);\n\n if (!utils.isFunction(visitor)) {\n throw new TypeError('visitor must be a function');\n }\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isBoolean(value)) {\n return value.toString();\n }\n\n if (!useBlob && utils.isBlob(value)) {\n throw new AxiosError('Blob is not supported. Use a Buffer instead.');\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n /**\n * Default visitor.\n *\n * @param {*} value\n * @param {String|Number} key\n * @param {Array} path\n * @this {FormData}\n *\n * @returns {boolean} return true to visit the each prop of the value recursively\n */\n function defaultVisitor(value, key, path) {\n let arr = value;\n\n if (value && !path && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n key = metaTokens ? key : key.slice(0, -2);\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (\n (utils.isArray(value) && isFlatArray(value)) ||\n ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value))\n )) {\n // eslint-disable-next-line no-param-reassign\n key = removeBrackets(key);\n\n arr.forEach(function each(el, index) {\n !(utils.isUndefined(el) || el === null) && formData.append(\n // eslint-disable-next-line no-nested-ternary\n indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'),\n convertValue(el)\n );\n });\n return false;\n }\n }\n\n if (isVisitable(value)) {\n return true;\n }\n\n formData.append(renderKey(path, key, dots), convertValue(value));\n\n return false;\n }\n\n const stack = [];\n\n const exposedHelpers = Object.assign(predicates, {\n defaultVisitor,\n convertValue,\n isVisitable\n });\n\n function build(value, path) {\n if (utils.isUndefined(value)) return;\n\n if (stack.indexOf(value) !== -1) {\n throw Error('Circular reference detected in ' + path.join('.'));\n }\n\n stack.push(value);\n\n utils.forEach(value, function each(el, key) {\n const result = !(utils.isUndefined(el) || el === null) && visitor.call(\n formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers\n );\n\n if (result === true) {\n build(el, path ? path.concat(key) : [key]);\n }\n });\n\n stack.pop();\n }\n\n if (!utils.isObject(obj)) {\n throw new TypeError('data must be an object');\n }\n\n build(obj);\n\n return formData;\n}\n\nexport default toFormData;\n","'use strict';\n\nimport toFormData from './toFormData.js';\n\n/**\n * It encodes a string by replacing all characters that are not in the unreserved set with\n * their percent-encoded equivalents\n *\n * @param {string} str - The string to encode.\n *\n * @returns {string} The encoded string.\n */\nfunction encode(str) {\n const charMap = {\n '!': '%21',\n \"'\": '%27',\n '(': '%28',\n ')': '%29',\n '~': '%7E',\n '%20': '+',\n '%00': '\\x00'\n };\n return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) {\n return charMap[match];\n });\n}\n\n/**\n * It takes a params object and converts it to a FormData object\n *\n * @param {Object} params - The parameters to be converted to a FormData object.\n * @param {Object} options - The options object passed to the Axios constructor.\n *\n * @returns {void}\n */\nfunction AxiosURLSearchParams(params, options) {\n this._pairs = [];\n\n params && toFormData(params, this, options);\n}\n\nconst prototype = AxiosURLSearchParams.prototype;\n\nprototype.append = function append(name, value) {\n this._pairs.push([name, value]);\n};\n\nprototype.toString = function toString(encoder) {\n const _encode = encoder ? function(value) {\n return encoder.call(this, value, encode);\n } : encode;\n\n return this._pairs.map(function each(pair) {\n return _encode(pair[0]) + '=' + _encode(pair[1]);\n }, '').join('&');\n};\n\nexport default AxiosURLSearchParams;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js';\n\n/**\n * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their\n * URI encoded counterparts\n *\n * @param {string} val The value to be encoded.\n *\n * @returns {string} The encoded value.\n */\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @param {?(object|Function)} options\n *\n * @returns {string} The formatted url\n */\nexport default function buildURL(url, params, options) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n \n const _encode = options && options.encode || encode;\n\n if (utils.isFunction(options)) {\n options = {\n serialize: options\n };\n } \n\n const serializeFn = options && options.serialize;\n\n let serializedParams;\n\n if (serializeFn) {\n serializedParams = serializeFn(params, options);\n } else {\n serializedParams = utils.isURLSearchParams(params) ?\n params.toString() :\n new AxiosURLSearchParams(params, options).toString(_encode);\n }\n\n if (serializedParams) {\n const hashmarkIndex = url.indexOf(\"#\");\n\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\nclass InterceptorManager {\n constructor() {\n this.handlers = [];\n }\n\n /**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\n use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled,\n rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n }\n\n /**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n *\n * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise\n */\n eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n }\n\n /**\n * Clear all interceptors from the stack\n *\n * @returns {void}\n */\n clear() {\n if (this.handlers) {\n this.handlers = [];\n }\n }\n\n /**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n *\n * @returns {void}\n */\n forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n }\n}\n\nexport default InterceptorManager;\n","'use strict';\n\nexport default {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n","'use strict';\n\nimport url from 'url';\nexport default url.URLSearchParams;\n","import crypto from 'crypto';\nimport URLSearchParams from './classes/URLSearchParams.js'\nimport FormData from './classes/FormData.js'\n\nconst ALPHA = 'abcdefghijklmnopqrstuvwxyz'\n\nconst DIGIT = '0123456789';\n\nconst ALPHABET = {\n DIGIT,\n ALPHA,\n ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT\n}\n\nconst generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {\n let str = '';\n const {length} = alphabet;\n const randomValues = new Uint32Array(size);\n crypto.randomFillSync(randomValues);\n for (let i = 0; i < size; i++) {\n str += alphabet[randomValues[i] % length];\n }\n\n return str;\n}\n\n\nexport default {\n isNode: true,\n classes: {\n URLSearchParams,\n FormData,\n Blob: typeof Blob !== 'undefined' && Blob || null\n },\n ALPHABET,\n generateString,\n protocols: [ 'http', 'https', 'file', 'data' ]\n};\n","const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined';\n\nconst _navigator = typeof navigator === 'object' && navigator || undefined;\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n *\n * @returns {boolean}\n */\nconst hasStandardBrowserEnv = hasBrowserEnv &&\n (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0);\n\n/**\n * Determine if we're running in a standard browser webWorker environment\n *\n * Although the `isStandardBrowserEnv` method indicates that\n * `allows axios to run in a web worker`, the WebWorker will still be\n * filtered out due to its judgment standard\n * `typeof window !== 'undefined' && typeof document !== 'undefined'`.\n * This leads to a problem when axios post `FormData` in webWorker\n */\nconst hasStandardBrowserWebWorkerEnv = (() => {\n return (\n typeof WorkerGlobalScope !== 'undefined' &&\n // eslint-disable-next-line no-undef\n self instanceof WorkerGlobalScope &&\n typeof self.importScripts === 'function'\n );\n})();\n\nconst origin = hasBrowserEnv && window.location.href || 'http://localhost';\n\nexport {\n hasBrowserEnv,\n hasStandardBrowserWebWorkerEnv,\n hasStandardBrowserEnv,\n _navigator as navigator,\n origin\n}\n","import platform from './node/index.js';\nimport * as utils from './common/utils.js';\n\nexport default {\n ...utils,\n ...platform\n}\n","'use strict';\n\nimport utils from '../utils.js';\nimport toFormData from './toFormData.js';\nimport platform from '../platform/index.js';\n\nexport default function toURLEncodedForm(data, options) {\n return toFormData(data, new platform.classes.URLSearchParams(), {\n visitor: function(value, key, path, helpers) {\n if (platform.isNode && utils.isBuffer(value)) {\n this.append(key, value.toString('base64'));\n return false;\n }\n\n return helpers.defaultVisitor.apply(this, arguments);\n },\n ...options\n });\n}\n","'use strict';\n\nimport utils from '../utils.js';\n\n/**\n * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z']\n *\n * @param {string} name - The name of the property to get.\n *\n * @returns An array of strings.\n */\nfunction parsePropPath(name) {\n // foo[x][y][z]\n // foo.x.y.z\n // foo-x-y-z\n // foo x y z\n return utils.matchAll(/\\w+|\\[(\\w*)]/g, name).map(match => {\n return match[0] === '[]' ? '' : match[1] || match[0];\n });\n}\n\n/**\n * Convert an array to an object.\n *\n * @param {Array} arr - The array to convert to an object.\n *\n * @returns An object with the same keys and values as the array.\n */\nfunction arrayToObject(arr) {\n const obj = {};\n const keys = Object.keys(arr);\n let i;\n const len = keys.length;\n let key;\n for (i = 0; i < len; i++) {\n key = keys[i];\n obj[key] = arr[key];\n }\n return obj;\n}\n\n/**\n * It takes a FormData object and returns a JavaScript object\n *\n * @param {string} formData The FormData object to convert to JSON.\n *\n * @returns {Object | null} The converted object.\n */\nfunction formDataToJSON(formData) {\n function buildPath(path, value, target, index) {\n let name = path[index++];\n\n if (name === '__proto__') return true;\n\n const isNumericKey = Number.isFinite(+name);\n const isLast = index >= path.length;\n name = !name && utils.isArray(target) ? target.length : name;\n\n if (isLast) {\n if (utils.hasOwnProp(target, name)) {\n target[name] = [target[name], value];\n } else {\n target[name] = value;\n }\n\n return !isNumericKey;\n }\n\n if (!target[name] || !utils.isObject(target[name])) {\n target[name] = [];\n }\n\n const result = buildPath(path, value, target[name], index);\n\n if (result && utils.isArray(target[name])) {\n target[name] = arrayToObject(target[name]);\n }\n\n return !isNumericKey;\n }\n\n if (utils.isFormData(formData) && utils.isFunction(formData.entries)) {\n const obj = {};\n\n utils.forEachEntry(formData, (name, value) => {\n buildPath(parsePropPath(name), value, obj, 0);\n });\n\n return obj;\n }\n\n return null;\n}\n\nexport default formDataToJSON;\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosError from '../core/AxiosError.js';\nimport transitionalDefaults from './transitional.js';\nimport toFormData from '../helpers/toFormData.js';\nimport toURLEncodedForm from '../helpers/toURLEncodedForm.js';\nimport platform from '../platform/index.js';\nimport formDataToJSON from '../helpers/formDataToJSON.js';\n\n/**\n * It takes a string, tries to parse it, and if it fails, it returns the stringified version\n * of the input\n *\n * @param {any} rawValue - The value to be stringified.\n * @param {Function} parser - A function that parses a string into a JavaScript object.\n * @param {Function} encoder - A function that takes a value and returns a string.\n *\n * @returns {string} A stringified version of the rawValue.\n */\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nconst defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: ['xhr', 'http', 'fetch'],\n\n transformRequest: [function transformRequest(data, headers) {\n const contentType = headers.getContentType() || '';\n const hasJSONContentType = contentType.indexOf('application/json') > -1;\n const isObjectPayload = utils.isObject(data);\n\n if (isObjectPayload && utils.isHTMLForm(data)) {\n data = new FormData(data);\n }\n\n const isFormData = utils.isFormData(data);\n\n if (isFormData) {\n return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data;\n }\n\n if (utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data) ||\n utils.isReadableStream(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false);\n return data.toString();\n }\n\n let isFileList;\n\n if (isObjectPayload) {\n if (contentType.indexOf('application/x-www-form-urlencoded') > -1) {\n return toURLEncodedForm(data, this.formSerializer).toString();\n }\n\n if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) {\n const _FormData = this.env && this.env.FormData;\n\n return toFormData(\n isFileList ? {'files[]': data} : data,\n _FormData && new _FormData(),\n this.formSerializer\n );\n }\n }\n\n if (isObjectPayload || hasJSONContentType ) {\n headers.setContentType('application/json', false);\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n const transitional = this.transitional || defaults.transitional;\n const forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n const JSONRequested = this.responseType === 'json';\n\n if (utils.isResponse(data) || utils.isReadableStream(data)) {\n return data;\n }\n\n if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) {\n const silentJSONParsing = transitional && transitional.silentJSONParsing;\n const strictJSONParsing = !silentJSONParsing && JSONRequested;\n\n try {\n return JSON.parse(data, this.parseReviver);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: platform.classes.FormData,\n Blob: platform.classes.Blob\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*',\n 'Content-Type': undefined\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {\n defaults.headers[method] = {};\n});\n\nexport default defaults;\n","'use strict';\n\nimport utils from './../utils.js';\n\n// RawAxiosHeaders whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nconst ignoreDuplicateOf = utils.toObjectSet([\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n]);\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} rawHeaders Headers needing to be parsed\n *\n * @returns {Object} Headers parsed into an object\n */\nexport default rawHeaders => {\n const parsed = {};\n let key;\n let val;\n let i;\n\n rawHeaders && rawHeaders.split('\\n').forEach(function parser(line) {\n i = line.indexOf(':');\n key = line.substring(0, i).trim().toLowerCase();\n val = line.substring(i + 1).trim();\n\n if (!key || (parsed[key] && ignoreDuplicateOf[key])) {\n return;\n }\n\n if (key === 'set-cookie') {\n if (parsed[key]) {\n parsed[key].push(val);\n } else {\n parsed[key] = [val];\n }\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n });\n\n return parsed;\n};\n","'use strict';\n\nimport utils from '../utils.js';\nimport parseHeaders from '../helpers/parseHeaders.js';\n\nconst $internals = Symbol('internals');\n\nfunction normalizeHeader(header) {\n return header && String(header).trim().toLowerCase();\n}\n\nfunction normalizeValue(value) {\n if (value === false || value == null) {\n return value;\n }\n\n return utils.isArray(value) ? value.map(normalizeValue) : String(value);\n}\n\nfunction parseTokens(str) {\n const tokens = Object.create(null);\n const tokensRE = /([^\\s,;=]+)\\s*(?:=\\s*([^,;]+))?/g;\n let match;\n\n while ((match = tokensRE.exec(str))) {\n tokens[match[1]] = match[2];\n }\n\n return tokens;\n}\n\nconst isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim());\n\nfunction matchHeaderValue(context, value, header, filter, isHeaderNameFilter) {\n if (utils.isFunction(filter)) {\n return filter.call(this, value, header);\n }\n\n if (isHeaderNameFilter) {\n value = header;\n }\n\n if (!utils.isString(value)) return;\n\n if (utils.isString(filter)) {\n return value.indexOf(filter) !== -1;\n }\n\n if (utils.isRegExp(filter)) {\n return filter.test(value);\n }\n}\n\nfunction formatHeader(header) {\n return header.trim()\n .toLowerCase().replace(/([a-z\\d])(\\w*)/g, (w, char, str) => {\n return char.toUpperCase() + str;\n });\n}\n\nfunction buildAccessors(obj, header) {\n const accessorName = utils.toCamelCase(' ' + header);\n\n ['get', 'set', 'has'].forEach(methodName => {\n Object.defineProperty(obj, methodName + accessorName, {\n value: function(arg1, arg2, arg3) {\n return this[methodName].call(this, header, arg1, arg2, arg3);\n },\n configurable: true\n });\n });\n}\n\nclass AxiosHeaders {\n constructor(headers) {\n headers && this.set(headers);\n }\n\n set(header, valueOrRewrite, rewrite) {\n const self = this;\n\n function setHeader(_value, _header, _rewrite) {\n const lHeader = normalizeHeader(_header);\n\n if (!lHeader) {\n throw new Error('header name must be a non-empty string');\n }\n\n const key = utils.findKey(self, lHeader);\n\n if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) {\n self[key || _header] = normalizeValue(_value);\n }\n }\n\n const setHeaders = (headers, _rewrite) =>\n utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));\n\n if (utils.isPlainObject(header) || header instanceof this.constructor) {\n setHeaders(header, valueOrRewrite)\n } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {\n setHeaders(parseHeaders(header), valueOrRewrite);\n } else if (utils.isObject(header) && utils.isIterable(header)) {\n let obj = {}, dest, key;\n for (const entry of header) {\n if (!utils.isArray(entry)) {\n throw TypeError('Object iterator must return a key-value pair');\n }\n\n obj[key = entry[0]] = (dest = obj[key]) ?\n (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1];\n }\n\n setHeaders(obj, valueOrRewrite)\n } else {\n header != null && setHeader(valueOrRewrite, header, rewrite);\n }\n\n return this;\n }\n\n get(header, parser) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n if (key) {\n const value = this[key];\n\n if (!parser) {\n return value;\n }\n\n if (parser === true) {\n return parseTokens(value);\n }\n\n if (utils.isFunction(parser)) {\n return parser.call(this, value, key);\n }\n\n if (utils.isRegExp(parser)) {\n return parser.exec(value);\n }\n\n throw new TypeError('parser must be boolean|regexp|function');\n }\n }\n }\n\n has(header, matcher) {\n header = normalizeHeader(header);\n\n if (header) {\n const key = utils.findKey(this, header);\n\n return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher)));\n }\n\n return false;\n }\n\n delete(header, matcher) {\n const self = this;\n let deleted = false;\n\n function deleteHeader(_header) {\n _header = normalizeHeader(_header);\n\n if (_header) {\n const key = utils.findKey(self, _header);\n\n if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) {\n delete self[key];\n\n deleted = true;\n }\n }\n }\n\n if (utils.isArray(header)) {\n header.forEach(deleteHeader);\n } else {\n deleteHeader(header);\n }\n\n return deleted;\n }\n\n clear(matcher) {\n const keys = Object.keys(this);\n let i = keys.length;\n let deleted = false;\n\n while (i--) {\n const key = keys[i];\n if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) {\n delete this[key];\n deleted = true;\n }\n }\n\n return deleted;\n }\n\n normalize(format) {\n const self = this;\n const headers = {};\n\n utils.forEach(this, (value, header) => {\n const key = utils.findKey(headers, header);\n\n if (key) {\n self[key] = normalizeValue(value);\n delete self[header];\n return;\n }\n\n const normalized = format ? formatHeader(header) : String(header).trim();\n\n if (normalized !== header) {\n delete self[header];\n }\n\n self[normalized] = normalizeValue(value);\n\n headers[normalized] = true;\n });\n\n return this;\n }\n\n concat(...targets) {\n return this.constructor.concat(this, ...targets);\n }\n\n toJSON(asStrings) {\n const obj = Object.create(null);\n\n utils.forEach(this, (value, header) => {\n value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value);\n });\n\n return obj;\n }\n\n [Symbol.iterator]() {\n return Object.entries(this.toJSON())[Symbol.iterator]();\n }\n\n toString() {\n return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\\n');\n }\n\n getSetCookie() {\n return this.get(\"set-cookie\") || [];\n }\n\n get [Symbol.toStringTag]() {\n return 'AxiosHeaders';\n }\n\n static from(thing) {\n return thing instanceof this ? thing : new this(thing);\n }\n\n static concat(first, ...targets) {\n const computed = new this(first);\n\n targets.forEach((target) => computed.set(target));\n\n return computed;\n }\n\n static accessor(header) {\n const internals = this[$internals] = (this[$internals] = {\n accessors: {}\n });\n\n const accessors = internals.accessors;\n const prototype = this.prototype;\n\n function defineAccessor(_header) {\n const lHeader = normalizeHeader(_header);\n\n if (!accessors[lHeader]) {\n buildAccessors(prototype, _header);\n accessors[lHeader] = true;\n }\n }\n\n utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);\n\n return this;\n }\n}\n\nAxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);\n\n// reserved names hotfix\nutils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {\n let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`\n return {\n get: () => value,\n set(headerValue) {\n this[mapped] = headerValue;\n }\n }\n});\n\nutils.freezeMethods(AxiosHeaders);\n\nexport default AxiosHeaders;\n","'use strict';\n\nimport utils from './../utils.js';\nimport defaults from '../defaults/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Array|Function} fns A single function or Array of functions\n * @param {?Object} response The response object\n *\n * @returns {*} The resulting transformed data\n */\nexport default function transformData(fns, response) {\n const config = this || defaults;\n const context = response || config;\n const headers = AxiosHeaders.from(context.headers);\n let data = context.data;\n\n utils.forEach(fns, function transform(fn) {\n data = fn.call(config, data, headers.normalize(), response ? response.status : undefined);\n });\n\n headers.normalize();\n\n return data;\n}\n","'use strict';\n\nexport default function isCancel(value) {\n return !!(value && value.__CANCEL__);\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport utils from '../utils.js';\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @param {string=} message The message.\n * @param {Object=} config The config.\n * @param {Object=} request The request.\n *\n * @returns {CanceledError} The created error.\n */\nfunction CanceledError(message, config, request) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nexport default CanceledError;\n","'use strict';\n\nimport AxiosError from './AxiosError.js';\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n *\n * @returns {object} The response.\n */\nexport default function settle(resolve, reject, response) {\n const validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n}\n","'use strict';\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n *\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nexport default function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n}\n","'use strict';\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n *\n * @returns {string} The combined URL\n */\nexport default function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/?\\/$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n}\n","'use strict';\n\nimport isAbsoluteURL from '../helpers/isAbsoluteURL.js';\nimport combineURLs from '../helpers/combineURLs.js';\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n *\n * @returns {string} The combined full path\n */\nexport default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) {\n let isRelativeUrl = !isAbsoluteURL(requestedURL);\n if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n}\n","export const VERSION = \"1.12.2\";","'use strict';\n\nexport default function parseProtocol(url) {\n const match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n}\n","'use strict';\n\nimport AxiosError from '../core/AxiosError.js';\nimport parseProtocol from './parseProtocol.js';\nimport platform from '../platform/index.js';\n\nconst DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\\s\\S]*)$/;\n\n/**\n * Parse data uri to a Buffer or Blob\n *\n * @param {String} uri\n * @param {?Boolean} asBlob\n * @param {?Object} options\n * @param {?Function} options.Blob\n *\n * @returns {Buffer|Blob}\n */\nexport default function fromDataURI(uri, asBlob, options) {\n const _Blob = options && options.Blob || platform.classes.Blob;\n const protocol = parseProtocol(uri);\n\n if (asBlob === undefined && _Blob) {\n asBlob = true;\n }\n\n if (protocol === 'data') {\n uri = protocol.length ? uri.slice(protocol.length + 1) : uri;\n\n const match = DATA_URL_PATTERN.exec(uri);\n\n if (!match) {\n throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL);\n }\n\n const mime = match[1];\n const isBase64 = match[2];\n const body = match[3];\n const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8');\n\n if (asBlob) {\n if (!_Blob) {\n throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT);\n }\n\n return new _Blob([buffer], {type: mime});\n }\n\n return buffer;\n }\n\n throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT);\n}\n","'use strict';\n\nimport stream from 'stream';\nimport utils from '../utils.js';\n\nconst kInternals = Symbol('internals');\n\nclass AxiosTransformStream extends stream.Transform{\n constructor(options) {\n options = utils.toFlatObject(options, {\n maxRate: 0,\n chunkSize: 64 * 1024,\n minChunkSize: 100,\n timeWindow: 500,\n ticksRate: 2,\n samplesCount: 15\n }, null, (prop, source) => {\n return !utils.isUndefined(source[prop]);\n });\n\n super({\n readableHighWaterMark: options.chunkSize\n });\n\n const internals = this[kInternals] = {\n timeWindow: options.timeWindow,\n chunkSize: options.chunkSize,\n maxRate: options.maxRate,\n minChunkSize: options.minChunkSize,\n bytesSeen: 0,\n isCaptured: false,\n notifiedBytesLoaded: 0,\n ts: Date.now(),\n bytes: 0,\n onReadCallback: null\n };\n\n this.on('newListener', event => {\n if (event === 'progress') {\n if (!internals.isCaptured) {\n internals.isCaptured = true;\n }\n }\n });\n }\n\n _read(size) {\n const internals = this[kInternals];\n\n if (internals.onReadCallback) {\n internals.onReadCallback();\n }\n\n return super._read(size);\n }\n\n _transform(chunk, encoding, callback) {\n const internals = this[kInternals];\n const maxRate = internals.maxRate;\n\n const readableHighWaterMark = this.readableHighWaterMark;\n\n const timeWindow = internals.timeWindow;\n\n const divider = 1000 / timeWindow;\n const bytesThreshold = (maxRate / divider);\n const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0;\n\n const pushChunk = (_chunk, _callback) => {\n const bytes = Buffer.byteLength(_chunk);\n internals.bytesSeen += bytes;\n internals.bytes += bytes;\n\n internals.isCaptured && this.emit('progress', internals.bytesSeen);\n\n if (this.push(_chunk)) {\n process.nextTick(_callback);\n } else {\n internals.onReadCallback = () => {\n internals.onReadCallback = null;\n process.nextTick(_callback);\n };\n }\n }\n\n const transformChunk = (_chunk, _callback) => {\n const chunkSize = Buffer.byteLength(_chunk);\n let chunkRemainder = null;\n let maxChunkSize = readableHighWaterMark;\n let bytesLeft;\n let passed = 0;\n\n if (maxRate) {\n const now = Date.now();\n\n if (!internals.ts || (passed = (now - internals.ts)) >= timeWindow) {\n internals.ts = now;\n bytesLeft = bytesThreshold - internals.bytes;\n internals.bytes = bytesLeft < 0 ? -bytesLeft : 0;\n passed = 0;\n }\n\n bytesLeft = bytesThreshold - internals.bytes;\n }\n\n if (maxRate) {\n if (bytesLeft <= 0) {\n // next time window\n return setTimeout(() => {\n _callback(null, _chunk);\n }, timeWindow - passed);\n }\n\n if (bytesLeft < maxChunkSize) {\n maxChunkSize = bytesLeft;\n }\n }\n\n if (maxChunkSize && chunkSize > maxChunkSize && (chunkSize - maxChunkSize) > minChunkSize) {\n chunkRemainder = _chunk.subarray(maxChunkSize);\n _chunk = _chunk.subarray(0, maxChunkSize);\n }\n\n pushChunk(_chunk, chunkRemainder ? () => {\n process.nextTick(_callback, null, chunkRemainder);\n } : _callback);\n };\n\n transformChunk(chunk, function transformNextChunk(err, _chunk) {\n if (err) {\n return callback(err);\n }\n\n if (_chunk) {\n transformChunk(_chunk, transformNextChunk);\n } else {\n callback(null);\n }\n });\n }\n}\n\nexport default AxiosTransformStream;\n","const {asyncIterator} = Symbol;\n\nconst readBlob = async function* (blob) {\n if (blob.stream) {\n yield* blob.stream()\n } else if (blob.arrayBuffer) {\n yield await blob.arrayBuffer()\n } else if (blob[asyncIterator]) {\n yield* blob[asyncIterator]();\n } else {\n yield blob;\n }\n}\n\nexport default readBlob;\n","import util from 'util';\nimport {Readable} from 'stream';\nimport utils from \"../utils.js\";\nimport readBlob from \"./readBlob.js\";\nimport platform from \"../platform/index.js\";\n\nconst BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_';\n\nconst textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util.TextEncoder();\n\nconst CRLF = '\\r\\n';\nconst CRLF_BYTES = textEncoder.encode(CRLF);\nconst CRLF_BYTES_COUNT = 2;\n\nclass FormDataPart {\n constructor(name, value) {\n const {escapeName} = this.constructor;\n const isStringValue = utils.isString(value);\n\n let headers = `Content-Disposition: form-data; name=\"${escapeName(name)}\"${\n !isStringValue && value.name ? `; filename=\"${escapeName(value.name)}\"` : ''\n }${CRLF}`;\n\n if (isStringValue) {\n value = textEncoder.encode(String(value).replace(/\\r?\\n|\\r\\n?/g, CRLF));\n } else {\n headers += `Content-Type: ${value.type || \"application/octet-stream\"}${CRLF}`\n }\n\n this.headers = textEncoder.encode(headers + CRLF);\n\n this.contentLength = isStringValue ? value.byteLength : value.size;\n\n this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;\n\n this.name = name;\n this.value = value;\n }\n\n async *encode(){\n yield this.headers;\n\n const {value} = this;\n\n if(utils.isTypedArray(value)) {\n yield value;\n } else {\n yield* readBlob(value);\n }\n\n yield CRLF_BYTES;\n }\n\n static escapeName(name) {\n return String(name).replace(/[\\r\\n\"]/g, (match) => ({\n '\\r' : '%0D',\n '\\n' : '%0A',\n '\"' : '%22',\n }[match]));\n }\n}\n\nconst formDataToStream = (form, headersHandler, options) => {\n const {\n tag = 'form-data-boundary',\n size = 25,\n boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET)\n } = options || {};\n\n if(!utils.isFormData(form)) {\n throw TypeError('FormData instance required');\n }\n\n if (boundary.length < 1 || boundary.length > 70) {\n throw Error('boundary must be 10-70 characters long')\n }\n\n const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);\n const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF);\n let contentLength = footerBytes.byteLength;\n\n const parts = Array.from(form.entries()).map(([name, value]) => {\n const part = new FormDataPart(name, value);\n contentLength += part.size;\n return part;\n });\n\n contentLength += boundaryBytes.byteLength * parts.length;\n\n contentLength = utils.toFiniteNumber(contentLength);\n\n const computedHeaders = {\n 'Content-Type': `multipart/form-data; boundary=${boundary}`\n }\n\n if (Number.isFinite(contentLength)) {\n computedHeaders['Content-Length'] = contentLength;\n }\n\n headersHandler && headersHandler(computedHeaders);\n\n return Readable.from((async function *() {\n for(const part of parts) {\n yield boundaryBytes;\n yield* part.encode();\n }\n\n yield footerBytes;\n })());\n};\n\nexport default formDataToStream;\n","\"use strict\";\n\nimport stream from \"stream\";\n\nclass ZlibHeaderTransformStream extends stream.Transform {\n __transform(chunk, encoding, callback) {\n this.push(chunk);\n callback();\n }\n\n _transform(chunk, encoding, callback) {\n if (chunk.length !== 0) {\n this._transform = this.__transform;\n\n // Add Default Compression headers if no zlib headers are present\n if (chunk[0] !== 120) { // Hex: 78\n const header = Buffer.alloc(2);\n header[0] = 120; // Hex: 78\n header[1] = 156; // Hex: 9C \n this.push(header, encoding);\n }\n }\n\n this.__transform(chunk, encoding, callback);\n }\n}\n\nexport default ZlibHeaderTransformStream;\n","import utils from \"../utils.js\";\n\nconst callbackify = (fn, reducer) => {\n return utils.isAsyncFn(fn) ? function (...args) {\n const cb = args.pop();\n fn.apply(this, args).then((value) => {\n try {\n reducer ? cb(null, ...reducer(value)) : cb(null, value);\n } catch (err) {\n cb(err);\n }\n }, cb);\n } : fn;\n}\n\nexport default callbackify;\n","'use strict';\n\n/**\n * Calculate data maxRate\n * @param {Number} [samplesCount= 10]\n * @param {Number} [min= 1000]\n * @returns {Function}\n */\nfunction speedometer(samplesCount, min) {\n samplesCount = samplesCount || 10;\n const bytes = new Array(samplesCount);\n const timestamps = new Array(samplesCount);\n let head = 0;\n let tail = 0;\n let firstSampleTS;\n\n min = min !== undefined ? min : 1000;\n\n return function push(chunkLength) {\n const now = Date.now();\n\n const startedAt = timestamps[tail];\n\n if (!firstSampleTS) {\n firstSampleTS = now;\n }\n\n bytes[head] = chunkLength;\n timestamps[head] = now;\n\n let i = tail;\n let bytesCount = 0;\n\n while (i !== head) {\n bytesCount += bytes[i++];\n i = i % samplesCount;\n }\n\n head = (head + 1) % samplesCount;\n\n if (head === tail) {\n tail = (tail + 1) % samplesCount;\n }\n\n if (now - firstSampleTS < min) {\n return;\n }\n\n const passed = startedAt && now - startedAt;\n\n return passed ? Math.round(bytesCount * 1000 / passed) : undefined;\n };\n}\n\nexport default speedometer;\n","/**\n * Throttle decorator\n * @param {Function} fn\n * @param {Number} freq\n * @return {Function}\n */\nfunction throttle(fn, freq) {\n let timestamp = 0;\n let threshold = 1000 / freq;\n let lastArgs;\n let timer;\n\n const invoke = (args, now = Date.now()) => {\n timestamp = now;\n lastArgs = null;\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n fn(...args);\n }\n\n const throttled = (...args) => {\n const now = Date.now();\n const passed = now - timestamp;\n if ( passed >= threshold) {\n invoke(args, now);\n } else {\n lastArgs = args;\n if (!timer) {\n timer = setTimeout(() => {\n timer = null;\n invoke(lastArgs)\n }, threshold - passed);\n }\n }\n }\n\n const flush = () => lastArgs && invoke(lastArgs);\n\n return [throttled, flush];\n}\n\nexport default throttle;\n","import speedometer from \"./speedometer.js\";\nimport throttle from \"./throttle.js\";\nimport utils from \"../utils.js\";\n\nexport const progressEventReducer = (listener, isDownloadStream, freq = 3) => {\n let bytesNotified = 0;\n const _speedometer = speedometer(50, 250);\n\n return throttle(e => {\n const loaded = e.loaded;\n const total = e.lengthComputable ? e.total : undefined;\n const progressBytes = loaded - bytesNotified;\n const rate = _speedometer(progressBytes);\n const inRange = loaded <= total;\n\n bytesNotified = loaded;\n\n const data = {\n loaded,\n total,\n progress: total ? (loaded / total) : undefined,\n bytes: progressBytes,\n rate: rate ? rate : undefined,\n estimated: rate && total && inRange ? (total - loaded) / rate : undefined,\n event: e,\n lengthComputable: total != null,\n [isDownloadStream ? 'download' : 'upload']: true\n };\n\n listener(data);\n }, freq);\n}\n\nexport const progressEventDecorator = (total, throttled) => {\n const lengthComputable = total != null;\n\n return [(loaded) => throttled[0]({\n lengthComputable,\n total,\n loaded\n }), throttled[1]];\n}\n\nexport const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args));\n","/**\n * Estimate decoded byte length of a data:// URL *without* allocating large buffers.\n * - For base64: compute exact decoded size using length and padding;\n * handle %XX at the character-count level (no string allocation).\n * - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound.\n *\n * @param {string} url\n * @returns {number}\n */\nexport default function estimateDataURLDecodedBytes(url) {\n if (!url || typeof url !== 'string') return 0;\n if (!url.startsWith('data:')) return 0;\n\n const comma = url.indexOf(',');\n if (comma < 0) return 0;\n\n const meta = url.slice(5, comma);\n const body = url.slice(comma + 1);\n const isBase64 = /;base64/i.test(meta);\n\n if (isBase64) {\n let effectiveLen = body.length;\n const len = body.length; // cache length\n\n for (let i = 0; i < len; i++) {\n if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) {\n const a = body.charCodeAt(i + 1);\n const b = body.charCodeAt(i + 2);\n const isHex =\n ((a >= 48 && a <= 57) || (a >= 65 && a <= 70) || (a >= 97 && a <= 102)) &&\n ((b >= 48 && b <= 57) || (b >= 65 && b <= 70) || (b >= 97 && b <= 102));\n\n if (isHex) {\n effectiveLen -= 2;\n i += 2;\n }\n }\n }\n\n let pad = 0;\n let idx = len - 1;\n\n const tailIsPct3D = (j) =>\n j >= 2 &&\n body.charCodeAt(j - 2) === 37 && // '%'\n body.charCodeAt(j - 1) === 51 && // '3'\n (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd'\n\n if (idx >= 0) {\n if (body.charCodeAt(idx) === 61 /* '=' */) {\n pad++;\n idx--;\n } else if (tailIsPct3D(idx)) {\n pad++;\n idx -= 3;\n }\n }\n\n if (pad === 1 && idx >= 0) {\n if (body.charCodeAt(idx) === 61 /* '=' */) {\n pad++;\n } else if (tailIsPct3D(idx)) {\n pad++;\n }\n }\n\n const groups = Math.floor(effectiveLen / 4);\n const bytes = groups * 3 - (pad || 0);\n return bytes > 0 ? bytes : 0;\n }\n\n return Buffer.byteLength(body, 'utf8');\n}\n","'use strict';\n\nimport utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport buildFullPath from '../core/buildFullPath.js';\nimport buildURL from './../helpers/buildURL.js';\nimport proxyFromEnv from 'proxy-from-env';\nimport http from 'http';\nimport https from 'https';\nimport util from 'util';\nimport followRedirects from 'follow-redirects';\nimport zlib from 'zlib';\nimport {VERSION} from '../env/data.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport platform from '../platform/index.js';\nimport fromDataURI from '../helpers/fromDataURI.js';\nimport stream from 'stream';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport AxiosTransformStream from '../helpers/AxiosTransformStream.js';\nimport {EventEmitter} from 'events';\nimport formDataToStream from \"../helpers/formDataToStream.js\";\nimport readBlob from \"../helpers/readBlob.js\";\nimport ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js';\nimport callbackify from \"../helpers/callbackify.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js';\n\nconst zlibOptions = {\n flush: zlib.constants.Z_SYNC_FLUSH,\n finishFlush: zlib.constants.Z_SYNC_FLUSH\n};\n\nconst brotliOptions = {\n flush: zlib.constants.BROTLI_OPERATION_FLUSH,\n finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH\n}\n\nconst isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress);\n\nconst {http: httpFollow, https: httpsFollow} = followRedirects;\n\nconst isHttps = /https:?/;\n\nconst supportedProtocols = platform.protocols.map(protocol => {\n return protocol + ':';\n});\n\n\nconst flushOnFinish = (stream, [throttled, flush]) => {\n stream\n .on('end', flush)\n .on('error', flush);\n\n return throttled;\n}\n\n\n/**\n * If the proxy or config beforeRedirects functions are defined, call them with the options\n * object.\n *\n * @param {Object} options - The options object that was passed to the request.\n *\n * @returns {Object}\n */\nfunction dispatchBeforeRedirect(options, responseDetails) {\n if (options.beforeRedirects.proxy) {\n options.beforeRedirects.proxy(options);\n }\n if (options.beforeRedirects.config) {\n options.beforeRedirects.config(options, responseDetails);\n }\n}\n\n/**\n * If the proxy or config afterRedirects functions are defined, call them with the options\n *\n * @param {http.ClientRequestArgs} options\n * @param {AxiosProxyConfig} configProxy configuration from Axios options object\n * @param {string} location\n *\n * @returns {http.ClientRequestArgs}\n */\nfunction setProxy(options, configProxy, location) {\n let proxy = configProxy;\n if (!proxy && proxy !== false) {\n const proxyUrl = proxyFromEnv.getProxyForUrl(location);\n if (proxyUrl) {\n proxy = new URL(proxyUrl);\n }\n }\n if (proxy) {\n // Basic proxy authorization\n if (proxy.username) {\n proxy.auth = (proxy.username || '') + ':' + (proxy.password || '');\n }\n\n if (proxy.auth) {\n // Support proxy auth object form\n if (proxy.auth.username || proxy.auth.password) {\n proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || '');\n }\n const base64 = Buffer\n .from(proxy.auth, 'utf8')\n .toString('base64');\n options.headers['Proxy-Authorization'] = 'Basic ' + base64;\n }\n\n options.headers.host = options.hostname + (options.port ? ':' + options.port : '');\n const proxyHost = proxy.hostname || proxy.host;\n options.hostname = proxyHost;\n // Replace 'host' since options is not a URL object\n options.host = proxyHost;\n options.port = proxy.port;\n options.path = location;\n if (proxy.protocol) {\n options.protocol = proxy.protocol.includes(':') ? proxy.protocol : `${proxy.protocol}:`;\n }\n }\n\n options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) {\n // Configure proxy for redirected request, passing the original config proxy to apply\n // the exact same logic as if the redirected request was performed by axios directly.\n setProxy(redirectOptions, configProxy, redirectOptions.href);\n };\n}\n\nconst isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process';\n\n// temporary hotfix\n\nconst wrapAsync = (asyncExecutor) => {\n return new Promise((resolve, reject) => {\n let onDone;\n let isDone;\n\n const done = (value, isRejected) => {\n if (isDone) return;\n isDone = true;\n onDone && onDone(value, isRejected);\n }\n\n const _resolve = (value) => {\n done(value);\n resolve(value);\n };\n\n const _reject = (reason) => {\n done(reason, true);\n reject(reason);\n }\n\n asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject);\n })\n};\n\nconst resolveFamily = ({address, family}) => {\n if (!utils.isString(address)) {\n throw TypeError('address must be a string');\n }\n return ({\n address,\n family: family || (address.indexOf('.') < 0 ? 6 : 4)\n });\n}\n\nconst buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});\n\n/*eslint consistent-return:0*/\nexport default isHttpAdapterSupported && function httpAdapter(config) {\n return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {\n let {data, lookup, family} = config;\n const {responseType, responseEncoding} = config;\n const method = config.method.toUpperCase();\n let isDone;\n let rejected = false;\n let req;\n\n if (lookup) {\n const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]);\n // hotfix to support opt.all option which is required for node 20.x\n lookup = (hostname, opt, cb) => {\n _lookup(hostname, opt, (err, arg0, arg1) => {\n if (err) {\n return cb(err);\n }\n\n const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];\n\n opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);\n });\n }\n }\n\n // temporary internal emitter until the AxiosRequest class will be implemented\n const emitter = new EventEmitter();\n\n const onFinished = () => {\n if (config.cancelToken) {\n config.cancelToken.unsubscribe(abort);\n }\n\n if (config.signal) {\n config.signal.removeEventListener('abort', abort);\n }\n\n emitter.removeAllListeners();\n }\n\n onDone((value, isRejected) => {\n isDone = true;\n if (isRejected) {\n rejected = true;\n onFinished();\n }\n });\n\n function abort(reason) {\n emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason);\n }\n\n emitter.once('abort', reject);\n\n if (config.cancelToken || config.signal) {\n config.cancelToken && config.cancelToken.subscribe(abort);\n if (config.signal) {\n config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort);\n }\n }\n\n // Parse url\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined);\n const protocol = parsed.protocol || supportedProtocols[0];\n\n if (protocol === 'data:') {\n // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set.\n if (config.maxContentLength > -1) {\n // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed.\n const dataUrl = String(config.url || fullPath || '');\n const estimated = estimateDataURLDecodedBytes(dataUrl);\n\n if (estimated > config.maxContentLength) {\n return reject(new AxiosError(\n 'maxContentLength size of ' + config.maxContentLength + ' exceeded',\n AxiosError.ERR_BAD_RESPONSE,\n config\n ));\n }\n }\n\n let convertedData;\n\n if (method !== 'GET') {\n return settle(resolve, reject, {\n status: 405,\n statusText: 'method not allowed',\n headers: {},\n config\n });\n }\n\n try {\n convertedData = fromDataURI(config.url, responseType === 'blob', {\n Blob: config.env && config.env.Blob\n });\n } catch (err) {\n throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config);\n }\n\n if (responseType === 'text') {\n convertedData = convertedData.toString(responseEncoding);\n\n if (!responseEncoding || responseEncoding === 'utf8') {\n convertedData = utils.stripBOM(convertedData);\n }\n } else if (responseType === 'stream') {\n convertedData = stream.Readable.from(convertedData);\n }\n\n return settle(resolve, reject, {\n data: convertedData,\n status: 200,\n statusText: 'OK',\n headers: new AxiosHeaders(),\n config\n });\n }\n\n if (supportedProtocols.indexOf(protocol) === -1) {\n return reject(new AxiosError(\n 'Unsupported protocol ' + protocol,\n AxiosError.ERR_BAD_REQUEST,\n config\n ));\n }\n\n const headers = AxiosHeaders.from(config.headers).normalize();\n\n // Set User-Agent (required by some servers)\n // See https://github.com/axios/axios/issues/69\n // User-Agent is specified; handle case where no UA header is desired\n // Only set header if it hasn't been set in config\n headers.set('User-Agent', 'axios/' + VERSION, false);\n\n const {onUploadProgress, onDownloadProgress} = config;\n const maxRate = config.maxRate;\n let maxUploadRate = undefined;\n let maxDownloadRate = undefined;\n\n // support for spec compliant FormData objects\n if (utils.isSpecCompliantForm(data)) {\n const userBoundary = headers.getContentType(/boundary=([-_\\w\\d]{10,70})/i);\n\n data = formDataToStream(data, (formHeaders) => {\n headers.set(formHeaders);\n }, {\n tag: `axios-${VERSION}-boundary`,\n boundary: userBoundary && userBoundary[1] || undefined\n });\n // support for https://www.npmjs.com/package/form-data api\n } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) {\n headers.set(data.getHeaders());\n\n if (!headers.hasContentLength()) {\n try {\n const knownLength = await util.promisify(data.getLength).call(data);\n Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength);\n /*eslint no-empty:0*/\n } catch (e) {\n }\n }\n } else if (utils.isBlob(data) || utils.isFile(data)) {\n data.size && headers.setContentType(data.type || 'application/octet-stream');\n headers.setContentLength(data.size || 0);\n data = stream.Readable.from(readBlob(data));\n } else if (data && !utils.isStream(data)) {\n if (Buffer.isBuffer(data)) {\n // Nothing to do...\n } else if (utils.isArrayBuffer(data)) {\n data = Buffer.from(new Uint8Array(data));\n } else if (utils.isString(data)) {\n data = Buffer.from(data, 'utf-8');\n } else {\n return reject(new AxiosError(\n 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream',\n AxiosError.ERR_BAD_REQUEST,\n config\n ));\n }\n\n // Add Content-Length header if data exists\n headers.setContentLength(data.length, false);\n\n if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) {\n return reject(new AxiosError(\n 'Request body larger than maxBodyLength limit',\n AxiosError.ERR_BAD_REQUEST,\n config\n ));\n }\n }\n\n const contentLength = utils.toFiniteNumber(headers.getContentLength());\n\n if (utils.isArray(maxRate)) {\n maxUploadRate = maxRate[0];\n maxDownloadRate = maxRate[1];\n } else {\n maxUploadRate = maxDownloadRate = maxRate;\n }\n\n if (data && (onUploadProgress || maxUploadRate)) {\n if (!utils.isStream(data)) {\n data = stream.Readable.from(data, {objectMode: false});\n }\n\n data = stream.pipeline([data, new AxiosTransformStream({\n maxRate: utils.toFiniteNumber(maxUploadRate)\n })], utils.noop);\n\n onUploadProgress && data.on('progress', flushOnFinish(\n data,\n progressEventDecorator(\n contentLength,\n progressEventReducer(asyncDecorator(onUploadProgress), false, 3)\n )\n ));\n }\n\n // HTTP basic authentication\n let auth = undefined;\n if (config.auth) {\n const username = config.auth.username || '';\n const password = config.auth.password || '';\n auth = username + ':' + password;\n }\n\n if (!auth && parsed.username) {\n const urlUsername = parsed.username;\n const urlPassword = parsed.password;\n auth = urlUsername + ':' + urlPassword;\n }\n\n auth && headers.delete('authorization');\n\n let path;\n\n try {\n path = buildURL(\n parsed.pathname + parsed.search,\n config.params,\n config.paramsSerializer\n ).replace(/^\\?/, '');\n } catch (err) {\n const customErr = new Error(err.message);\n customErr.config = config;\n customErr.url = config.url;\n customErr.exists = true;\n return reject(customErr);\n }\n\n headers.set(\n 'Accept-Encoding',\n 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false\n );\n\n const options = {\n path,\n method: method,\n headers: headers.toJSON(),\n agents: { http: config.httpAgent, https: config.httpsAgent },\n auth,\n protocol,\n family,\n beforeRedirect: dispatchBeforeRedirect,\n beforeRedirects: {}\n };\n\n // cacheable-lookup integration hotfix\n !utils.isUndefined(lookup) && (options.lookup = lookup);\n\n if (config.socketPath) {\n options.socketPath = config.socketPath;\n } else {\n options.hostname = parsed.hostname.startsWith(\"[\") ? parsed.hostname.slice(1, -1) : parsed.hostname;\n options.port = parsed.port;\n setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path);\n }\n\n let transport;\n const isHttpsRequest = isHttps.test(options.protocol);\n options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent;\n if (config.transport) {\n transport = config.transport;\n } else if (config.maxRedirects === 0) {\n transport = isHttpsRequest ? https : http;\n } else {\n if (config.maxRedirects) {\n options.maxRedirects = config.maxRedirects;\n }\n if (config.beforeRedirect) {\n options.beforeRedirects.config = config.beforeRedirect;\n }\n transport = isHttpsRequest ? httpsFollow : httpFollow;\n }\n\n if (config.maxBodyLength > -1) {\n options.maxBodyLength = config.maxBodyLength;\n } else {\n // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited\n options.maxBodyLength = Infinity;\n }\n\n if (config.insecureHTTPParser) {\n options.insecureHTTPParser = config.insecureHTTPParser;\n }\n\n // Create the request\n req = transport.request(options, function handleResponse(res) {\n if (req.destroyed) return;\n\n const streams = [res];\n\n const responseLength = +res.headers['content-length'];\n\n if (onDownloadProgress || maxDownloadRate) {\n const transformStream = new AxiosTransformStream({\n maxRate: utils.toFiniteNumber(maxDownloadRate)\n });\n\n onDownloadProgress && transformStream.on('progress', flushOnFinish(\n transformStream,\n progressEventDecorator(\n responseLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true, 3)\n )\n ));\n\n streams.push(transformStream);\n }\n\n // decompress the response body transparently if required\n let responseStream = res;\n\n // return the last request in case of redirects\n const lastRequest = res.req || req;\n\n // if decompress disabled we should not decompress\n if (config.decompress !== false && res.headers['content-encoding']) {\n // if no content, but headers still say that it is encoded,\n // remove the header not confuse downstream operations\n if (method === 'HEAD' || res.statusCode === 204) {\n delete res.headers['content-encoding'];\n }\n\n switch ((res.headers['content-encoding'] || '').toLowerCase()) {\n /*eslint default-case:0*/\n case 'gzip':\n case 'x-gzip':\n case 'compress':\n case 'x-compress':\n // add the unzipper to the body stream processing pipeline\n streams.push(zlib.createUnzip(zlibOptions));\n\n // remove the content-encoding in order to not confuse downstream operations\n delete res.headers['content-encoding'];\n break;\n case 'deflate':\n streams.push(new ZlibHeaderTransformStream());\n\n // add the unzipper to the body stream processing pipeline\n streams.push(zlib.createUnzip(zlibOptions));\n\n // remove the content-encoding in order to not confuse downstream operations\n delete res.headers['content-encoding'];\n break;\n case 'br':\n if (isBrotliSupported) {\n streams.push(zlib.createBrotliDecompress(brotliOptions));\n delete res.headers['content-encoding'];\n }\n }\n }\n\n responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0];\n\n const offListeners = stream.finished(responseStream, () => {\n offListeners();\n onFinished();\n });\n\n const response = {\n status: res.statusCode,\n statusText: res.statusMessage,\n headers: new AxiosHeaders(res.headers),\n config,\n request: lastRequest\n };\n\n if (responseType === 'stream') {\n response.data = responseStream;\n settle(resolve, reject, response);\n } else {\n const responseBuffer = [];\n let totalResponseBytes = 0;\n\n responseStream.on('data', function handleStreamData(chunk) {\n responseBuffer.push(chunk);\n totalResponseBytes += chunk.length;\n\n // make sure the content length is not over the maxContentLength if specified\n if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) {\n // stream.destroy() emit aborted event before calling reject() on Node.js v16\n rejected = true;\n responseStream.destroy();\n reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded',\n AxiosError.ERR_BAD_RESPONSE, config, lastRequest));\n }\n });\n\n responseStream.on('aborted', function handlerStreamAborted() {\n if (rejected) {\n return;\n }\n\n const err = new AxiosError(\n 'stream has been aborted',\n AxiosError.ERR_BAD_RESPONSE,\n config,\n lastRequest\n );\n responseStream.destroy(err);\n reject(err);\n });\n\n responseStream.on('error', function handleStreamError(err) {\n if (req.destroyed) return;\n reject(AxiosError.from(err, null, config, lastRequest));\n });\n\n responseStream.on('end', function handleStreamEnd() {\n try {\n let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer);\n if (responseType !== 'arraybuffer') {\n responseData = responseData.toString(responseEncoding);\n if (!responseEncoding || responseEncoding === 'utf8') {\n responseData = utils.stripBOM(responseData);\n }\n }\n response.data = responseData;\n } catch (err) {\n return reject(AxiosError.from(err, null, config, response.request, response));\n }\n settle(resolve, reject, response);\n });\n }\n\n emitter.once('abort', err => {\n if (!responseStream.destroyed) {\n responseStream.emit('error', err);\n responseStream.destroy();\n }\n });\n });\n\n emitter.once('abort', err => {\n reject(err);\n req.destroy(err);\n });\n\n // Handle errors\n req.on('error', function handleRequestError(err) {\n // @todo remove\n // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return;\n reject(AxiosError.from(err, null, config, req));\n });\n\n // set tcp keep alive to prevent drop connection by peer\n req.on('socket', function handleRequestSocket(socket) {\n // default interval of sending ack packet is 1 minute\n socket.setKeepAlive(true, 1000 * 60);\n });\n\n // Handle request timeout\n if (config.timeout) {\n // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.\n const timeout = parseInt(config.timeout, 10);\n\n if (Number.isNaN(timeout)) {\n reject(new AxiosError(\n 'error trying to parse `config.timeout` to int',\n AxiosError.ERR_BAD_OPTION_VALUE,\n config,\n req\n ));\n\n return;\n }\n\n // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system.\n // And timer callback will be fired, and abort() will be invoked before connection, then get \"socket hang up\" and code ECONNRESET.\n // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up.\n // And then these socket which be hang up will devouring CPU little by little.\n // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect.\n req.setTimeout(timeout, function handleRequestTimeout() {\n if (isDone) return;\n let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = config.transitional || transitionalDefaults;\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n req\n ));\n abort();\n });\n }\n\n\n // Send the request\n if (utils.isStream(data)) {\n let ended = false;\n let errored = false;\n\n data.on('end', () => {\n ended = true;\n });\n\n data.once('error', err => {\n errored = true;\n req.destroy(err);\n });\n\n data.on('close', () => {\n if (!ended && !errored) {\n abort(new CanceledError('Request stream has been aborted', config, req));\n }\n });\n\n data.pipe(req);\n } else {\n req.end(data);\n }\n });\n}\n\nexport const __setProxy = setProxy;\n","import platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => {\n url = new URL(url, platform.origin);\n\n return (\n origin.protocol === url.protocol &&\n origin.host === url.host &&\n (isMSIE || origin.port === url.port)\n );\n})(\n new URL(platform.origin),\n platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent)\n) : () => true;\n","import utils from './../utils.js';\nimport platform from '../platform/index.js';\n\nexport default platform.hasStandardBrowserEnv ?\n\n // Standard browser envs support document.cookie\n {\n write(name, value, expires, path, domain, secure) {\n const cookie = [name + '=' + encodeURIComponent(value)];\n\n utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString());\n\n utils.isString(path) && cookie.push('path=' + path);\n\n utils.isString(domain) && cookie.push('domain=' + domain);\n\n secure === true && cookie.push('secure');\n\n document.cookie = cookie.join('; ');\n },\n\n read(name) {\n const match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n }\n\n :\n\n // Non-standard browser env (web workers, react-native) lack needed support.\n {\n write() {},\n read() {\n return null;\n },\n remove() {}\n };\n\n","'use strict';\n\nimport utils from '../utils.js';\nimport AxiosHeaders from \"./AxiosHeaders.js\";\n\nconst headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n *\n * @returns {Object} New object resulting from merging config2 to config1\n */\nexport default function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n const config = {};\n\n function getMergedValue(target, source, prop, caseless) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge.call({caseless}, target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(a, b, prop , caseless) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(a, b, prop , caseless);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a, prop , caseless);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(a, b) {\n if (!utils.isUndefined(b)) {\n return getMergedValue(undefined, b);\n } else if (!utils.isUndefined(a)) {\n return getMergedValue(undefined, a);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(a, b, prop) {\n if (prop in config2) {\n return getMergedValue(a, b);\n } else if (prop in config1) {\n return getMergedValue(undefined, a);\n }\n }\n\n const mergeMap = {\n url: valueFromConfig2,\n method: valueFromConfig2,\n data: valueFromConfig2,\n baseURL: defaultToConfig2,\n transformRequest: defaultToConfig2,\n transformResponse: defaultToConfig2,\n paramsSerializer: defaultToConfig2,\n timeout: defaultToConfig2,\n timeoutMessage: defaultToConfig2,\n withCredentials: defaultToConfig2,\n withXSRFToken: defaultToConfig2,\n adapter: defaultToConfig2,\n responseType: defaultToConfig2,\n xsrfCookieName: defaultToConfig2,\n xsrfHeaderName: defaultToConfig2,\n onUploadProgress: defaultToConfig2,\n onDownloadProgress: defaultToConfig2,\n decompress: defaultToConfig2,\n maxContentLength: defaultToConfig2,\n maxBodyLength: defaultToConfig2,\n beforeRedirect: defaultToConfig2,\n transport: defaultToConfig2,\n httpAgent: defaultToConfig2,\n httpsAgent: defaultToConfig2,\n cancelToken: defaultToConfig2,\n socketPath: defaultToConfig2,\n responseEncoding: defaultToConfig2,\n validateStatus: mergeDirectKeys,\n headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)\n };\n\n utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {\n const merge = mergeMap[prop] || mergeDeepProperties;\n const configValue = merge(config1[prop], config2[prop], prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport isURLSameOrigin from \"./isURLSameOrigin.js\";\nimport cookies from \"./cookies.js\";\nimport buildFullPath from \"../core/buildFullPath.js\";\nimport mergeConfig from \"../core/mergeConfig.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport buildURL from \"./buildURL.js\";\n\nexport default (config) => {\n const newConfig = mergeConfig({}, config);\n\n let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;\n\n newConfig.headers = headers = AxiosHeaders.from(headers);\n\n newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer);\n\n // HTTP basic authentication\n if (auth) {\n headers.set('Authorization', 'Basic ' +\n btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : ''))\n );\n }\n\n if (utils.isFormData(data)) {\n if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) {\n headers.setContentType(undefined); // browser handles it\n } else if (utils.isFunction(data.getHeaders)) {\n // Node.js FormData (like form-data package)\n const formHeaders = data.getHeaders();\n // Only set safe headers to avoid overwriting security headers\n const allowedHeaders = ['content-type', 'content-length'];\n Object.entries(formHeaders).forEach(([key, val]) => {\n if (allowedHeaders.includes(key.toLowerCase())) {\n headers.set(key, val);\n }\n });\n }\n } \n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n\n if (platform.hasStandardBrowserEnv) {\n withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig));\n\n if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) {\n // Add xsrf header\n const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName);\n\n if (xsrfValue) {\n headers.set(xsrfHeaderName, xsrfValue);\n }\n }\n }\n\n return newConfig;\n}\n\n","import utils from './../utils.js';\nimport settle from './../core/settle.js';\nimport transitionalDefaults from '../defaults/transitional.js';\nimport AxiosError from '../core/AxiosError.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport parseProtocol from '../helpers/parseProtocol.js';\nimport platform from '../platform/index.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport {progressEventReducer} from '../helpers/progressEventReducer.js';\nimport resolveConfig from \"../helpers/resolveConfig.js\";\n\nconst isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined';\n\nexport default isXHRAdapterSupported && function (config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n const _config = resolveConfig(config);\n let requestData = _config.data;\n const requestHeaders = AxiosHeaders.from(_config.headers).normalize();\n let {responseType, onUploadProgress, onDownloadProgress} = _config;\n let onCanceled;\n let uploadThrottled, downloadThrottled;\n let flushUpload, flushDownload;\n\n function done() {\n flushUpload && flushUpload(); // flush events\n flushDownload && flushDownload(); // flush events\n\n _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled);\n\n _config.signal && _config.signal.removeEventListener('abort', onCanceled);\n }\n\n let request = new XMLHttpRequest();\n\n request.open(_config.method.toUpperCase(), _config.url, true);\n\n // Set the request timeout in MS\n request.timeout = _config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n const responseHeaders = AxiosHeaders.from(\n 'getAllResponseHeaders' in request && request.getAllResponseHeaders()\n );\n const responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n const response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config,\n request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError(event) {\n // Browsers deliver a ProgressEvent in XHR onerror\n // (message may be empty; when present, surface it)\n // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event\n const msg = event && event.message ? event.message : 'Network Error';\n const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request);\n // attach the underlying event for consumers who want details\n err.event = event || null;\n reject(err);\n request = null;\n };\n \n // Handle timeout\n request.ontimeout = function handleTimeout() {\n let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded';\n const transitional = _config.transitional || transitionalDefaults;\n if (_config.timeoutErrorMessage) {\n timeoutErrorMessage = _config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Remove Content-Type if data is undefined\n requestData === undefined && requestHeaders.setContentType(null);\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) {\n request.setRequestHeader(key, val);\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(_config.withCredentials)) {\n request.withCredentials = !!_config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = _config.responseType;\n }\n\n // Handle progress if needed\n if (onDownloadProgress) {\n ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true));\n request.addEventListener('progress', downloadThrottled);\n }\n\n // Not all browsers support upload events\n if (onUploadProgress && request.upload) {\n ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress));\n\n request.upload.addEventListener('progress', uploadThrottled);\n\n request.upload.addEventListener('loadend', flushUpload);\n }\n\n if (_config.cancelToken || _config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = cancel => {\n if (!request) {\n return;\n }\n reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);\n request.abort();\n request = null;\n };\n\n _config.cancelToken && _config.cancelToken.subscribe(onCanceled);\n if (_config.signal) {\n _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n const protocol = parseProtocol(_config.url);\n\n if (protocol && platform.protocols.indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData || null);\n });\n}\n","import CanceledError from \"../cancel/CanceledError.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport utils from '../utils.js';\n\nconst composeSignals = (signals, timeout) => {\n const {length} = (signals = signals ? signals.filter(Boolean) : []);\n\n if (timeout || length) {\n let controller = new AbortController();\n\n let aborted;\n\n const onabort = function (reason) {\n if (!aborted) {\n aborted = true;\n unsubscribe();\n const err = reason instanceof Error ? reason : this.reason;\n controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));\n }\n }\n\n let timer = timeout && setTimeout(() => {\n timer = null;\n onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT))\n }, timeout)\n\n const unsubscribe = () => {\n if (signals) {\n timer && clearTimeout(timer);\n timer = null;\n signals.forEach(signal => {\n signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort);\n });\n signals = null;\n }\n }\n\n signals.forEach((signal) => signal.addEventListener('abort', onabort));\n\n const {signal} = controller;\n\n signal.unsubscribe = () => utils.asap(unsubscribe);\n\n return signal;\n }\n}\n\nexport default composeSignals;\n","\nexport const streamChunk = function* (chunk, chunkSize) {\n let len = chunk.byteLength;\n\n if (!chunkSize || len < chunkSize) {\n yield chunk;\n return;\n }\n\n let pos = 0;\n let end;\n\n while (pos < len) {\n end = pos + chunkSize;\n yield chunk.slice(pos, end);\n pos = end;\n }\n}\n\nexport const readBytes = async function* (iterable, chunkSize) {\n for await (const chunk of readStream(iterable)) {\n yield* streamChunk(chunk, chunkSize);\n }\n}\n\nconst readStream = async function* (stream) {\n if (stream[Symbol.asyncIterator]) {\n yield* stream;\n return;\n }\n\n const reader = stream.getReader();\n try {\n for (;;) {\n const {done, value} = await reader.read();\n if (done) {\n break;\n }\n yield value;\n }\n } finally {\n await reader.cancel();\n }\n}\n\nexport const trackStream = (stream, chunkSize, onProgress, onFinish) => {\n const iterator = readBytes(stream, chunkSize);\n\n let bytes = 0;\n let done;\n let _onFinish = (e) => {\n if (!done) {\n done = true;\n onFinish && onFinish(e);\n }\n }\n\n return new ReadableStream({\n async pull(controller) {\n try {\n const {done, value} = await iterator.next();\n\n if (done) {\n _onFinish();\n controller.close();\n return;\n }\n\n let len = value.byteLength;\n if (onProgress) {\n let loadedBytes = bytes += len;\n onProgress(loadedBytes);\n }\n controller.enqueue(new Uint8Array(value));\n } catch (err) {\n _onFinish(err);\n throw err;\n }\n },\n cancel(reason) {\n _onFinish(reason);\n return iterator.return();\n }\n }, {\n highWaterMark: 2\n })\n}\n","import platform from \"../platform/index.js\";\nimport utils from \"../utils.js\";\nimport AxiosError from \"../core/AxiosError.js\";\nimport composeSignals from \"../helpers/composeSignals.js\";\nimport {trackStream} from \"../helpers/trackStream.js\";\nimport AxiosHeaders from \"../core/AxiosHeaders.js\";\nimport {progressEventReducer, progressEventDecorator, asyncDecorator} from \"../helpers/progressEventReducer.js\";\nimport resolveConfig from \"../helpers/resolveConfig.js\";\nimport settle from \"../core/settle.js\";\n\nconst DEFAULT_CHUNK_SIZE = 64 * 1024;\n\nconst {isFunction} = utils;\n\nconst globalFetchAPI = (({Request, Response}) => ({\n Request, Response\n}))(utils.global);\n\nconst {\n ReadableStream, TextEncoder\n} = utils.global;\n\n\nconst test = (fn, ...args) => {\n try {\n return !!fn(...args);\n } catch (e) {\n return false\n }\n}\n\nconst factory = (env) => {\n env = utils.merge.call({\n skipUndefined: true\n }, globalFetchAPI, env);\n\n const {fetch: envFetch, Request, Response} = env;\n const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function';\n const isRequestSupported = isFunction(Request);\n const isResponseSupported = isFunction(Response);\n\n if (!isFetchSupported) {\n return false;\n }\n\n const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream);\n\n const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ?\n ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) :\n async (str) => new Uint8Array(await new Request(str).arrayBuffer())\n );\n\n const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => {\n let duplexAccessed = false;\n\n const hasContentType = new Request(platform.origin, {\n body: new ReadableStream(),\n method: 'POST',\n get duplex() {\n duplexAccessed = true;\n return 'half';\n },\n }).headers.has('Content-Type');\n\n return duplexAccessed && !hasContentType;\n });\n\n const supportsResponseStream = isResponseSupported && isReadableStreamSupported &&\n test(() => utils.isReadableStream(new Response('').body));\n\n const resolvers = {\n stream: supportsResponseStream && ((res) => res.body)\n };\n\n isFetchSupported && ((() => {\n ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => {\n !resolvers[type] && (resolvers[type] = (res, config) => {\n let method = res && res[type];\n\n if (method) {\n return method.call(res);\n }\n\n throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);\n })\n });\n })());\n\n const getBodyLength = async (body) => {\n if (body == null) {\n return 0;\n }\n\n if (utils.isBlob(body)) {\n return body.size;\n }\n\n if (utils.isSpecCompliantForm(body)) {\n const _request = new Request(platform.origin, {\n method: 'POST',\n body,\n });\n return (await _request.arrayBuffer()).byteLength;\n }\n\n if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {\n return body.byteLength;\n }\n\n if (utils.isURLSearchParams(body)) {\n body = body + '';\n }\n\n if (utils.isString(body)) {\n return (await encodeText(body)).byteLength;\n }\n }\n\n const resolveBodyLength = async (headers, body) => {\n const length = utils.toFiniteNumber(headers.getContentLength());\n\n return length == null ? getBodyLength(body) : length;\n }\n\n return async (config) => {\n let {\n url,\n method,\n data,\n signal,\n cancelToken,\n timeout,\n onDownloadProgress,\n onUploadProgress,\n responseType,\n headers,\n withCredentials = 'same-origin',\n fetchOptions\n } = resolveConfig(config);\n\n let _fetch = envFetch || fetch;\n\n responseType = responseType ? (responseType + '').toLowerCase() : 'text';\n\n let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout);\n\n let request = null;\n\n const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => {\n composedSignal.unsubscribe();\n });\n\n let requestContentLength;\n\n try {\n if (\n onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' &&\n (requestContentLength = await resolveBodyLength(headers, data)) !== 0\n ) {\n let _request = new Request(url, {\n method: 'POST',\n body: data,\n duplex: \"half\"\n });\n\n let contentTypeHeader;\n\n if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) {\n headers.setContentType(contentTypeHeader)\n }\n\n if (_request.body) {\n const [onProgress, flush] = progressEventDecorator(\n requestContentLength,\n progressEventReducer(asyncDecorator(onUploadProgress))\n );\n\n data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush);\n }\n }\n\n if (!utils.isString(withCredentials)) {\n withCredentials = withCredentials ? 'include' : 'omit';\n }\n\n // Cloudflare Workers throws when credentials are defined\n // see https://github.com/cloudflare/workerd/issues/902\n const isCredentialsSupported = isRequestSupported && \"credentials\" in Request.prototype;\n\n const resolvedOptions = {\n ...fetchOptions,\n signal: composedSignal,\n method: method.toUpperCase(),\n headers: headers.normalize().toJSON(),\n body: data,\n duplex: \"half\",\n credentials: isCredentialsSupported ? withCredentials : undefined\n };\n\n request = isRequestSupported && new Request(url, resolvedOptions);\n\n let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions));\n\n const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');\n\n if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) {\n const options = {};\n\n ['status', 'statusText', 'headers'].forEach(prop => {\n options[prop] = response[prop];\n });\n\n const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length'));\n\n const [onProgress, flush] = onDownloadProgress && progressEventDecorator(\n responseContentLength,\n progressEventReducer(asyncDecorator(onDownloadProgress), true)\n ) || [];\n\n response = new Response(\n trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => {\n flush && flush();\n unsubscribe && unsubscribe();\n }),\n options\n );\n }\n\n responseType = responseType || 'text';\n\n let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config);\n\n !isStreamResponse && unsubscribe && unsubscribe();\n\n return await new Promise((resolve, reject) => {\n settle(resolve, reject, {\n data: responseData,\n headers: AxiosHeaders.from(response.headers),\n status: response.status,\n statusText: response.statusText,\n config,\n request\n })\n })\n } catch (err) {\n unsubscribe && unsubscribe();\n\n if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) {\n throw Object.assign(\n new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request),\n {\n cause: err.cause || err\n }\n )\n }\n\n throw AxiosError.from(err, err && err.code, config, request);\n }\n }\n}\n\nconst seedCache = new Map();\n\nexport const getFetch = (config) => {\n let env = config ? config.env : {};\n const {fetch, Request, Response} = env;\n const seeds = [\n Request, Response, fetch\n ];\n\n let len = seeds.length, i = len,\n seed, target, map = seedCache;\n\n while (i--) {\n seed = seeds[i];\n target = map.get(seed);\n\n target === undefined && map.set(seed, target = (i ? new Map() : factory(env)))\n\n map = target;\n }\n\n return target;\n};\n\nconst adapter = getFetch();\n\nexport default adapter;\n","import utils from '../utils.js';\nimport httpAdapter from './http.js';\nimport xhrAdapter from './xhr.js';\nimport * as fetchAdapter from './fetch.js';\nimport AxiosError from \"../core/AxiosError.js\";\n\nconst knownAdapters = {\n http: httpAdapter,\n xhr: xhrAdapter,\n fetch: {\n get: fetchAdapter.getFetch,\n }\n}\n\nutils.forEach(knownAdapters, (fn, value) => {\n if (fn) {\n try {\n Object.defineProperty(fn, 'name', {value});\n } catch (e) {\n // eslint-disable-next-line no-empty\n }\n Object.defineProperty(fn, 'adapterName', {value});\n }\n});\n\nconst renderReason = (reason) => `- ${reason}`;\n\nconst isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;\n\nexport default {\n getAdapter: (adapters, config) => {\n adapters = utils.isArray(adapters) ? adapters : [adapters];\n\n const {length} = adapters;\n let nameOrAdapter;\n let adapter;\n\n const rejectedReasons = {};\n\n for (let i = 0; i < length; i++) {\n nameOrAdapter = adapters[i];\n let id;\n\n adapter = nameOrAdapter;\n\n if (!isResolvedHandle(nameOrAdapter)) {\n adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];\n\n if (adapter === undefined) {\n throw new AxiosError(`Unknown adapter '${id}'`);\n }\n }\n\n if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) {\n break;\n }\n\n rejectedReasons[id || '#' + i] = adapter;\n }\n\n if (!adapter) {\n\n const reasons = Object.entries(rejectedReasons)\n .map(([id, state]) => `adapter ${id} ` +\n (state === false ? 'is not supported by the environment' : 'is not available in the build')\n );\n\n let s = length ?\n (reasons.length > 1 ? 'since :\\n' + reasons.map(renderReason).join('\\n') : ' ' + renderReason(reasons[0])) :\n 'as no adapter specified';\n\n throw new AxiosError(\n `There is no suitable adapter to dispatch the request ` + s,\n 'ERR_NOT_SUPPORT'\n );\n }\n\n return adapter;\n },\n adapters: knownAdapters\n}\n","'use strict';\n\nimport transformData from './transformData.js';\nimport isCancel from '../cancel/isCancel.js';\nimport defaults from '../defaults/index.js';\nimport CanceledError from '../cancel/CanceledError.js';\nimport AxiosHeaders from '../core/AxiosHeaders.js';\nimport adapters from \"../adapters/adapters.js\";\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n *\n * @param {Object} config The config that is to be used for the request\n *\n * @returns {void}\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError(null, config);\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n *\n * @returns {Promise} The Promise to be fulfilled\n */\nexport default function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n config.headers = AxiosHeaders.from(config.headers);\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.transformRequest\n );\n\n if (['post', 'put', 'patch'].indexOf(config.method) !== -1) {\n config.headers.setContentType('application/x-www-form-urlencoded', false);\n }\n\n const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config);\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n config.transformResponse,\n response\n );\n\n response.headers = AxiosHeaders.from(response.headers);\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n config.transformResponse,\n reason.response\n );\n reason.response.headers = AxiosHeaders.from(reason.response.headers);\n }\n }\n\n return Promise.reject(reason);\n });\n}\n","'use strict';\n\nimport {VERSION} from '../env/data.js';\nimport AxiosError from '../core/AxiosError.js';\n\nconst validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nconst deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n *\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n *\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return (value, opt, opts) => {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\nvalidators.spelling = function spelling(correctSpelling) {\n return (value, opt) => {\n // eslint-disable-next-line no-console\n console.warn(`${opt} is likely a misspelling of ${correctSpelling}`);\n return true;\n }\n};\n\n/**\n * Assert object's properties type\n *\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n *\n * @returns {object}\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n const keys = Object.keys(options);\n let i = keys.length;\n while (i-- > 0) {\n const opt = keys[i];\n const validator = schema[opt];\n if (validator) {\n const value = options[opt];\n const result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nexport default {\n assertOptions,\n validators\n};\n","'use strict';\n\nimport utils from './../utils.js';\nimport buildURL from '../helpers/buildURL.js';\nimport InterceptorManager from './InterceptorManager.js';\nimport dispatchRequest from './dispatchRequest.js';\nimport mergeConfig from './mergeConfig.js';\nimport buildFullPath from './buildFullPath.js';\nimport validator from '../helpers/validator.js';\nimport AxiosHeaders from './AxiosHeaders.js';\n\nconst validators = validator.validators;\n\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n *\n * @return {Axios} A new instance of Axios\n */\nclass Axios {\n constructor(instanceConfig) {\n this.defaults = instanceConfig || {};\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n }\n\n /**\n * Dispatch a request\n *\n * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults)\n * @param {?Object} config\n *\n * @returns {Promise} The Promise to be fulfilled\n */\n async request(configOrUrl, config) {\n try {\n return await this._request(configOrUrl, config);\n } catch (err) {\n if (err instanceof Error) {\n let dummy = {};\n\n Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error());\n\n // slice off the Error: ... line\n const stack = dummy.stack ? dummy.stack.replace(/^.+\\n/, '') : '';\n try {\n if (!err.stack) {\n err.stack = stack;\n // match without the 2 top stack lines\n } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\\n.+\\n/, ''))) {\n err.stack += '\\n' + stack\n }\n } catch (e) {\n // ignore the case where \"stack\" is an un-writable property\n }\n }\n\n throw err;\n }\n }\n\n _request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n const {transitional, paramsSerializer, headers} = config;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n if (paramsSerializer != null) {\n if (utils.isFunction(paramsSerializer)) {\n config.paramsSerializer = {\n serialize: paramsSerializer\n }\n } else {\n validator.assertOptions(paramsSerializer, {\n encode: validators.function,\n serialize: validators.function\n }, true);\n }\n }\n\n // Set config.allowAbsoluteUrls\n if (config.allowAbsoluteUrls !== undefined) {\n // do nothing\n } else if (this.defaults.allowAbsoluteUrls !== undefined) {\n config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls;\n } else {\n config.allowAbsoluteUrls = true;\n }\n\n validator.assertOptions(config, {\n baseUrl: validators.spelling('baseURL'),\n withXsrfToken: validators.spelling('withXSRFToken')\n }, true);\n\n // Set config.method\n config.method = (config.method || this.defaults.method || 'get').toLowerCase();\n\n // Flatten headers\n let contextHeaders = headers && utils.merge(\n headers.common,\n headers[config.method]\n );\n\n headers && utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n (method) => {\n delete headers[method];\n }\n );\n\n config.headers = AxiosHeaders.concat(contextHeaders, headers);\n\n // filter out skipped interceptors\n const requestInterceptorChain = [];\n let synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n const responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n let promise;\n let i = 0;\n let len;\n\n if (!synchronousRequestInterceptors) {\n const chain = [dispatchRequest.bind(this), undefined];\n chain.unshift(...requestInterceptorChain);\n chain.push(...responseInterceptorChain);\n len = chain.length;\n\n promise = Promise.resolve(config);\n\n while (i < len) {\n promise = promise.then(chain[i++], chain[i++]);\n }\n\n return promise;\n }\n\n len = requestInterceptorChain.length;\n\n let newConfig = config;\n\n while (i < len) {\n const onFulfilled = requestInterceptorChain[i++];\n const onRejected = requestInterceptorChain[i++];\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected.call(this, error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest.call(this, newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n i = 0;\n len = responseInterceptorChain.length;\n\n while (i < len) {\n promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]);\n }\n\n return promise;\n }\n\n getUri(config) {\n config = mergeConfig(this.defaults, config);\n const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n }\n}\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url,\n data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nexport default Axios;\n","'use strict';\n\nimport CanceledError from './CanceledError.js';\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @param {Function} executor The executor function.\n *\n * @returns {CancelToken}\n */\nclass CancelToken {\n constructor(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n let resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n const token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(cancel => {\n if (!token._listeners) return;\n\n let i = token._listeners.length;\n\n while (i-- > 0) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = onfulfilled => {\n let _resolve;\n // eslint-disable-next-line func-names\n const promise = new Promise(resolve => {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message, config, request) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message, config, request);\n resolvePromise(token.reason);\n });\n }\n\n /**\n * Throws a `CanceledError` if cancellation has been requested.\n */\n throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n }\n\n /**\n * Subscribe to the cancel signal\n */\n\n subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n }\n\n /**\n * Unsubscribe from the cancel signal\n */\n\n unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n const index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n }\n\n toAbortSignal() {\n const controller = new AbortController();\n\n const abort = (err) => {\n controller.abort(err);\n };\n\n this.subscribe(abort);\n\n controller.signal.unsubscribe = () => this.unsubscribe(abort);\n\n return controller.signal;\n }\n\n /**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\n static source() {\n let cancel;\n const token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token,\n cancel\n };\n }\n}\n\nexport default CancelToken;\n","'use strict';\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n *\n * @returns {Function}\n */\nexport default function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n}\n","'use strict';\n\nimport utils from './../utils.js';\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n *\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nexport default function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n}\n","const HttpStatusCode = {\n Continue: 100,\n SwitchingProtocols: 101,\n Processing: 102,\n EarlyHints: 103,\n Ok: 200,\n Created: 201,\n Accepted: 202,\n NonAuthoritativeInformation: 203,\n NoContent: 204,\n ResetContent: 205,\n PartialContent: 206,\n MultiStatus: 207,\n AlreadyReported: 208,\n ImUsed: 226,\n MultipleChoices: 300,\n MovedPermanently: 301,\n Found: 302,\n SeeOther: 303,\n NotModified: 304,\n UseProxy: 305,\n Unused: 306,\n TemporaryRedirect: 307,\n PermanentRedirect: 308,\n BadRequest: 400,\n Unauthorized: 401,\n PaymentRequired: 402,\n Forbidden: 403,\n NotFound: 404,\n MethodNotAllowed: 405,\n NotAcceptable: 406,\n ProxyAuthenticationRequired: 407,\n RequestTimeout: 408,\n Conflict: 409,\n Gone: 410,\n LengthRequired: 411,\n PreconditionFailed: 412,\n PayloadTooLarge: 413,\n UriTooLong: 414,\n UnsupportedMediaType: 415,\n RangeNotSatisfiable: 416,\n ExpectationFailed: 417,\n ImATeapot: 418,\n MisdirectedRequest: 421,\n UnprocessableEntity: 422,\n Locked: 423,\n FailedDependency: 424,\n TooEarly: 425,\n UpgradeRequired: 426,\n PreconditionRequired: 428,\n TooManyRequests: 429,\n RequestHeaderFieldsTooLarge: 431,\n UnavailableForLegalReasons: 451,\n InternalServerError: 500,\n NotImplemented: 501,\n BadGateway: 502,\n ServiceUnavailable: 503,\n GatewayTimeout: 504,\n HttpVersionNotSupported: 505,\n VariantAlsoNegotiates: 506,\n InsufficientStorage: 507,\n LoopDetected: 508,\n NotExtended: 510,\n NetworkAuthenticationRequired: 511,\n};\n\nObject.entries(HttpStatusCode).forEach(([key, value]) => {\n HttpStatusCode[value] = key;\n});\n\nexport default HttpStatusCode;\n","'use strict';\n\nimport utils from './utils.js';\nimport bind from './helpers/bind.js';\nimport Axios from './core/Axios.js';\nimport mergeConfig from './core/mergeConfig.js';\nimport defaults from './defaults/index.js';\nimport formDataToJSON from './helpers/formDataToJSON.js';\nimport CanceledError from './cancel/CanceledError.js';\nimport CancelToken from './cancel/CancelToken.js';\nimport isCancel from './cancel/isCancel.js';\nimport {VERSION} from './env/data.js';\nimport toFormData from './helpers/toFormData.js';\nimport AxiosError from './core/AxiosError.js';\nimport spread from './helpers/spread.js';\nimport isAxiosError from './helpers/isAxiosError.js';\nimport AxiosHeaders from \"./core/AxiosHeaders.js\";\nimport adapters from './adapters/adapters.js';\nimport HttpStatusCode from './helpers/HttpStatusCode.js';\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n *\n * @returns {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n const context = new Axios(defaultConfig);\n const instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context, {allOwnKeys: true});\n\n // Copy context to instance\n utils.extend(instance, context, null, {allOwnKeys: true});\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nconst axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = CanceledError;\naxios.CancelToken = CancelToken;\naxios.isCancel = isCancel;\naxios.VERSION = VERSION;\naxios.toFormData = toFormData;\n\n// Expose AxiosError class\naxios.AxiosError = AxiosError;\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\n\naxios.spread = spread;\n\n// Expose isAxiosError\naxios.isAxiosError = isAxiosError;\n\n// Expose mergeConfig\naxios.mergeConfig = mergeConfig;\n\naxios.AxiosHeaders = AxiosHeaders;\n\naxios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);\n\naxios.getAdapter = adapters.getAdapter;\n\naxios.HttpStatusCode = HttpStatusCode;\n\naxios.default = axios;\n\n// this module should only have a default export\nexport default axios\n"],"names":["isFunction","utils","prototype","PlatformFormData","encode","url","crypto","FormData","platform","defaults","AxiosHeaders","stream","util","readBlob","Readable","zlib","followRedirects","proxyFromEnv","callbackify","EventEmitter","formDataToStream","AxiosTransformStream","https","http","ZlibHeaderTransformStream","ReadableStream","TextEncoder","composeSignals","fetchAdapter.getFetch","validators","InterceptorManager","Axios","CancelToken","HttpStatusCode"],"mappings":"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"} \ No newline at end of file diff --git a/node_modules/axios/index.d.cts b/node_modules/axios/index.d.cts new file mode 100644 index 0000000..971a644 --- /dev/null +++ b/node_modules/axios/index.d.cts @@ -0,0 +1,568 @@ +interface RawAxiosHeaders { + [key: string]: axios.AxiosHeaderValue; +} + +type MethodsHeaders = Partial<{ + [Key in axios.Method as Lowercase]: AxiosHeaders; +} & {common: AxiosHeaders}>; + +type AxiosHeaderMatcher = string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean); + +type AxiosHeaderParser = (this: AxiosHeaders, value: axios.AxiosHeaderValue, header: string) => any; + +type CommonRequestHeadersList = 'Accept' | 'Content-Length' | 'User-Agent'| 'Content-Encoding' | 'Authorization'; + +type ContentType = axios.AxiosHeaderValue | 'text/html' | 'text/plain' | 'multipart/form-data' | 'application/json' | 'application/x-www-form-urlencoded' | 'application/octet-stream'; + +type CommonResponseHeadersList = 'Server' | 'Content-Type' | 'Content-Length' | 'Cache-Control'| 'Content-Encoding'; + +type BrowserProgressEvent = any; + +declare class AxiosHeaders { + constructor( + headers?: RawAxiosHeaders | AxiosHeaders | string + ); + + [key: string]: any; + + set(headerName?: string, value?: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; + + get(headerName: string, parser: RegExp): RegExpExecArray | null; + get(headerName: string, matcher?: true | AxiosHeaderParser): axios.AxiosHeaderValue; + + has(header: string, matcher?: AxiosHeaderMatcher): boolean; + + delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; + + clear(matcher?: AxiosHeaderMatcher): boolean; + + normalize(format: boolean): AxiosHeaders; + + concat(...targets: Array): AxiosHeaders; + + toJSON(asStrings?: boolean): RawAxiosHeaders; + + static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; + + static accessor(header: string | string[]): AxiosHeaders; + + static concat(...targets: Array): AxiosHeaders; + + setContentType(value: ContentType, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getContentType(parser?: RegExp): RegExpExecArray | null; + getContentType(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; + hasContentType(matcher?: AxiosHeaderMatcher): boolean; + + setContentLength(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getContentLength(parser?: RegExp): RegExpExecArray | null; + getContentLength(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; + hasContentLength(matcher?: AxiosHeaderMatcher): boolean; + + setAccept(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getAccept(parser?: RegExp): RegExpExecArray | null; + getAccept(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; + hasAccept(matcher?: AxiosHeaderMatcher): boolean; + + setUserAgent(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getUserAgent(parser?: RegExp): RegExpExecArray | null; + getUserAgent(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; + hasUserAgent(matcher?: AxiosHeaderMatcher): boolean; + + setContentEncoding(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getContentEncoding(parser?: RegExp): RegExpExecArray | null; + getContentEncoding(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; + hasContentEncoding(matcher?: AxiosHeaderMatcher): boolean; + + setAuthorization(value: axios.AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getAuthorization(parser?: RegExp): RegExpExecArray | null; + getAuthorization(matcher?: AxiosHeaderMatcher): axios.AxiosHeaderValue; + hasAuthorization(matcher?: AxiosHeaderMatcher): boolean; + + getSetCookie(): string[]; + + [Symbol.iterator](): IterableIterator<[string, axios.AxiosHeaderValue]>; +} + +declare class AxiosError extends Error { + constructor( + message?: string, + code?: string, + config?: axios.InternalAxiosRequestConfig, + request?: any, + response?: axios.AxiosResponse + ); + + config?: axios.InternalAxiosRequestConfig; + code?: string; + request?: any; + response?: axios.AxiosResponse; + isAxiosError: boolean; + status?: number; + toJSON: () => object; + cause?: unknown; + event?: BrowserProgressEvent; + static from( + error: Error | unknown, + code?: string, + config?: axios.InternalAxiosRequestConfig, + request?: any, + response?: axios.AxiosResponse, + customProps?: object, +): AxiosError; + static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS"; + static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE"; + static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION"; + static readonly ERR_NETWORK = "ERR_NETWORK"; + static readonly ERR_DEPRECATED = "ERR_DEPRECATED"; + static readonly ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE"; + static readonly ERR_BAD_REQUEST = "ERR_BAD_REQUEST"; + static readonly ERR_NOT_SUPPORT = "ERR_NOT_SUPPORT"; + static readonly ERR_INVALID_URL = "ERR_INVALID_URL"; + static readonly ERR_CANCELED = "ERR_CANCELED"; + static readonly ECONNABORTED = "ECONNABORTED"; + static readonly ETIMEDOUT = "ETIMEDOUT"; +} + +declare class CanceledError extends AxiosError { +} + +declare class Axios { + constructor(config?: axios.AxiosRequestConfig); + defaults: axios.AxiosDefaults; + interceptors: { + request: axios.AxiosInterceptorManager; + response: axios.AxiosInterceptorManager; + }; + getUri(config?: axios.AxiosRequestConfig): string; + request, D = any>(config: axios.AxiosRequestConfig): Promise; + get, D = any>(url: string, config?: axios.AxiosRequestConfig): Promise; + delete, D = any>(url: string, config?: axios.AxiosRequestConfig): Promise; + head, D = any>(url: string, config?: axios.AxiosRequestConfig): Promise; + options, D = any>(url: string, config?: axios.AxiosRequestConfig): Promise; + post, D = any>(url: string, data?: D, config?: axios.AxiosRequestConfig): Promise; + put, D = any>(url: string, data?: D, config?: axios.AxiosRequestConfig): Promise; + patch, D = any>(url: string, data?: D, config?: axios.AxiosRequestConfig): Promise; + postForm, D = any>(url: string, data?: D, config?: axios.AxiosRequestConfig): Promise; + putForm, D = any>(url: string, data?: D, config?: axios.AxiosRequestConfig): Promise; + patchForm, D = any>(url: string, data?: D, config?: axios.AxiosRequestConfig): Promise; +} + +declare enum HttpStatusCode { + Continue = 100, + SwitchingProtocols = 101, + Processing = 102, + EarlyHints = 103, + Ok = 200, + Created = 201, + Accepted = 202, + NonAuthoritativeInformation = 203, + NoContent = 204, + ResetContent = 205, + PartialContent = 206, + MultiStatus = 207, + AlreadyReported = 208, + ImUsed = 226, + MultipleChoices = 300, + MovedPermanently = 301, + Found = 302, + SeeOther = 303, + NotModified = 304, + UseProxy = 305, + Unused = 306, + TemporaryRedirect = 307, + PermanentRedirect = 308, + BadRequest = 400, + Unauthorized = 401, + PaymentRequired = 402, + Forbidden = 403, + NotFound = 404, + MethodNotAllowed = 405, + NotAcceptable = 406, + ProxyAuthenticationRequired = 407, + RequestTimeout = 408, + Conflict = 409, + Gone = 410, + LengthRequired = 411, + PreconditionFailed = 412, + PayloadTooLarge = 413, + UriTooLong = 414, + UnsupportedMediaType = 415, + RangeNotSatisfiable = 416, + ExpectationFailed = 417, + ImATeapot = 418, + MisdirectedRequest = 421, + UnprocessableEntity = 422, + Locked = 423, + FailedDependency = 424, + TooEarly = 425, + UpgradeRequired = 426, + PreconditionRequired = 428, + TooManyRequests = 429, + RequestHeaderFieldsTooLarge = 431, + UnavailableForLegalReasons = 451, + InternalServerError = 500, + NotImplemented = 501, + BadGateway = 502, + ServiceUnavailable = 503, + GatewayTimeout = 504, + HttpVersionNotSupported = 505, + VariantAlsoNegotiates = 506, + InsufficientStorage = 507, + LoopDetected = 508, + NotExtended = 510, + NetworkAuthenticationRequired = 511, +} + +type InternalAxiosError = AxiosError; + +declare namespace axios { + type AxiosError = InternalAxiosError; + + type RawAxiosRequestHeaders = Partial; + + type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders; + + type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null; + + type RawCommonResponseHeaders = { + [Key in CommonResponseHeadersList]: AxiosHeaderValue; + } & { + "set-cookie": string[]; + }; + + type RawAxiosResponseHeaders = Partial; + + type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders; + + interface AxiosRequestTransformer { + (this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any; + } + + interface AxiosResponseTransformer { + (this: InternalAxiosRequestConfig, data: any, headers: AxiosResponseHeaders, status?: number): any; + } + + interface AxiosAdapter { + (config: InternalAxiosRequestConfig): AxiosPromise; + } + + interface AxiosBasicCredentials { + username: string; + password: string; + } + + interface AxiosProxyConfig { + host: string; + port: number; + auth?: AxiosBasicCredentials; + protocol?: string; + } + + type Method = + | 'get' | 'GET' + | 'delete' | 'DELETE' + | 'head' | 'HEAD' + | 'options' | 'OPTIONS' + | 'post' | 'POST' + | 'put' | 'PUT' + | 'patch' | 'PATCH' + | 'purge' | 'PURGE' + | 'link' | 'LINK' + | 'unlink' | 'UNLINK'; + + type ResponseType = + | 'arraybuffer' + | 'blob' + | 'document' + | 'json' + | 'text' + | 'stream' + | 'formdata'; + + type responseEncoding = + | 'ascii' | 'ASCII' + | 'ansi' | 'ANSI' + | 'binary' | 'BINARY' + | 'base64' | 'BASE64' + | 'base64url' | 'BASE64URL' + | 'hex' | 'HEX' + | 'latin1' | 'LATIN1' + | 'ucs-2' | 'UCS-2' + | 'ucs2' | 'UCS2' + | 'utf-8' | 'UTF-8' + | 'utf8' | 'UTF8' + | 'utf16le' | 'UTF16LE'; + + interface TransitionalOptions { + silentJSONParsing?: boolean; + forcedJSONParsing?: boolean; + clarifyTimeoutError?: boolean; + } + + interface GenericAbortSignal { + readonly aborted: boolean; + onabort?: ((...args: any) => any) | null; + addEventListener?: (...args: any) => any; + removeEventListener?: (...args: any) => any; + } + + interface FormDataVisitorHelpers { + defaultVisitor: SerializerVisitor; + convertValue: (value: any) => any; + isVisitable: (value: any) => boolean; + } + + interface SerializerVisitor { + ( + this: GenericFormData, + value: any, + key: string | number, + path: null | Array, + helpers: FormDataVisitorHelpers + ): boolean; + } + + interface SerializerOptions { + visitor?: SerializerVisitor; + dots?: boolean; + metaTokens?: boolean; + indexes?: boolean | null; + } + + // tslint:disable-next-line + interface FormSerializerOptions extends SerializerOptions { + } + + interface ParamEncoder { + (value: any, defaultEncoder: (value: any) => any): any; + } + + interface CustomParamsSerializer { + (params: Record, options?: ParamsSerializerOptions): string; + } + + interface ParamsSerializerOptions extends SerializerOptions { + encode?: ParamEncoder; + serialize?: CustomParamsSerializer; + } + + type MaxUploadRate = number; + + type MaxDownloadRate = number; + + interface AxiosProgressEvent { + loaded: number; + total?: number; + progress?: number; + bytes: number; + rate?: number; + estimated?: number; + upload?: boolean; + download?: boolean; + event?: BrowserProgressEvent; + lengthComputable: boolean; + } + + type Milliseconds = number; + + type AxiosAdapterName = 'fetch' | 'xhr' | 'http' | (string & {}); + + type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName; + + type AddressFamily = 4 | 6 | undefined; + + interface LookupAddressEntry { + address: string; + family?: AddressFamily; + } + + type LookupAddress = string | LookupAddressEntry; + + interface AxiosRequestConfig { + url?: string; + method?: Method | string; + baseURL?: string; + allowAbsoluteUrls?: boolean; + transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[]; + transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[]; + headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders; + params?: any; + paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer; + data?: D; + timeout?: Milliseconds; + timeoutErrorMessage?: string; + withCredentials?: boolean; + adapter?: AxiosAdapterConfig | AxiosAdapterConfig[]; + auth?: AxiosBasicCredentials; + responseType?: ResponseType; + responseEncoding?: responseEncoding | string; + xsrfCookieName?: string; + xsrfHeaderName?: string; + onUploadProgress?: (progressEvent: AxiosProgressEvent) => void; + onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void; + maxContentLength?: number; + validateStatus?: ((status: number) => boolean) | null; + maxBodyLength?: number; + maxRedirects?: number; + maxRate?: number | [MaxUploadRate, MaxDownloadRate]; + beforeRedirect?: (options: Record, responseDetails: {headers: Record, statusCode: HttpStatusCode}) => void; + socketPath?: string | null; + transport?: any; + httpAgent?: any; + httpsAgent?: any; + proxy?: AxiosProxyConfig | false; + cancelToken?: CancelToken; + decompress?: boolean; + transitional?: TransitionalOptions; + signal?: GenericAbortSignal; + insecureHTTPParser?: boolean; + env?: { + FormData?: new (...args: any[]) => object; + fetch?: (input: URL | Request | string, init?: RequestInit) => Promise; + Request?: new (input: URL | Request | string, init?: RequestInit) => Request; + Response?: new ( + body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null, + init?: ResponseInit + ) => Response; + }; + formSerializer?: FormSerializerOptions; + family?: AddressFamily; + lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) | + ((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>); + withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined); + fetchOptions?: Omit | Record; + } + + // Alias + type RawAxiosRequestConfig = AxiosRequestConfig; + + interface InternalAxiosRequestConfig extends AxiosRequestConfig { + headers: AxiosRequestHeaders; + } + + interface HeadersDefaults { + common: RawAxiosRequestHeaders; + delete: RawAxiosRequestHeaders; + get: RawAxiosRequestHeaders; + head: RawAxiosRequestHeaders; + post: RawAxiosRequestHeaders; + put: RawAxiosRequestHeaders; + patch: RawAxiosRequestHeaders; + options?: RawAxiosRequestHeaders; + purge?: RawAxiosRequestHeaders; + link?: RawAxiosRequestHeaders; + unlink?: RawAxiosRequestHeaders; + } + + interface AxiosDefaults extends Omit, 'headers'> { + headers: HeadersDefaults; + } + + interface CreateAxiosDefaults extends Omit, 'headers'> { + headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial; + } + + interface AxiosResponse { + data: T; + status: number; + statusText: string; + headers: H & RawAxiosResponseHeaders | AxiosResponseHeaders; + config: InternalAxiosRequestConfig; + request?: any; + } + + type AxiosPromise = Promise>; + + interface CancelStatic { + new (message?: string): Cancel; + } + + interface Cancel { + message: string | undefined; + } + + interface Canceler { + (message?: string, config?: AxiosRequestConfig, request?: any): void; + } + + interface CancelTokenStatic { + new (executor: (cancel: Canceler) => void): CancelToken; + source(): CancelTokenSource; + } + + interface CancelToken { + promise: Promise; + reason?: Cancel; + throwIfRequested(): void; + } + + interface CancelTokenSource { + token: CancelToken; + cancel: Canceler; + } + + interface AxiosInterceptorOptions { + synchronous?: boolean; + runWhen?: (config: InternalAxiosRequestConfig) => boolean; + } + + type AxiosRequestInterceptorUse = (onFulfilled?: ((value: T) => T | Promise) | null, onRejected?: ((error: any) => any) | null, options?: AxiosInterceptorOptions) => number; + + type AxiosResponseInterceptorUse = (onFulfilled?: ((value: T) => T | Promise) | null, onRejected?: ((error: any) => any) | null) => number; + + interface AxiosInterceptorManager { + use: V extends AxiosResponse ? AxiosResponseInterceptorUse : AxiosRequestInterceptorUse; + eject(id: number): void; + clear(): void; + } + + interface AxiosInstance extends Axios { + , D = any>(config: AxiosRequestConfig): Promise; + , D = any>(url: string, config?: AxiosRequestConfig): Promise; + + create(config?: CreateAxiosDefaults): AxiosInstance; + defaults: Omit & { + headers: HeadersDefaults & { + [key: string]: AxiosHeaderValue + } + }; + } + + interface GenericFormData { + append(name: string, value: any, options?: any): any; + } + + interface GenericHTMLFormElement { + name: string; + method: string; + submit(): void; + } + + interface AxiosStatic extends AxiosInstance { + Cancel: CancelStatic; + CancelToken: CancelTokenStatic; + Axios: typeof Axios; + AxiosError: typeof AxiosError; + CanceledError: typeof CanceledError; + HttpStatusCode: typeof HttpStatusCode; + readonly VERSION: string; + isCancel(value: any): value is Cancel; + all(values: Array>): Promise; + spread(callback: (...args: T[]) => R): (array: T[]) => R; + isAxiosError(payload: any): payload is AxiosError; + toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData; + formToJSON(form: GenericFormData|GenericHTMLFormElement): object; + getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter; + AxiosHeaders: typeof AxiosHeaders; + mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig; + } +} + +declare const axios: axios.AxiosStatic; + +export = axios; diff --git a/node_modules/axios/index.d.ts b/node_modules/axios/index.d.ts new file mode 100644 index 0000000..554140e --- /dev/null +++ b/node_modules/axios/index.d.ts @@ -0,0 +1,581 @@ +// TypeScript Version: 4.7 +export type AxiosHeaderValue = AxiosHeaders | string | string[] | number | boolean | null; + +interface RawAxiosHeaders { + [key: string]: AxiosHeaderValue; +} + +type MethodsHeaders = Partial<{ + [Key in Method as Lowercase]: AxiosHeaders; +} & {common: AxiosHeaders}>; + +type AxiosHeaderMatcher = string | RegExp | ((this: AxiosHeaders, value: string, name: string) => boolean); + +type AxiosHeaderParser = (this: AxiosHeaders, value: AxiosHeaderValue, header: string) => any; + +export class AxiosHeaders { + constructor( + headers?: RawAxiosHeaders | AxiosHeaders | string + ); + + [key: string]: any; + + set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; + + get(headerName: string, parser: RegExp): RegExpExecArray | null; + get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue; + + has(header: string, matcher?: AxiosHeaderMatcher): boolean; + + delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean; + + clear(matcher?: AxiosHeaderMatcher): boolean; + + normalize(format: boolean): AxiosHeaders; + + concat(...targets: Array): AxiosHeaders; + + toJSON(asStrings?: boolean): RawAxiosHeaders; + + static from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders; + + static accessor(header: string | string[]): AxiosHeaders; + + static concat(...targets: Array): AxiosHeaders; + + setContentType(value: ContentType, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getContentType(parser?: RegExp): RegExpExecArray | null; + getContentType(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; + hasContentType(matcher?: AxiosHeaderMatcher): boolean; + + setContentLength(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getContentLength(parser?: RegExp): RegExpExecArray | null; + getContentLength(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; + hasContentLength(matcher?: AxiosHeaderMatcher): boolean; + + setAccept(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getAccept(parser?: RegExp): RegExpExecArray | null; + getAccept(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; + hasAccept(matcher?: AxiosHeaderMatcher): boolean; + + setUserAgent(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getUserAgent(parser?: RegExp): RegExpExecArray | null; + getUserAgent(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; + hasUserAgent(matcher?: AxiosHeaderMatcher): boolean; + + setContentEncoding(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getContentEncoding(parser?: RegExp): RegExpExecArray | null; + getContentEncoding(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; + hasContentEncoding(matcher?: AxiosHeaderMatcher): boolean; + + setAuthorization(value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; + getAuthorization(parser?: RegExp): RegExpExecArray | null; + getAuthorization(matcher?: AxiosHeaderMatcher): AxiosHeaderValue; + hasAuthorization(matcher?: AxiosHeaderMatcher): boolean; + + getSetCookie(): string[]; + + [Symbol.iterator](): IterableIterator<[string, AxiosHeaderValue]>; +} + +type CommonRequestHeadersList = 'Accept' | 'Content-Length' | 'User-Agent' | 'Content-Encoding' | 'Authorization'; + +type ContentType = AxiosHeaderValue | 'text/html' | 'text/plain' | 'multipart/form-data' | 'application/json' | 'application/x-www-form-urlencoded' | 'application/octet-stream'; + +export type RawAxiosRequestHeaders = Partial; + +export type AxiosRequestHeaders = RawAxiosRequestHeaders & AxiosHeaders; + +type CommonResponseHeadersList = 'Server' | 'Content-Type' | 'Content-Length' | 'Cache-Control'| 'Content-Encoding'; + +type RawCommonResponseHeaders = { + [Key in CommonResponseHeadersList]: AxiosHeaderValue; +} & { + "set-cookie": string[]; +}; + +export type RawAxiosResponseHeaders = Partial; + +export type AxiosResponseHeaders = RawAxiosResponseHeaders & AxiosHeaders; + +export interface AxiosRequestTransformer { + (this: InternalAxiosRequestConfig, data: any, headers: AxiosRequestHeaders): any; +} + +export interface AxiosResponseTransformer { + (this: InternalAxiosRequestConfig, data: any, headers: AxiosResponseHeaders, status?: number): any; +} + +export interface AxiosAdapter { + (config: InternalAxiosRequestConfig): AxiosPromise; +} + +export interface AxiosBasicCredentials { + username: string; + password: string; +} + +export interface AxiosProxyConfig { + host: string; + port: number; + auth?: AxiosBasicCredentials; + protocol?: string; +} + +export enum HttpStatusCode { + Continue = 100, + SwitchingProtocols = 101, + Processing = 102, + EarlyHints = 103, + Ok = 200, + Created = 201, + Accepted = 202, + NonAuthoritativeInformation = 203, + NoContent = 204, + ResetContent = 205, + PartialContent = 206, + MultiStatus = 207, + AlreadyReported = 208, + ImUsed = 226, + MultipleChoices = 300, + MovedPermanently = 301, + Found = 302, + SeeOther = 303, + NotModified = 304, + UseProxy = 305, + Unused = 306, + TemporaryRedirect = 307, + PermanentRedirect = 308, + BadRequest = 400, + Unauthorized = 401, + PaymentRequired = 402, + Forbidden = 403, + NotFound = 404, + MethodNotAllowed = 405, + NotAcceptable = 406, + ProxyAuthenticationRequired = 407, + RequestTimeout = 408, + Conflict = 409, + Gone = 410, + LengthRequired = 411, + PreconditionFailed = 412, + PayloadTooLarge = 413, + UriTooLong = 414, + UnsupportedMediaType = 415, + RangeNotSatisfiable = 416, + ExpectationFailed = 417, + ImATeapot = 418, + MisdirectedRequest = 421, + UnprocessableEntity = 422, + Locked = 423, + FailedDependency = 424, + TooEarly = 425, + UpgradeRequired = 426, + PreconditionRequired = 428, + TooManyRequests = 429, + RequestHeaderFieldsTooLarge = 431, + UnavailableForLegalReasons = 451, + InternalServerError = 500, + NotImplemented = 501, + BadGateway = 502, + ServiceUnavailable = 503, + GatewayTimeout = 504, + HttpVersionNotSupported = 505, + VariantAlsoNegotiates = 506, + InsufficientStorage = 507, + LoopDetected = 508, + NotExtended = 510, + NetworkAuthenticationRequired = 511, +} + +export type Method = + | 'get' | 'GET' + | 'delete' | 'DELETE' + | 'head' | 'HEAD' + | 'options' | 'OPTIONS' + | 'post' | 'POST' + | 'put' | 'PUT' + | 'patch' | 'PATCH' + | 'purge' | 'PURGE' + | 'link' | 'LINK' + | 'unlink' | 'UNLINK'; + +export type ResponseType = + | 'arraybuffer' + | 'blob' + | 'document' + | 'json' + | 'text' + | 'stream' + | 'formdata'; + +export type responseEncoding = + | 'ascii' | 'ASCII' + | 'ansi' | 'ANSI' + | 'binary' | 'BINARY' + | 'base64' | 'BASE64' + | 'base64url' | 'BASE64URL' + | 'hex' | 'HEX' + | 'latin1' | 'LATIN1' + | 'ucs-2' | 'UCS-2' + | 'ucs2' | 'UCS2' + | 'utf-8' | 'UTF-8' + | 'utf8' | 'UTF8' + | 'utf16le' | 'UTF16LE'; + +export interface TransitionalOptions { + silentJSONParsing?: boolean; + forcedJSONParsing?: boolean; + clarifyTimeoutError?: boolean; +} + +export interface GenericAbortSignal { + readonly aborted: boolean; + onabort?: ((...args: any) => any) | null; + addEventListener?: (...args: any) => any; + removeEventListener?: (...args: any) => any; +} + +export interface FormDataVisitorHelpers { + defaultVisitor: SerializerVisitor; + convertValue: (value: any) => any; + isVisitable: (value: any) => boolean; +} + +export interface SerializerVisitor { + ( + this: GenericFormData, + value: any, + key: string | number, + path: null | Array, + helpers: FormDataVisitorHelpers + ): boolean; +} + +export interface SerializerOptions { + visitor?: SerializerVisitor; + dots?: boolean; + metaTokens?: boolean; + indexes?: boolean | null; +} + +// tslint:disable-next-line +export interface FormSerializerOptions extends SerializerOptions { +} + +export interface ParamEncoder { + (value: any, defaultEncoder: (value: any) => any): any; +} + +export interface CustomParamsSerializer { + (params: Record, options?: ParamsSerializerOptions): string; +} + +export interface ParamsSerializerOptions extends SerializerOptions { + encode?: ParamEncoder; + serialize?: CustomParamsSerializer; +} + +type MaxUploadRate = number; + +type MaxDownloadRate = number; + +type BrowserProgressEvent = any; + +export interface AxiosProgressEvent { + loaded: number; + total?: number; + progress?: number; + bytes: number; + rate?: number; + estimated?: number; + upload?: boolean; + download?: boolean; + event?: BrowserProgressEvent; + lengthComputable: boolean; +} + +type Milliseconds = number; + +type AxiosAdapterName = 'fetch' | 'xhr' | 'http' | (string & {}); + +type AxiosAdapterConfig = AxiosAdapter | AxiosAdapterName; + +export type AddressFamily = 4 | 6 | undefined; + +export interface LookupAddressEntry { + address: string; + family?: AddressFamily; +} + +export type LookupAddress = string | LookupAddressEntry; + +export interface AxiosRequestConfig { + url?: string; + method?: Method | string; + baseURL?: string; + allowAbsoluteUrls?: boolean; + transformRequest?: AxiosRequestTransformer | AxiosRequestTransformer[]; + transformResponse?: AxiosResponseTransformer | AxiosResponseTransformer[]; + headers?: (RawAxiosRequestHeaders & MethodsHeaders) | AxiosHeaders; + params?: any; + paramsSerializer?: ParamsSerializerOptions | CustomParamsSerializer; + data?: D; + timeout?: Milliseconds; + timeoutErrorMessage?: string; + withCredentials?: boolean; + adapter?: AxiosAdapterConfig | AxiosAdapterConfig[]; + auth?: AxiosBasicCredentials; + responseType?: ResponseType; + responseEncoding?: responseEncoding | string; + xsrfCookieName?: string; + xsrfHeaderName?: string; + onUploadProgress?: (progressEvent: AxiosProgressEvent) => void; + onDownloadProgress?: (progressEvent: AxiosProgressEvent) => void; + maxContentLength?: number; + validateStatus?: ((status: number) => boolean) | null; + maxBodyLength?: number; + maxRedirects?: number; + maxRate?: number | [MaxUploadRate, MaxDownloadRate]; + beforeRedirect?: (options: Record, responseDetails: {headers: Record, statusCode: HttpStatusCode}) => void; + socketPath?: string | null; + transport?: any; + httpAgent?: any; + httpsAgent?: any; + proxy?: AxiosProxyConfig | false; + cancelToken?: CancelToken; + decompress?: boolean; + transitional?: TransitionalOptions; + signal?: GenericAbortSignal; + insecureHTTPParser?: boolean; + env?: { + FormData?: new (...args: any[]) => object; + fetch?: (input: URL | Request | string, init?: RequestInit) => Promise; + Request?: new (input: URL | Request | string, init?: RequestInit) => Request; + Response?: new ( + body?: ArrayBuffer | ArrayBufferView | Blob | FormData | URLSearchParams | string | null, + init?: ResponseInit + ) => Response; + }; + formSerializer?: FormSerializerOptions; + family?: AddressFamily; + lookup?: ((hostname: string, options: object, cb: (err: Error | null, address: LookupAddress | LookupAddress[], family?: AddressFamily) => void) => void) | + ((hostname: string, options: object) => Promise<[address: LookupAddressEntry | LookupAddressEntry[], family?: AddressFamily] | LookupAddress>); + withXSRFToken?: boolean | ((config: InternalAxiosRequestConfig) => boolean | undefined); + parseReviver?: (this: any, key: string, value: any) => any; + fetchOptions?: Omit | Record; +} + +// Alias +export type RawAxiosRequestConfig = AxiosRequestConfig; + +export interface InternalAxiosRequestConfig extends AxiosRequestConfig { + headers: AxiosRequestHeaders; +} + +export interface HeadersDefaults { + common: RawAxiosRequestHeaders; + delete: RawAxiosRequestHeaders; + get: RawAxiosRequestHeaders; + head: RawAxiosRequestHeaders; + post: RawAxiosRequestHeaders; + put: RawAxiosRequestHeaders; + patch: RawAxiosRequestHeaders; + options?: RawAxiosRequestHeaders; + purge?: RawAxiosRequestHeaders; + link?: RawAxiosRequestHeaders; + unlink?: RawAxiosRequestHeaders; +} + +export interface AxiosDefaults extends Omit, 'headers'> { + headers: HeadersDefaults; +} + +export interface CreateAxiosDefaults extends Omit, 'headers'> { + headers?: RawAxiosRequestHeaders | AxiosHeaders | Partial; +} + +export interface AxiosResponse { + data: T; + status: number; + statusText: string; + headers: H & RawAxiosResponseHeaders | AxiosResponseHeaders; + config: InternalAxiosRequestConfig; + request?: any; +} + +export class AxiosError extends Error { + constructor( + message?: string, + code?: string, + config?: InternalAxiosRequestConfig, + request?: any, + response?: AxiosResponse + ); + + config?: InternalAxiosRequestConfig; + code?: string; + request?: any; + response?: AxiosResponse; + isAxiosError: boolean; + status?: number; + toJSON: () => object; + cause?: unknown; + event?: BrowserProgressEvent; + static from( + error: Error | unknown, + code?: string, + config?: InternalAxiosRequestConfig, + request?: any, + response?: AxiosResponse, + customProps?: object, +): AxiosError; + static readonly ERR_FR_TOO_MANY_REDIRECTS = "ERR_FR_TOO_MANY_REDIRECTS"; + static readonly ERR_BAD_OPTION_VALUE = "ERR_BAD_OPTION_VALUE"; + static readonly ERR_BAD_OPTION = "ERR_BAD_OPTION"; + static readonly ERR_NETWORK = "ERR_NETWORK"; + static readonly ERR_DEPRECATED = "ERR_DEPRECATED"; + static readonly ERR_BAD_RESPONSE = "ERR_BAD_RESPONSE"; + static readonly ERR_BAD_REQUEST = "ERR_BAD_REQUEST"; + static readonly ERR_NOT_SUPPORT = "ERR_NOT_SUPPORT"; + static readonly ERR_INVALID_URL = "ERR_INVALID_URL"; + static readonly ERR_CANCELED = "ERR_CANCELED"; + static readonly ECONNABORTED = "ECONNABORTED"; + static readonly ETIMEDOUT = "ETIMEDOUT"; +} + +export class CanceledError extends AxiosError { + readonly name: "CanceledError"; +} + +export type AxiosPromise = Promise>; + +export interface CancelStatic { + new (message?: string): Cancel; +} + +export interface Cancel { + message: string | undefined; +} + +export interface Canceler { + (message?: string, config?: AxiosRequestConfig, request?: any): void; +} + +export interface CancelTokenStatic { + new (executor: (cancel: Canceler) => void): CancelToken; + source(): CancelTokenSource; +} + +export interface CancelToken { + promise: Promise; + reason?: Cancel; + throwIfRequested(): void; +} + +export interface CancelTokenSource { + token: CancelToken; + cancel: Canceler; +} + +export interface AxiosInterceptorOptions { + synchronous?: boolean; + runWhen?: (config: InternalAxiosRequestConfig) => boolean; +} + +type AxiosRequestInterceptorUse = (onFulfilled?: ((value: T) => T | Promise) | null, onRejected?: ((error: any) => any) | null, options?: AxiosInterceptorOptions) => number; + +type AxiosResponseInterceptorUse = (onFulfilled?: ((value: T) => T | Promise) | null, onRejected?: ((error: any) => any) | null) => number; + +export interface AxiosInterceptorManager { + use: V extends AxiosResponse ? AxiosResponseInterceptorUse : AxiosRequestInterceptorUse; + eject(id: number): void; + clear(): void; +} + +export class Axios { + constructor(config?: AxiosRequestConfig); + defaults: AxiosDefaults; + interceptors: { + request: AxiosInterceptorManager; + response: AxiosInterceptorManager; + }; + getUri(config?: AxiosRequestConfig): string; + request, D = any>(config: AxiosRequestConfig): Promise; + get, D = any>(url: string, config?: AxiosRequestConfig): Promise; + delete, D = any>(url: string, config?: AxiosRequestConfig): Promise; + head, D = any>(url: string, config?: AxiosRequestConfig): Promise; + options, D = any>(url: string, config?: AxiosRequestConfig): Promise; + post, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise; + put, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise; + patch, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise; + postForm, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise; + putForm, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise; + patchForm, D = any>(url: string, data?: D, config?: AxiosRequestConfig): Promise; +} + +export interface AxiosInstance extends Axios { + , D = any>(config: AxiosRequestConfig): Promise; + , D = any>(url: string, config?: AxiosRequestConfig): Promise; + + create(config?: CreateAxiosDefaults): AxiosInstance; + defaults: Omit & { + headers: HeadersDefaults & { + [key: string]: AxiosHeaderValue + } + }; +} + +export interface GenericFormData { + append(name: string, value: any, options?: any): any; +} + +export interface GenericHTMLFormElement { + name: string; + method: string; + submit(): void; +} + +export function getAdapter(adapters: AxiosAdapterConfig | AxiosAdapterConfig[] | undefined): AxiosAdapter; + +export function toFormData(sourceObj: object, targetFormData?: GenericFormData, options?: FormSerializerOptions): GenericFormData; + +export function formToJSON(form: GenericFormData|GenericHTMLFormElement): object; + +export function isAxiosError(payload: any): payload is AxiosError; + +export function spread(callback: (...args: T[]) => R): (array: T[]) => R; + +export function isCancel(value: any): value is CanceledError; + +export function all(values: Array>): Promise; + +export function mergeConfig(config1: AxiosRequestConfig, config2: AxiosRequestConfig): AxiosRequestConfig; + +export interface AxiosStatic extends AxiosInstance { + Cancel: CancelStatic; + CancelToken: CancelTokenStatic; + Axios: typeof Axios; + AxiosError: typeof AxiosError; + HttpStatusCode: typeof HttpStatusCode; + readonly VERSION: string; + isCancel: typeof isCancel; + all: typeof all; + spread: typeof spread; + isAxiosError: typeof isAxiosError; + toFormData: typeof toFormData; + formToJSON: typeof formToJSON; + getAdapter: typeof getAdapter; + CanceledError: typeof CanceledError; + AxiosHeaders: typeof AxiosHeaders; + mergeConfig: typeof mergeConfig; +} + +declare const axios: AxiosStatic; + +export default axios; diff --git a/node_modules/axios/index.js b/node_modules/axios/index.js new file mode 100644 index 0000000..fba3990 --- /dev/null +++ b/node_modules/axios/index.js @@ -0,0 +1,43 @@ +import axios from './lib/axios.js'; + +// This module is intended to unwrap Axios default export as named. +// Keep top-level export same with static properties +// so that it can keep same with es module or cjs +const { + Axios, + AxiosError, + CanceledError, + isCancel, + CancelToken, + VERSION, + all, + Cancel, + isAxiosError, + spread, + toFormData, + AxiosHeaders, + HttpStatusCode, + formToJSON, + getAdapter, + mergeConfig +} = axios; + +export { + axios as default, + Axios, + AxiosError, + CanceledError, + isCancel, + CancelToken, + VERSION, + all, + Cancel, + isAxiosError, + spread, + toFormData, + AxiosHeaders, + HttpStatusCode, + formToJSON, + getAdapter, + mergeConfig +} diff --git a/node_modules/axios/lib/adapters/README.md b/node_modules/axios/lib/adapters/README.md new file mode 100644 index 0000000..68f1118 --- /dev/null +++ b/node_modules/axios/lib/adapters/README.md @@ -0,0 +1,37 @@ +# axios // adapters + +The modules under `adapters/` are modules that handle dispatching a request and settling a returned `Promise` once a response is received. + +## Example + +```js +var settle = require('./../core/settle'); + +module.exports = function myAdapter(config) { + // At this point: + // - config has been merged with defaults + // - request transformers have already run + // - request interceptors have already run + + // Make the request using config provided + // Upon response settle the Promise + + return new Promise(function(resolve, reject) { + + var response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config: config, + request: request + }; + + settle(resolve, reject, response); + + // From here: + // - response transformers will run + // - response interceptors will run + }); +} +``` diff --git a/node_modules/axios/lib/adapters/adapters.js b/node_modules/axios/lib/adapters/adapters.js new file mode 100644 index 0000000..7be725c --- /dev/null +++ b/node_modules/axios/lib/adapters/adapters.js @@ -0,0 +1,81 @@ +import utils from '../utils.js'; +import httpAdapter from './http.js'; +import xhrAdapter from './xhr.js'; +import * as fetchAdapter from './fetch.js'; +import AxiosError from "../core/AxiosError.js"; + +const knownAdapters = { + http: httpAdapter, + xhr: xhrAdapter, + fetch: { + get: fetchAdapter.getFetch, + } +} + +utils.forEach(knownAdapters, (fn, value) => { + if (fn) { + try { + Object.defineProperty(fn, 'name', {value}); + } catch (e) { + // eslint-disable-next-line no-empty + } + Object.defineProperty(fn, 'adapterName', {value}); + } +}); + +const renderReason = (reason) => `- ${reason}`; + +const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false; + +export default { + getAdapter: (adapters, config) => { + adapters = utils.isArray(adapters) ? adapters : [adapters]; + + const {length} = adapters; + let nameOrAdapter; + let adapter; + + const rejectedReasons = {}; + + for (let i = 0; i < length; i++) { + nameOrAdapter = adapters[i]; + let id; + + adapter = nameOrAdapter; + + if (!isResolvedHandle(nameOrAdapter)) { + adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()]; + + if (adapter === undefined) { + throw new AxiosError(`Unknown adapter '${id}'`); + } + } + + if (adapter && (utils.isFunction(adapter) || (adapter = adapter.get(config)))) { + break; + } + + rejectedReasons[id || '#' + i] = adapter; + } + + if (!adapter) { + + const reasons = Object.entries(rejectedReasons) + .map(([id, state]) => `adapter ${id} ` + + (state === false ? 'is not supported by the environment' : 'is not available in the build') + ); + + let s = length ? + (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) : + 'as no adapter specified'; + + throw new AxiosError( + `There is no suitable adapter to dispatch the request ` + s, + 'ERR_NOT_SUPPORT' + ); + } + + return adapter; + }, + adapters: knownAdapters +} diff --git a/node_modules/axios/lib/adapters/fetch.js b/node_modules/axios/lib/adapters/fetch.js new file mode 100644 index 0000000..8893b7b --- /dev/null +++ b/node_modules/axios/lib/adapters/fetch.js @@ -0,0 +1,288 @@ +import platform from "../platform/index.js"; +import utils from "../utils.js"; +import AxiosError from "../core/AxiosError.js"; +import composeSignals from "../helpers/composeSignals.js"; +import {trackStream} from "../helpers/trackStream.js"; +import AxiosHeaders from "../core/AxiosHeaders.js"; +import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js"; +import resolveConfig from "../helpers/resolveConfig.js"; +import settle from "../core/settle.js"; + +const DEFAULT_CHUNK_SIZE = 64 * 1024; + +const {isFunction} = utils; + +const globalFetchAPI = (({Request, Response}) => ({ + Request, Response +}))(utils.global); + +const { + ReadableStream, TextEncoder +} = utils.global; + + +const test = (fn, ...args) => { + try { + return !!fn(...args); + } catch (e) { + return false + } +} + +const factory = (env) => { + env = utils.merge.call({ + skipUndefined: true + }, globalFetchAPI, env); + + const {fetch: envFetch, Request, Response} = env; + const isFetchSupported = envFetch ? isFunction(envFetch) : typeof fetch === 'function'; + const isRequestSupported = isFunction(Request); + const isResponseSupported = isFunction(Response); + + if (!isFetchSupported) { + return false; + } + + const isReadableStreamSupported = isFetchSupported && isFunction(ReadableStream); + + const encodeText = isFetchSupported && (typeof TextEncoder === 'function' ? + ((encoder) => (str) => encoder.encode(str))(new TextEncoder()) : + async (str) => new Uint8Array(await new Request(str).arrayBuffer()) + ); + + const supportsRequestStream = isRequestSupported && isReadableStreamSupported && test(() => { + let duplexAccessed = false; + + const hasContentType = new Request(platform.origin, { + body: new ReadableStream(), + method: 'POST', + get duplex() { + duplexAccessed = true; + return 'half'; + }, + }).headers.has('Content-Type'); + + return duplexAccessed && !hasContentType; + }); + + const supportsResponseStream = isResponseSupported && isReadableStreamSupported && + test(() => utils.isReadableStream(new Response('').body)); + + const resolvers = { + stream: supportsResponseStream && ((res) => res.body) + }; + + isFetchSupported && ((() => { + ['text', 'arrayBuffer', 'blob', 'formData', 'stream'].forEach(type => { + !resolvers[type] && (resolvers[type] = (res, config) => { + let method = res && res[type]; + + if (method) { + return method.call(res); + } + + throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config); + }) + }); + })()); + + const getBodyLength = async (body) => { + if (body == null) { + return 0; + } + + if (utils.isBlob(body)) { + return body.size; + } + + if (utils.isSpecCompliantForm(body)) { + const _request = new Request(platform.origin, { + method: 'POST', + body, + }); + return (await _request.arrayBuffer()).byteLength; + } + + if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) { + return body.byteLength; + } + + if (utils.isURLSearchParams(body)) { + body = body + ''; + } + + if (utils.isString(body)) { + return (await encodeText(body)).byteLength; + } + } + + const resolveBodyLength = async (headers, body) => { + const length = utils.toFiniteNumber(headers.getContentLength()); + + return length == null ? getBodyLength(body) : length; + } + + return async (config) => { + let { + url, + method, + data, + signal, + cancelToken, + timeout, + onDownloadProgress, + onUploadProgress, + responseType, + headers, + withCredentials = 'same-origin', + fetchOptions + } = resolveConfig(config); + + let _fetch = envFetch || fetch; + + responseType = responseType ? (responseType + '').toLowerCase() : 'text'; + + let composedSignal = composeSignals([signal, cancelToken && cancelToken.toAbortSignal()], timeout); + + let request = null; + + const unsubscribe = composedSignal && composedSignal.unsubscribe && (() => { + composedSignal.unsubscribe(); + }); + + let requestContentLength; + + try { + if ( + onUploadProgress && supportsRequestStream && method !== 'get' && method !== 'head' && + (requestContentLength = await resolveBodyLength(headers, data)) !== 0 + ) { + let _request = new Request(url, { + method: 'POST', + body: data, + duplex: "half" + }); + + let contentTypeHeader; + + if (utils.isFormData(data) && (contentTypeHeader = _request.headers.get('content-type'))) { + headers.setContentType(contentTypeHeader) + } + + if (_request.body) { + const [onProgress, flush] = progressEventDecorator( + requestContentLength, + progressEventReducer(asyncDecorator(onUploadProgress)) + ); + + data = trackStream(_request.body, DEFAULT_CHUNK_SIZE, onProgress, flush); + } + } + + if (!utils.isString(withCredentials)) { + withCredentials = withCredentials ? 'include' : 'omit'; + } + + // Cloudflare Workers throws when credentials are defined + // see https://github.com/cloudflare/workerd/issues/902 + const isCredentialsSupported = isRequestSupported && "credentials" in Request.prototype; + + const resolvedOptions = { + ...fetchOptions, + signal: composedSignal, + method: method.toUpperCase(), + headers: headers.normalize().toJSON(), + body: data, + duplex: "half", + credentials: isCredentialsSupported ? withCredentials : undefined + }; + + request = isRequestSupported && new Request(url, resolvedOptions); + + let response = await (isRequestSupported ? _fetch(request, fetchOptions) : _fetch(url, resolvedOptions)); + + const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response'); + + if (supportsResponseStream && (onDownloadProgress || (isStreamResponse && unsubscribe))) { + const options = {}; + + ['status', 'statusText', 'headers'].forEach(prop => { + options[prop] = response[prop]; + }); + + const responseContentLength = utils.toFiniteNumber(response.headers.get('content-length')); + + const [onProgress, flush] = onDownloadProgress && progressEventDecorator( + responseContentLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true) + ) || []; + + response = new Response( + trackStream(response.body, DEFAULT_CHUNK_SIZE, onProgress, () => { + flush && flush(); + unsubscribe && unsubscribe(); + }), + options + ); + } + + responseType = responseType || 'text'; + + let responseData = await resolvers[utils.findKey(resolvers, responseType) || 'text'](response, config); + + !isStreamResponse && unsubscribe && unsubscribe(); + + return await new Promise((resolve, reject) => { + settle(resolve, reject, { + data: responseData, + headers: AxiosHeaders.from(response.headers), + status: response.status, + statusText: response.statusText, + config, + request + }) + }) + } catch (err) { + unsubscribe && unsubscribe(); + + if (err && err.name === 'TypeError' && /Load failed|fetch/i.test(err.message)) { + throw Object.assign( + new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request), + { + cause: err.cause || err + } + ) + } + + throw AxiosError.from(err, err && err.code, config, request); + } + } +} + +const seedCache = new Map(); + +export const getFetch = (config) => { + let env = config ? config.env : {}; + const {fetch, Request, Response} = env; + const seeds = [ + Request, Response, fetch + ]; + + let len = seeds.length, i = len, + seed, target, map = seedCache; + + while (i--) { + seed = seeds[i]; + target = map.get(seed); + + target === undefined && map.set(seed, target = (i ? new Map() : factory(env))) + + map = target; + } + + return target; +}; + +const adapter = getFetch(); + +export default adapter; diff --git a/node_modules/axios/lib/adapters/http.js b/node_modules/axios/lib/adapters/http.js new file mode 100755 index 0000000..a3489b2 --- /dev/null +++ b/node_modules/axios/lib/adapters/http.js @@ -0,0 +1,713 @@ +'use strict'; + +import utils from './../utils.js'; +import settle from './../core/settle.js'; +import buildFullPath from '../core/buildFullPath.js'; +import buildURL from './../helpers/buildURL.js'; +import proxyFromEnv from 'proxy-from-env'; +import http from 'http'; +import https from 'https'; +import util from 'util'; +import followRedirects from 'follow-redirects'; +import zlib from 'zlib'; +import {VERSION} from '../env/data.js'; +import transitionalDefaults from '../defaults/transitional.js'; +import AxiosError from '../core/AxiosError.js'; +import CanceledError from '../cancel/CanceledError.js'; +import platform from '../platform/index.js'; +import fromDataURI from '../helpers/fromDataURI.js'; +import stream from 'stream'; +import AxiosHeaders from '../core/AxiosHeaders.js'; +import AxiosTransformStream from '../helpers/AxiosTransformStream.js'; +import {EventEmitter} from 'events'; +import formDataToStream from "../helpers/formDataToStream.js"; +import readBlob from "../helpers/readBlob.js"; +import ZlibHeaderTransformStream from '../helpers/ZlibHeaderTransformStream.js'; +import callbackify from "../helpers/callbackify.js"; +import {progressEventReducer, progressEventDecorator, asyncDecorator} from "../helpers/progressEventReducer.js"; +import estimateDataURLDecodedBytes from '../helpers/estimateDataURLDecodedBytes.js'; + +const zlibOptions = { + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH +}; + +const brotliOptions = { + flush: zlib.constants.BROTLI_OPERATION_FLUSH, + finishFlush: zlib.constants.BROTLI_OPERATION_FLUSH +} + +const isBrotliSupported = utils.isFunction(zlib.createBrotliDecompress); + +const {http: httpFollow, https: httpsFollow} = followRedirects; + +const isHttps = /https:?/; + +const supportedProtocols = platform.protocols.map(protocol => { + return protocol + ':'; +}); + + +const flushOnFinish = (stream, [throttled, flush]) => { + stream + .on('end', flush) + .on('error', flush); + + return throttled; +} + + +/** + * If the proxy or config beforeRedirects functions are defined, call them with the options + * object. + * + * @param {Object} options - The options object that was passed to the request. + * + * @returns {Object} + */ +function dispatchBeforeRedirect(options, responseDetails) { + if (options.beforeRedirects.proxy) { + options.beforeRedirects.proxy(options); + } + if (options.beforeRedirects.config) { + options.beforeRedirects.config(options, responseDetails); + } +} + +/** + * If the proxy or config afterRedirects functions are defined, call them with the options + * + * @param {http.ClientRequestArgs} options + * @param {AxiosProxyConfig} configProxy configuration from Axios options object + * @param {string} location + * + * @returns {http.ClientRequestArgs} + */ +function setProxy(options, configProxy, location) { + let proxy = configProxy; + if (!proxy && proxy !== false) { + const proxyUrl = proxyFromEnv.getProxyForUrl(location); + if (proxyUrl) { + proxy = new URL(proxyUrl); + } + } + if (proxy) { + // Basic proxy authorization + if (proxy.username) { + proxy.auth = (proxy.username || '') + ':' + (proxy.password || ''); + } + + if (proxy.auth) { + // Support proxy auth object form + if (proxy.auth.username || proxy.auth.password) { + proxy.auth = (proxy.auth.username || '') + ':' + (proxy.auth.password || ''); + } + const base64 = Buffer + .from(proxy.auth, 'utf8') + .toString('base64'); + options.headers['Proxy-Authorization'] = 'Basic ' + base64; + } + + options.headers.host = options.hostname + (options.port ? ':' + options.port : ''); + const proxyHost = proxy.hostname || proxy.host; + options.hostname = proxyHost; + // Replace 'host' since options is not a URL object + options.host = proxyHost; + options.port = proxy.port; + options.path = location; + if (proxy.protocol) { + options.protocol = proxy.protocol.includes(':') ? proxy.protocol : `${proxy.protocol}:`; + } + } + + options.beforeRedirects.proxy = function beforeRedirect(redirectOptions) { + // Configure proxy for redirected request, passing the original config proxy to apply + // the exact same logic as if the redirected request was performed by axios directly. + setProxy(redirectOptions, configProxy, redirectOptions.href); + }; +} + +const isHttpAdapterSupported = typeof process !== 'undefined' && utils.kindOf(process) === 'process'; + +// temporary hotfix + +const wrapAsync = (asyncExecutor) => { + return new Promise((resolve, reject) => { + let onDone; + let isDone; + + const done = (value, isRejected) => { + if (isDone) return; + isDone = true; + onDone && onDone(value, isRejected); + } + + const _resolve = (value) => { + done(value); + resolve(value); + }; + + const _reject = (reason) => { + done(reason, true); + reject(reason); + } + + asyncExecutor(_resolve, _reject, (onDoneHandler) => (onDone = onDoneHandler)).catch(_reject); + }) +}; + +const resolveFamily = ({address, family}) => { + if (!utils.isString(address)) { + throw TypeError('address must be a string'); + } + return ({ + address, + family: family || (address.indexOf('.') < 0 ? 6 : 4) + }); +} + +const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family}); + +/*eslint consistent-return:0*/ +export default isHttpAdapterSupported && function httpAdapter(config) { + return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) { + let {data, lookup, family} = config; + const {responseType, responseEncoding} = config; + const method = config.method.toUpperCase(); + let isDone; + let rejected = false; + let req; + + if (lookup) { + const _lookup = callbackify(lookup, (value) => utils.isArray(value) ? value : [value]); + // hotfix to support opt.all option which is required for node 20.x + lookup = (hostname, opt, cb) => { + _lookup(hostname, opt, (err, arg0, arg1) => { + if (err) { + return cb(err); + } + + const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)]; + + opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family); + }); + } + } + + // temporary internal emitter until the AxiosRequest class will be implemented + const emitter = new EventEmitter(); + + const onFinished = () => { + if (config.cancelToken) { + config.cancelToken.unsubscribe(abort); + } + + if (config.signal) { + config.signal.removeEventListener('abort', abort); + } + + emitter.removeAllListeners(); + } + + onDone((value, isRejected) => { + isDone = true; + if (isRejected) { + rejected = true; + onFinished(); + } + }); + + function abort(reason) { + emitter.emit('abort', !reason || reason.type ? new CanceledError(null, config, req) : reason); + } + + emitter.once('abort', reject); + + if (config.cancelToken || config.signal) { + config.cancelToken && config.cancelToken.subscribe(abort); + if (config.signal) { + config.signal.aborted ? abort() : config.signal.addEventListener('abort', abort); + } + } + + // Parse url + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + const parsed = new URL(fullPath, platform.hasBrowserEnv ? platform.origin : undefined); + const protocol = parsed.protocol || supportedProtocols[0]; + + if (protocol === 'data:') { + // Apply the same semantics as HTTP: only enforce if a finite, non-negative cap is set. + if (config.maxContentLength > -1) { + // Use the exact string passed to fromDataURI (config.url); fall back to fullPath if needed. + const dataUrl = String(config.url || fullPath || ''); + const estimated = estimateDataURLDecodedBytes(dataUrl); + + if (estimated > config.maxContentLength) { + return reject(new AxiosError( + 'maxContentLength size of ' + config.maxContentLength + ' exceeded', + AxiosError.ERR_BAD_RESPONSE, + config + )); + } + } + + let convertedData; + + if (method !== 'GET') { + return settle(resolve, reject, { + status: 405, + statusText: 'method not allowed', + headers: {}, + config + }); + } + + try { + convertedData = fromDataURI(config.url, responseType === 'blob', { + Blob: config.env && config.env.Blob + }); + } catch (err) { + throw AxiosError.from(err, AxiosError.ERR_BAD_REQUEST, config); + } + + if (responseType === 'text') { + convertedData = convertedData.toString(responseEncoding); + + if (!responseEncoding || responseEncoding === 'utf8') { + convertedData = utils.stripBOM(convertedData); + } + } else if (responseType === 'stream') { + convertedData = stream.Readable.from(convertedData); + } + + return settle(resolve, reject, { + data: convertedData, + status: 200, + statusText: 'OK', + headers: new AxiosHeaders(), + config + }); + } + + if (supportedProtocols.indexOf(protocol) === -1) { + return reject(new AxiosError( + 'Unsupported protocol ' + protocol, + AxiosError.ERR_BAD_REQUEST, + config + )); + } + + const headers = AxiosHeaders.from(config.headers).normalize(); + + // Set User-Agent (required by some servers) + // See https://github.com/axios/axios/issues/69 + // User-Agent is specified; handle case where no UA header is desired + // Only set header if it hasn't been set in config + headers.set('User-Agent', 'axios/' + VERSION, false); + + const {onUploadProgress, onDownloadProgress} = config; + const maxRate = config.maxRate; + let maxUploadRate = undefined; + let maxDownloadRate = undefined; + + // support for spec compliant FormData objects + if (utils.isSpecCompliantForm(data)) { + const userBoundary = headers.getContentType(/boundary=([-_\w\d]{10,70})/i); + + data = formDataToStream(data, (formHeaders) => { + headers.set(formHeaders); + }, { + tag: `axios-${VERSION}-boundary`, + boundary: userBoundary && userBoundary[1] || undefined + }); + // support for https://www.npmjs.com/package/form-data api + } else if (utils.isFormData(data) && utils.isFunction(data.getHeaders)) { + headers.set(data.getHeaders()); + + if (!headers.hasContentLength()) { + try { + const knownLength = await util.promisify(data.getLength).call(data); + Number.isFinite(knownLength) && knownLength >= 0 && headers.setContentLength(knownLength); + /*eslint no-empty:0*/ + } catch (e) { + } + } + } else if (utils.isBlob(data) || utils.isFile(data)) { + data.size && headers.setContentType(data.type || 'application/octet-stream'); + headers.setContentLength(data.size || 0); + data = stream.Readable.from(readBlob(data)); + } else if (data && !utils.isStream(data)) { + if (Buffer.isBuffer(data)) { + // Nothing to do... + } else if (utils.isArrayBuffer(data)) { + data = Buffer.from(new Uint8Array(data)); + } else if (utils.isString(data)) { + data = Buffer.from(data, 'utf-8'); + } else { + return reject(new AxiosError( + 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream', + AxiosError.ERR_BAD_REQUEST, + config + )); + } + + // Add Content-Length header if data exists + headers.setContentLength(data.length, false); + + if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) { + return reject(new AxiosError( + 'Request body larger than maxBodyLength limit', + AxiosError.ERR_BAD_REQUEST, + config + )); + } + } + + const contentLength = utils.toFiniteNumber(headers.getContentLength()); + + if (utils.isArray(maxRate)) { + maxUploadRate = maxRate[0]; + maxDownloadRate = maxRate[1]; + } else { + maxUploadRate = maxDownloadRate = maxRate; + } + + if (data && (onUploadProgress || maxUploadRate)) { + if (!utils.isStream(data)) { + data = stream.Readable.from(data, {objectMode: false}); + } + + data = stream.pipeline([data, new AxiosTransformStream({ + maxRate: utils.toFiniteNumber(maxUploadRate) + })], utils.noop); + + onUploadProgress && data.on('progress', flushOnFinish( + data, + progressEventDecorator( + contentLength, + progressEventReducer(asyncDecorator(onUploadProgress), false, 3) + ) + )); + } + + // HTTP basic authentication + let auth = undefined; + if (config.auth) { + const username = config.auth.username || ''; + const password = config.auth.password || ''; + auth = username + ':' + password; + } + + if (!auth && parsed.username) { + const urlUsername = parsed.username; + const urlPassword = parsed.password; + auth = urlUsername + ':' + urlPassword; + } + + auth && headers.delete('authorization'); + + let path; + + try { + path = buildURL( + parsed.pathname + parsed.search, + config.params, + config.paramsSerializer + ).replace(/^\?/, ''); + } catch (err) { + const customErr = new Error(err.message); + customErr.config = config; + customErr.url = config.url; + customErr.exists = true; + return reject(customErr); + } + + headers.set( + 'Accept-Encoding', + 'gzip, compress, deflate' + (isBrotliSupported ? ', br' : ''), false + ); + + const options = { + path, + method: method, + headers: headers.toJSON(), + agents: { http: config.httpAgent, https: config.httpsAgent }, + auth, + protocol, + family, + beforeRedirect: dispatchBeforeRedirect, + beforeRedirects: {} + }; + + // cacheable-lookup integration hotfix + !utils.isUndefined(lookup) && (options.lookup = lookup); + + if (config.socketPath) { + options.socketPath = config.socketPath; + } else { + options.hostname = parsed.hostname.startsWith("[") ? parsed.hostname.slice(1, -1) : parsed.hostname; + options.port = parsed.port; + setProxy(options, config.proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path); + } + + let transport; + const isHttpsRequest = isHttps.test(options.protocol); + options.agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; + if (config.transport) { + transport = config.transport; + } else if (config.maxRedirects === 0) { + transport = isHttpsRequest ? https : http; + } else { + if (config.maxRedirects) { + options.maxRedirects = config.maxRedirects; + } + if (config.beforeRedirect) { + options.beforeRedirects.config = config.beforeRedirect; + } + transport = isHttpsRequest ? httpsFollow : httpFollow; + } + + if (config.maxBodyLength > -1) { + options.maxBodyLength = config.maxBodyLength; + } else { + // follow-redirects does not skip comparison, so it should always succeed for axios -1 unlimited + options.maxBodyLength = Infinity; + } + + if (config.insecureHTTPParser) { + options.insecureHTTPParser = config.insecureHTTPParser; + } + + // Create the request + req = transport.request(options, function handleResponse(res) { + if (req.destroyed) return; + + const streams = [res]; + + const responseLength = +res.headers['content-length']; + + if (onDownloadProgress || maxDownloadRate) { + const transformStream = new AxiosTransformStream({ + maxRate: utils.toFiniteNumber(maxDownloadRate) + }); + + onDownloadProgress && transformStream.on('progress', flushOnFinish( + transformStream, + progressEventDecorator( + responseLength, + progressEventReducer(asyncDecorator(onDownloadProgress), true, 3) + ) + )); + + streams.push(transformStream); + } + + // decompress the response body transparently if required + let responseStream = res; + + // return the last request in case of redirects + const lastRequest = res.req || req; + + // if decompress disabled we should not decompress + if (config.decompress !== false && res.headers['content-encoding']) { + // if no content, but headers still say that it is encoded, + // remove the header not confuse downstream operations + if (method === 'HEAD' || res.statusCode === 204) { + delete res.headers['content-encoding']; + } + + switch ((res.headers['content-encoding'] || '').toLowerCase()) { + /*eslint default-case:0*/ + case 'gzip': + case 'x-gzip': + case 'compress': + case 'x-compress': + // add the unzipper to the body stream processing pipeline + streams.push(zlib.createUnzip(zlibOptions)); + + // remove the content-encoding in order to not confuse downstream operations + delete res.headers['content-encoding']; + break; + case 'deflate': + streams.push(new ZlibHeaderTransformStream()); + + // add the unzipper to the body stream processing pipeline + streams.push(zlib.createUnzip(zlibOptions)); + + // remove the content-encoding in order to not confuse downstream operations + delete res.headers['content-encoding']; + break; + case 'br': + if (isBrotliSupported) { + streams.push(zlib.createBrotliDecompress(brotliOptions)); + delete res.headers['content-encoding']; + } + } + } + + responseStream = streams.length > 1 ? stream.pipeline(streams, utils.noop) : streams[0]; + + const offListeners = stream.finished(responseStream, () => { + offListeners(); + onFinished(); + }); + + const response = { + status: res.statusCode, + statusText: res.statusMessage, + headers: new AxiosHeaders(res.headers), + config, + request: lastRequest + }; + + if (responseType === 'stream') { + response.data = responseStream; + settle(resolve, reject, response); + } else { + const responseBuffer = []; + let totalResponseBytes = 0; + + responseStream.on('data', function handleStreamData(chunk) { + responseBuffer.push(chunk); + totalResponseBytes += chunk.length; + + // make sure the content length is not over the maxContentLength if specified + if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) { + // stream.destroy() emit aborted event before calling reject() on Node.js v16 + rejected = true; + responseStream.destroy(); + reject(new AxiosError('maxContentLength size of ' + config.maxContentLength + ' exceeded', + AxiosError.ERR_BAD_RESPONSE, config, lastRequest)); + } + }); + + responseStream.on('aborted', function handlerStreamAborted() { + if (rejected) { + return; + } + + const err = new AxiosError( + 'stream has been aborted', + AxiosError.ERR_BAD_RESPONSE, + config, + lastRequest + ); + responseStream.destroy(err); + reject(err); + }); + + responseStream.on('error', function handleStreamError(err) { + if (req.destroyed) return; + reject(AxiosError.from(err, null, config, lastRequest)); + }); + + responseStream.on('end', function handleStreamEnd() { + try { + let responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer); + if (responseType !== 'arraybuffer') { + responseData = responseData.toString(responseEncoding); + if (!responseEncoding || responseEncoding === 'utf8') { + responseData = utils.stripBOM(responseData); + } + } + response.data = responseData; + } catch (err) { + return reject(AxiosError.from(err, null, config, response.request, response)); + } + settle(resolve, reject, response); + }); + } + + emitter.once('abort', err => { + if (!responseStream.destroyed) { + responseStream.emit('error', err); + responseStream.destroy(); + } + }); + }); + + emitter.once('abort', err => { + reject(err); + req.destroy(err); + }); + + // Handle errors + req.on('error', function handleRequestError(err) { + // @todo remove + // if (req.aborted && err.code !== AxiosError.ERR_FR_TOO_MANY_REDIRECTS) return; + reject(AxiosError.from(err, null, config, req)); + }); + + // set tcp keep alive to prevent drop connection by peer + req.on('socket', function handleRequestSocket(socket) { + // default interval of sending ack packet is 1 minute + socket.setKeepAlive(true, 1000 * 60); + }); + + // Handle request timeout + if (config.timeout) { + // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types. + const timeout = parseInt(config.timeout, 10); + + if (Number.isNaN(timeout)) { + reject(new AxiosError( + 'error trying to parse `config.timeout` to int', + AxiosError.ERR_BAD_OPTION_VALUE, + config, + req + )); + + return; + } + + // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system. + // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET. + // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up. + // And then these socket which be hang up will devouring CPU little by little. + // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect. + req.setTimeout(timeout, function handleRequestTimeout() { + if (isDone) return; + let timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = config.transitional || transitionalDefaults; + if (config.timeoutErrorMessage) { + timeoutErrorMessage = config.timeoutErrorMessage; + } + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + req + )); + abort(); + }); + } + + + // Send the request + if (utils.isStream(data)) { + let ended = false; + let errored = false; + + data.on('end', () => { + ended = true; + }); + + data.once('error', err => { + errored = true; + req.destroy(err); + }); + + data.on('close', () => { + if (!ended && !errored) { + abort(new CanceledError('Request stream has been aborted', config, req)); + } + }); + + data.pipe(req); + } else { + req.end(data); + } + }); +} + +export const __setProxy = setProxy; diff --git a/node_modules/axios/lib/adapters/xhr.js b/node_modules/axios/lib/adapters/xhr.js new file mode 100644 index 0000000..0223618 --- /dev/null +++ b/node_modules/axios/lib/adapters/xhr.js @@ -0,0 +1,200 @@ +import utils from './../utils.js'; +import settle from './../core/settle.js'; +import transitionalDefaults from '../defaults/transitional.js'; +import AxiosError from '../core/AxiosError.js'; +import CanceledError from '../cancel/CanceledError.js'; +import parseProtocol from '../helpers/parseProtocol.js'; +import platform from '../platform/index.js'; +import AxiosHeaders from '../core/AxiosHeaders.js'; +import {progressEventReducer} from '../helpers/progressEventReducer.js'; +import resolveConfig from "../helpers/resolveConfig.js"; + +const isXHRAdapterSupported = typeof XMLHttpRequest !== 'undefined'; + +export default isXHRAdapterSupported && function (config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + const _config = resolveConfig(config); + let requestData = _config.data; + const requestHeaders = AxiosHeaders.from(_config.headers).normalize(); + let {responseType, onUploadProgress, onDownloadProgress} = _config; + let onCanceled; + let uploadThrottled, downloadThrottled; + let flushUpload, flushDownload; + + function done() { + flushUpload && flushUpload(); // flush events + flushDownload && flushDownload(); // flush events + + _config.cancelToken && _config.cancelToken.unsubscribe(onCanceled); + + _config.signal && _config.signal.removeEventListener('abort', onCanceled); + } + + let request = new XMLHttpRequest(); + + request.open(_config.method.toUpperCase(), _config.url, true); + + // Set the request timeout in MS + request.timeout = _config.timeout; + + function onloadend() { + if (!request) { + return; + } + // Prepare the response + const responseHeaders = AxiosHeaders.from( + 'getAllResponseHeaders' in request && request.getAllResponseHeaders() + ); + const responseData = !responseType || responseType === 'text' || responseType === 'json' ? + request.responseText : request.response; + const response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config, + request + }; + + settle(function _resolve(value) { + resolve(value); + done(); + }, function _reject(err) { + reject(err); + done(); + }, response); + + // Clean up request + request = null; + } + + if ('onloadend' in request) { + // Use onloadend if available + request.onloadend = onloadend; + } else { + // Listen for ready state to emulate onloadend + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + // readystate handler is calling before onerror or ontimeout handlers, + // so we should call onloadend on the next 'tick' + setTimeout(onloadend); + }; + } + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError(event) { + // Browsers deliver a ProgressEvent in XHR onerror + // (message may be empty; when present, surface it) + // See https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/error_event + const msg = event && event.message ? event.message : 'Network Error'; + const err = new AxiosError(msg, AxiosError.ERR_NETWORK, config, request); + // attach the underlying event for consumers who want details + err.event = event || null; + reject(err); + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + let timeoutErrorMessage = _config.timeout ? 'timeout of ' + _config.timeout + 'ms exceeded' : 'timeout exceeded'; + const transitional = _config.transitional || transitionalDefaults; + if (_config.timeoutErrorMessage) { + timeoutErrorMessage = _config.timeoutErrorMessage; + } + reject(new AxiosError( + timeoutErrorMessage, + transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, + config, + request)); + + // Clean up request + request = null; + }; + + // Remove Content-Type if data is undefined + requestData === undefined && requestHeaders.setContentType(null); + + // Add headers to the request + if ('setRequestHeader' in request) { + utils.forEach(requestHeaders.toJSON(), function setRequestHeader(val, key) { + request.setRequestHeader(key, val); + }); + } + + // Add withCredentials to request if needed + if (!utils.isUndefined(_config.withCredentials)) { + request.withCredentials = !!_config.withCredentials; + } + + // Add responseType to request if needed + if (responseType && responseType !== 'json') { + request.responseType = _config.responseType; + } + + // Handle progress if needed + if (onDownloadProgress) { + ([downloadThrottled, flushDownload] = progressEventReducer(onDownloadProgress, true)); + request.addEventListener('progress', downloadThrottled); + } + + // Not all browsers support upload events + if (onUploadProgress && request.upload) { + ([uploadThrottled, flushUpload] = progressEventReducer(onUploadProgress)); + + request.upload.addEventListener('progress', uploadThrottled); + + request.upload.addEventListener('loadend', flushUpload); + } + + if (_config.cancelToken || _config.signal) { + // Handle cancellation + // eslint-disable-next-line func-names + onCanceled = cancel => { + if (!request) { + return; + } + reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel); + request.abort(); + request = null; + }; + + _config.cancelToken && _config.cancelToken.subscribe(onCanceled); + if (_config.signal) { + _config.signal.aborted ? onCanceled() : _config.signal.addEventListener('abort', onCanceled); + } + } + + const protocol = parseProtocol(_config.url); + + if (protocol && platform.protocols.indexOf(protocol) === -1) { + reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config)); + return; + } + + + // Send the request + request.send(requestData || null); + }); +} diff --git a/node_modules/axios/lib/axios.js b/node_modules/axios/lib/axios.js new file mode 100644 index 0000000..873f246 --- /dev/null +++ b/node_modules/axios/lib/axios.js @@ -0,0 +1,89 @@ +'use strict'; + +import utils from './utils.js'; +import bind from './helpers/bind.js'; +import Axios from './core/Axios.js'; +import mergeConfig from './core/mergeConfig.js'; +import defaults from './defaults/index.js'; +import formDataToJSON from './helpers/formDataToJSON.js'; +import CanceledError from './cancel/CanceledError.js'; +import CancelToken from './cancel/CancelToken.js'; +import isCancel from './cancel/isCancel.js'; +import {VERSION} from './env/data.js'; +import toFormData from './helpers/toFormData.js'; +import AxiosError from './core/AxiosError.js'; +import spread from './helpers/spread.js'; +import isAxiosError from './helpers/isAxiosError.js'; +import AxiosHeaders from "./core/AxiosHeaders.js"; +import adapters from './adapters/adapters.js'; +import HttpStatusCode from './helpers/HttpStatusCode.js'; + +/** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * + * @returns {Axios} A new instance of Axios + */ +function createInstance(defaultConfig) { + const context = new Axios(defaultConfig); + const instance = bind(Axios.prototype.request, context); + + // Copy axios.prototype to instance + utils.extend(instance, Axios.prototype, context, {allOwnKeys: true}); + + // Copy context to instance + utils.extend(instance, context, null, {allOwnKeys: true}); + + // Factory for creating new instances + instance.create = function create(instanceConfig) { + return createInstance(mergeConfig(defaultConfig, instanceConfig)); + }; + + return instance; +} + +// Create the default instance to be exported +const axios = createInstance(defaults); + +// Expose Axios class to allow class inheritance +axios.Axios = Axios; + +// Expose Cancel & CancelToken +axios.CanceledError = CanceledError; +axios.CancelToken = CancelToken; +axios.isCancel = isCancel; +axios.VERSION = VERSION; +axios.toFormData = toFormData; + +// Expose AxiosError class +axios.AxiosError = AxiosError; + +// alias for CanceledError for backward compatibility +axios.Cancel = axios.CanceledError; + +// Expose all/spread +axios.all = function all(promises) { + return Promise.all(promises); +}; + +axios.spread = spread; + +// Expose isAxiosError +axios.isAxiosError = isAxiosError; + +// Expose mergeConfig +axios.mergeConfig = mergeConfig; + +axios.AxiosHeaders = AxiosHeaders; + +axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing); + +axios.getAdapter = adapters.getAdapter; + +axios.HttpStatusCode = HttpStatusCode; + +axios.default = axios; + +// this module should only have a default export +export default axios diff --git a/node_modules/axios/lib/cancel/CancelToken.js b/node_modules/axios/lib/cancel/CancelToken.js new file mode 100644 index 0000000..0fc2025 --- /dev/null +++ b/node_modules/axios/lib/cancel/CancelToken.js @@ -0,0 +1,135 @@ +'use strict'; + +import CanceledError from './CanceledError.js'; + +/** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @param {Function} executor The executor function. + * + * @returns {CancelToken} + */ +class CancelToken { + constructor(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + + let resolvePromise; + + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + + const token = this; + + // eslint-disable-next-line func-names + this.promise.then(cancel => { + if (!token._listeners) return; + + let i = token._listeners.length; + + while (i-- > 0) { + token._listeners[i](cancel); + } + token._listeners = null; + }); + + // eslint-disable-next-line func-names + this.promise.then = onfulfilled => { + let _resolve; + // eslint-disable-next-line func-names + const promise = new Promise(resolve => { + token.subscribe(resolve); + _resolve = resolve; + }).then(onfulfilled); + + promise.cancel = function reject() { + token.unsubscribe(_resolve); + }; + + return promise; + }; + + executor(function cancel(message, config, request) { + if (token.reason) { + // Cancellation has already been requested + return; + } + + token.reason = new CanceledError(message, config, request); + resolvePromise(token.reason); + }); + } + + /** + * Throws a `CanceledError` if cancellation has been requested. + */ + throwIfRequested() { + if (this.reason) { + throw this.reason; + } + } + + /** + * Subscribe to the cancel signal + */ + + subscribe(listener) { + if (this.reason) { + listener(this.reason); + return; + } + + if (this._listeners) { + this._listeners.push(listener); + } else { + this._listeners = [listener]; + } + } + + /** + * Unsubscribe from the cancel signal + */ + + unsubscribe(listener) { + if (!this._listeners) { + return; + } + const index = this._listeners.indexOf(listener); + if (index !== -1) { + this._listeners.splice(index, 1); + } + } + + toAbortSignal() { + const controller = new AbortController(); + + const abort = (err) => { + controller.abort(err); + }; + + this.subscribe(abort); + + controller.signal.unsubscribe = () => this.unsubscribe(abort); + + return controller.signal; + } + + /** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ + static source() { + let cancel; + const token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token, + cancel + }; + } +} + +export default CancelToken; diff --git a/node_modules/axios/lib/cancel/CanceledError.js b/node_modules/axios/lib/cancel/CanceledError.js new file mode 100644 index 0000000..880066e --- /dev/null +++ b/node_modules/axios/lib/cancel/CanceledError.js @@ -0,0 +1,25 @@ +'use strict'; + +import AxiosError from '../core/AxiosError.js'; +import utils from '../utils.js'; + +/** + * A `CanceledError` is an object that is thrown when an operation is canceled. + * + * @param {string=} message The message. + * @param {Object=} config The config. + * @param {Object=} request The request. + * + * @returns {CanceledError} The created error. + */ +function CanceledError(message, config, request) { + // eslint-disable-next-line no-eq-null,eqeqeq + AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); + this.name = 'CanceledError'; +} + +utils.inherits(CanceledError, AxiosError, { + __CANCEL__: true +}); + +export default CanceledError; diff --git a/node_modules/axios/lib/cancel/isCancel.js b/node_modules/axios/lib/cancel/isCancel.js new file mode 100644 index 0000000..a444a12 --- /dev/null +++ b/node_modules/axios/lib/cancel/isCancel.js @@ -0,0 +1,5 @@ +'use strict'; + +export default function isCancel(value) { + return !!(value && value.__CANCEL__); +} diff --git a/node_modules/axios/lib/core/Axios.js b/node_modules/axios/lib/core/Axios.js new file mode 100644 index 0000000..a564927 --- /dev/null +++ b/node_modules/axios/lib/core/Axios.js @@ -0,0 +1,240 @@ +'use strict'; + +import utils from './../utils.js'; +import buildURL from '../helpers/buildURL.js'; +import InterceptorManager from './InterceptorManager.js'; +import dispatchRequest from './dispatchRequest.js'; +import mergeConfig from './mergeConfig.js'; +import buildFullPath from './buildFullPath.js'; +import validator from '../helpers/validator.js'; +import AxiosHeaders from './AxiosHeaders.js'; + +const validators = validator.validators; + +/** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + * + * @return {Axios} A new instance of Axios + */ +class Axios { + constructor(instanceConfig) { + this.defaults = instanceConfig || {}; + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + }; + } + + /** + * Dispatch a request + * + * @param {String|Object} configOrUrl The config specific for this request (merged with this.defaults) + * @param {?Object} config + * + * @returns {Promise} The Promise to be fulfilled + */ + async request(configOrUrl, config) { + try { + return await this._request(configOrUrl, config); + } catch (err) { + if (err instanceof Error) { + let dummy = {}; + + Error.captureStackTrace ? Error.captureStackTrace(dummy) : (dummy = new Error()); + + // slice off the Error: ... line + const stack = dummy.stack ? dummy.stack.replace(/^.+\n/, '') : ''; + try { + if (!err.stack) { + err.stack = stack; + // match without the 2 top stack lines + } else if (stack && !String(err.stack).endsWith(stack.replace(/^.+\n.+\n/, ''))) { + err.stack += '\n' + stack + } + } catch (e) { + // ignore the case where "stack" is an un-writable property + } + } + + throw err; + } + } + + _request(configOrUrl, config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof configOrUrl === 'string') { + config = config || {}; + config.url = configOrUrl; + } else { + config = configOrUrl || {}; + } + + config = mergeConfig(this.defaults, config); + + const {transitional, paramsSerializer, headers} = config; + + if (transitional !== undefined) { + validator.assertOptions(transitional, { + silentJSONParsing: validators.transitional(validators.boolean), + forcedJSONParsing: validators.transitional(validators.boolean), + clarifyTimeoutError: validators.transitional(validators.boolean) + }, false); + } + + if (paramsSerializer != null) { + if (utils.isFunction(paramsSerializer)) { + config.paramsSerializer = { + serialize: paramsSerializer + } + } else { + validator.assertOptions(paramsSerializer, { + encode: validators.function, + serialize: validators.function + }, true); + } + } + + // Set config.allowAbsoluteUrls + if (config.allowAbsoluteUrls !== undefined) { + // do nothing + } else if (this.defaults.allowAbsoluteUrls !== undefined) { + config.allowAbsoluteUrls = this.defaults.allowAbsoluteUrls; + } else { + config.allowAbsoluteUrls = true; + } + + validator.assertOptions(config, { + baseUrl: validators.spelling('baseURL'), + withXsrfToken: validators.spelling('withXSRFToken') + }, true); + + // Set config.method + config.method = (config.method || this.defaults.method || 'get').toLowerCase(); + + // Flatten headers + let contextHeaders = headers && utils.merge( + headers.common, + headers[config.method] + ); + + headers && utils.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + (method) => { + delete headers[method]; + } + ); + + config.headers = AxiosHeaders.concat(contextHeaders, headers); + + // filter out skipped interceptors + const requestInterceptorChain = []; + let synchronousRequestInterceptors = true; + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { + return; + } + + synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous; + + requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + + const responseInterceptorChain = []; + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected); + }); + + let promise; + let i = 0; + let len; + + if (!synchronousRequestInterceptors) { + const chain = [dispatchRequest.bind(this), undefined]; + chain.unshift(...requestInterceptorChain); + chain.push(...responseInterceptorChain); + len = chain.length; + + promise = Promise.resolve(config); + + while (i < len) { + promise = promise.then(chain[i++], chain[i++]); + } + + return promise; + } + + len = requestInterceptorChain.length; + + let newConfig = config; + + while (i < len) { + const onFulfilled = requestInterceptorChain[i++]; + const onRejected = requestInterceptorChain[i++]; + try { + newConfig = onFulfilled(newConfig); + } catch (error) { + onRejected.call(this, error); + break; + } + } + + try { + promise = dispatchRequest.call(this, newConfig); + } catch (error) { + return Promise.reject(error); + } + + i = 0; + len = responseInterceptorChain.length; + + while (i < len) { + promise = promise.then(responseInterceptorChain[i++], responseInterceptorChain[i++]); + } + + return promise; + } + + getUri(config) { + config = mergeConfig(this.defaults, config); + const fullPath = buildFullPath(config.baseURL, config.url, config.allowAbsoluteUrls); + return buildURL(fullPath, config.params, config.paramsSerializer); + } +} + +// Provide aliases for supported request methods +utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, config) { + return this.request(mergeConfig(config || {}, { + method, + url, + data: (config || {}).data + })); + }; +}); + +utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + + function generateHTTPMethod(isForm) { + return function httpMethod(url, data, config) { + return this.request(mergeConfig(config || {}, { + method, + headers: isForm ? { + 'Content-Type': 'multipart/form-data' + } : {}, + url, + data + })); + }; + } + + Axios.prototype[method] = generateHTTPMethod(); + + Axios.prototype[method + 'Form'] = generateHTTPMethod(true); +}); + +export default Axios; diff --git a/node_modules/axios/lib/core/AxiosError.js b/node_modules/axios/lib/core/AxiosError.js new file mode 100644 index 0000000..3d118cb --- /dev/null +++ b/node_modules/axios/lib/core/AxiosError.js @@ -0,0 +1,110 @@ +'use strict'; + +import utils from '../utils.js'; + +/** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [config] The config. + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * + * @returns {Error} The created error. + */ +function AxiosError(message, code, config, request, response) { + Error.call(this); + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } else { + this.stack = (new Error()).stack; + } + + this.message = message; + this.name = 'AxiosError'; + code && (this.code = code); + config && (this.config = config); + request && (this.request = request); + if (response) { + this.response = response; + this.status = response.status ? response.status : null; + } +} + +utils.inherits(AxiosError, Error, { + toJSON: function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: utils.toJSONObject(this.config), + code: this.code, + status: this.status + }; + } +}); + +const prototype = AxiosError.prototype; +const descriptors = {}; + +[ + 'ERR_BAD_OPTION_VALUE', + 'ERR_BAD_OPTION', + 'ECONNABORTED', + 'ETIMEDOUT', + 'ERR_NETWORK', + 'ERR_FR_TOO_MANY_REDIRECTS', + 'ERR_DEPRECATED', + 'ERR_BAD_RESPONSE', + 'ERR_BAD_REQUEST', + 'ERR_CANCELED', + 'ERR_NOT_SUPPORT', + 'ERR_INVALID_URL' +// eslint-disable-next-line func-names +].forEach(code => { + descriptors[code] = {value: code}; +}); + +Object.defineProperties(AxiosError, descriptors); +Object.defineProperty(prototype, 'isAxiosError', {value: true}); + +// eslint-disable-next-line func-names +AxiosError.from = (error, code, config, request, response, customProps) => { + const axiosError = Object.create(prototype); + + utils.toFlatObject(error, axiosError, function filter(obj) { + return obj !== Error.prototype; + }, prop => { + return prop !== 'isAxiosError'; + }); + + const msg = error && error.message ? error.message : 'Error'; + + // Prefer explicit code; otherwise copy the low-level error's code (e.g. ECONNREFUSED) + const errCode = code == null && error ? error.code : code; + AxiosError.call(axiosError, msg, errCode, config, request, response); + + // Chain the original error on the standard field; non-enumerable to avoid JSON noise + if (error && axiosError.cause == null) { + Object.defineProperty(axiosError, 'cause', { value: error, configurable: true }); + } + + axiosError.name = (error && error.name) || 'Error'; + + customProps && Object.assign(axiosError, customProps); + + return axiosError; +}; + +export default AxiosError; diff --git a/node_modules/axios/lib/core/AxiosHeaders.js b/node_modules/axios/lib/core/AxiosHeaders.js new file mode 100644 index 0000000..6744581 --- /dev/null +++ b/node_modules/axios/lib/core/AxiosHeaders.js @@ -0,0 +1,314 @@ +'use strict'; + +import utils from '../utils.js'; +import parseHeaders from '../helpers/parseHeaders.js'; + +const $internals = Symbol('internals'); + +function normalizeHeader(header) { + return header && String(header).trim().toLowerCase(); +} + +function normalizeValue(value) { + if (value === false || value == null) { + return value; + } + + return utils.isArray(value) ? value.map(normalizeValue) : String(value); +} + +function parseTokens(str) { + const tokens = Object.create(null); + const tokensRE = /([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g; + let match; + + while ((match = tokensRE.exec(str))) { + tokens[match[1]] = match[2]; + } + + return tokens; +} + +const isValidHeaderName = (str) => /^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(str.trim()); + +function matchHeaderValue(context, value, header, filter, isHeaderNameFilter) { + if (utils.isFunction(filter)) { + return filter.call(this, value, header); + } + + if (isHeaderNameFilter) { + value = header; + } + + if (!utils.isString(value)) return; + + if (utils.isString(filter)) { + return value.indexOf(filter) !== -1; + } + + if (utils.isRegExp(filter)) { + return filter.test(value); + } +} + +function formatHeader(header) { + return header.trim() + .toLowerCase().replace(/([a-z\d])(\w*)/g, (w, char, str) => { + return char.toUpperCase() + str; + }); +} + +function buildAccessors(obj, header) { + const accessorName = utils.toCamelCase(' ' + header); + + ['get', 'set', 'has'].forEach(methodName => { + Object.defineProperty(obj, methodName + accessorName, { + value: function(arg1, arg2, arg3) { + return this[methodName].call(this, header, arg1, arg2, arg3); + }, + configurable: true + }); + }); +} + +class AxiosHeaders { + constructor(headers) { + headers && this.set(headers); + } + + set(header, valueOrRewrite, rewrite) { + const self = this; + + function setHeader(_value, _header, _rewrite) { + const lHeader = normalizeHeader(_header); + + if (!lHeader) { + throw new Error('header name must be a non-empty string'); + } + + const key = utils.findKey(self, lHeader); + + if(!key || self[key] === undefined || _rewrite === true || (_rewrite === undefined && self[key] !== false)) { + self[key || _header] = normalizeValue(_value); + } + } + + const setHeaders = (headers, _rewrite) => + utils.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite)); + + if (utils.isPlainObject(header) || header instanceof this.constructor) { + setHeaders(header, valueOrRewrite) + } else if(utils.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) { + setHeaders(parseHeaders(header), valueOrRewrite); + } else if (utils.isObject(header) && utils.isIterable(header)) { + let obj = {}, dest, key; + for (const entry of header) { + if (!utils.isArray(entry)) { + throw TypeError('Object iterator must return a key-value pair'); + } + + obj[key = entry[0]] = (dest = obj[key]) ? + (utils.isArray(dest) ? [...dest, entry[1]] : [dest, entry[1]]) : entry[1]; + } + + setHeaders(obj, valueOrRewrite) + } else { + header != null && setHeader(valueOrRewrite, header, rewrite); + } + + return this; + } + + get(header, parser) { + header = normalizeHeader(header); + + if (header) { + const key = utils.findKey(this, header); + + if (key) { + const value = this[key]; + + if (!parser) { + return value; + } + + if (parser === true) { + return parseTokens(value); + } + + if (utils.isFunction(parser)) { + return parser.call(this, value, key); + } + + if (utils.isRegExp(parser)) { + return parser.exec(value); + } + + throw new TypeError('parser must be boolean|regexp|function'); + } + } + } + + has(header, matcher) { + header = normalizeHeader(header); + + if (header) { + const key = utils.findKey(this, header); + + return !!(key && this[key] !== undefined && (!matcher || matchHeaderValue(this, this[key], key, matcher))); + } + + return false; + } + + delete(header, matcher) { + const self = this; + let deleted = false; + + function deleteHeader(_header) { + _header = normalizeHeader(_header); + + if (_header) { + const key = utils.findKey(self, _header); + + if (key && (!matcher || matchHeaderValue(self, self[key], key, matcher))) { + delete self[key]; + + deleted = true; + } + } + } + + if (utils.isArray(header)) { + header.forEach(deleteHeader); + } else { + deleteHeader(header); + } + + return deleted; + } + + clear(matcher) { + const keys = Object.keys(this); + let i = keys.length; + let deleted = false; + + while (i--) { + const key = keys[i]; + if(!matcher || matchHeaderValue(this, this[key], key, matcher, true)) { + delete this[key]; + deleted = true; + } + } + + return deleted; + } + + normalize(format) { + const self = this; + const headers = {}; + + utils.forEach(this, (value, header) => { + const key = utils.findKey(headers, header); + + if (key) { + self[key] = normalizeValue(value); + delete self[header]; + return; + } + + const normalized = format ? formatHeader(header) : String(header).trim(); + + if (normalized !== header) { + delete self[header]; + } + + self[normalized] = normalizeValue(value); + + headers[normalized] = true; + }); + + return this; + } + + concat(...targets) { + return this.constructor.concat(this, ...targets); + } + + toJSON(asStrings) { + const obj = Object.create(null); + + utils.forEach(this, (value, header) => { + value != null && value !== false && (obj[header] = asStrings && utils.isArray(value) ? value.join(', ') : value); + }); + + return obj; + } + + [Symbol.iterator]() { + return Object.entries(this.toJSON())[Symbol.iterator](); + } + + toString() { + return Object.entries(this.toJSON()).map(([header, value]) => header + ': ' + value).join('\n'); + } + + getSetCookie() { + return this.get("set-cookie") || []; + } + + get [Symbol.toStringTag]() { + return 'AxiosHeaders'; + } + + static from(thing) { + return thing instanceof this ? thing : new this(thing); + } + + static concat(first, ...targets) { + const computed = new this(first); + + targets.forEach((target) => computed.set(target)); + + return computed; + } + + static accessor(header) { + const internals = this[$internals] = (this[$internals] = { + accessors: {} + }); + + const accessors = internals.accessors; + const prototype = this.prototype; + + function defineAccessor(_header) { + const lHeader = normalizeHeader(_header); + + if (!accessors[lHeader]) { + buildAccessors(prototype, _header); + accessors[lHeader] = true; + } + } + + utils.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header); + + return this; + } +} + +AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']); + +// reserved names hotfix +utils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => { + let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set` + return { + get: () => value, + set(headerValue) { + this[mapped] = headerValue; + } + } +}); + +utils.freezeMethods(AxiosHeaders); + +export default AxiosHeaders; diff --git a/node_modules/axios/lib/core/InterceptorManager.js b/node_modules/axios/lib/core/InterceptorManager.js new file mode 100644 index 0000000..6657a9d --- /dev/null +++ b/node_modules/axios/lib/core/InterceptorManager.js @@ -0,0 +1,71 @@ +'use strict'; + +import utils from './../utils.js'; + +class InterceptorManager { + constructor() { + this.handlers = []; + } + + /** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ + use(fulfilled, rejected, options) { + this.handlers.push({ + fulfilled, + rejected, + synchronous: options ? options.synchronous : false, + runWhen: options ? options.runWhen : null + }); + return this.handlers.length - 1; + } + + /** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + * + * @returns {Boolean} `true` if the interceptor was removed, `false` otherwise + */ + eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } + } + + /** + * Clear all interceptors from the stack + * + * @returns {void} + */ + clear() { + if (this.handlers) { + this.handlers = []; + } + } + + /** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + * + * @returns {void} + */ + forEach(fn) { + utils.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); + } +} + +export default InterceptorManager; diff --git a/node_modules/axios/lib/core/README.md b/node_modules/axios/lib/core/README.md new file mode 100644 index 0000000..84559ce --- /dev/null +++ b/node_modules/axios/lib/core/README.md @@ -0,0 +1,8 @@ +# axios // core + +The modules found in `core/` should be modules that are specific to the domain logic of axios. These modules would most likely not make sense to be consumed outside of the axios module, as their logic is too specific. Some examples of core modules are: + +- Dispatching requests + - Requests sent via `adapters/` (see lib/adapters/README.md) +- Managing interceptors +- Handling config diff --git a/node_modules/axios/lib/core/buildFullPath.js b/node_modules/axios/lib/core/buildFullPath.js new file mode 100644 index 0000000..3050bd6 --- /dev/null +++ b/node_modules/axios/lib/core/buildFullPath.js @@ -0,0 +1,22 @@ +'use strict'; + +import isAbsoluteURL from '../helpers/isAbsoluteURL.js'; +import combineURLs from '../helpers/combineURLs.js'; + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * + * @returns {string} The combined full path + */ +export default function buildFullPath(baseURL, requestedURL, allowAbsoluteUrls) { + let isRelativeUrl = !isAbsoluteURL(requestedURL); + if (baseURL && (isRelativeUrl || allowAbsoluteUrls == false)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; +} diff --git a/node_modules/axios/lib/core/dispatchRequest.js b/node_modules/axios/lib/core/dispatchRequest.js new file mode 100644 index 0000000..bdd07f8 --- /dev/null +++ b/node_modules/axios/lib/core/dispatchRequest.js @@ -0,0 +1,81 @@ +'use strict'; + +import transformData from './transformData.js'; +import isCancel from '../cancel/isCancel.js'; +import defaults from '../defaults/index.js'; +import CanceledError from '../cancel/CanceledError.js'; +import AxiosHeaders from '../core/AxiosHeaders.js'; +import adapters from "../adapters/adapters.js"; + +/** + * Throws a `CanceledError` if cancellation has been requested. + * + * @param {Object} config The config that is to be used for the request + * + * @returns {void} + */ +function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } + + if (config.signal && config.signal.aborted) { + throw new CanceledError(null, config); + } +} + +/** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * + * @returns {Promise} The Promise to be fulfilled + */ +export default function dispatchRequest(config) { + throwIfCancellationRequested(config); + + config.headers = AxiosHeaders.from(config.headers); + + // Transform request data + config.data = transformData.call( + config, + config.transformRequest + ); + + if (['post', 'put', 'patch'].indexOf(config.method) !== -1) { + config.headers.setContentType('application/x-www-form-urlencoded', false); + } + + const adapter = adapters.getAdapter(config.adapter || defaults.adapter, config); + + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData.call( + config, + config.transformResponse, + response + ); + + response.headers = AxiosHeaders.from(response.headers); + + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData.call( + config, + config.transformResponse, + reason.response + ); + reason.response.headers = AxiosHeaders.from(reason.response.headers); + } + } + + return Promise.reject(reason); + }); +} diff --git a/node_modules/axios/lib/core/mergeConfig.js b/node_modules/axios/lib/core/mergeConfig.js new file mode 100644 index 0000000..4430546 --- /dev/null +++ b/node_modules/axios/lib/core/mergeConfig.js @@ -0,0 +1,106 @@ +'use strict'; + +import utils from '../utils.js'; +import AxiosHeaders from "./AxiosHeaders.js"; + +const headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing; + +/** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * + * @returns {Object} New object resulting from merging config2 to config1 + */ +export default function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + const config = {}; + + function getMergedValue(target, source, prop, caseless) { + if (utils.isPlainObject(target) && utils.isPlainObject(source)) { + return utils.merge.call({caseless}, target, source); + } else if (utils.isPlainObject(source)) { + return utils.merge({}, source); + } else if (utils.isArray(source)) { + return source.slice(); + } + return source; + } + + // eslint-disable-next-line consistent-return + function mergeDeepProperties(a, b, prop , caseless) { + if (!utils.isUndefined(b)) { + return getMergedValue(a, b, prop , caseless); + } else if (!utils.isUndefined(a)) { + return getMergedValue(undefined, a, prop , caseless); + } + } + + // eslint-disable-next-line consistent-return + function valueFromConfig2(a, b) { + if (!utils.isUndefined(b)) { + return getMergedValue(undefined, b); + } + } + + // eslint-disable-next-line consistent-return + function defaultToConfig2(a, b) { + if (!utils.isUndefined(b)) { + return getMergedValue(undefined, b); + } else if (!utils.isUndefined(a)) { + return getMergedValue(undefined, a); + } + } + + // eslint-disable-next-line consistent-return + function mergeDirectKeys(a, b, prop) { + if (prop in config2) { + return getMergedValue(a, b); + } else if (prop in config1) { + return getMergedValue(undefined, a); + } + } + + const mergeMap = { + url: valueFromConfig2, + method: valueFromConfig2, + data: valueFromConfig2, + baseURL: defaultToConfig2, + transformRequest: defaultToConfig2, + transformResponse: defaultToConfig2, + paramsSerializer: defaultToConfig2, + timeout: defaultToConfig2, + timeoutMessage: defaultToConfig2, + withCredentials: defaultToConfig2, + withXSRFToken: defaultToConfig2, + adapter: defaultToConfig2, + responseType: defaultToConfig2, + xsrfCookieName: defaultToConfig2, + xsrfHeaderName: defaultToConfig2, + onUploadProgress: defaultToConfig2, + onDownloadProgress: defaultToConfig2, + decompress: defaultToConfig2, + maxContentLength: defaultToConfig2, + maxBodyLength: defaultToConfig2, + beforeRedirect: defaultToConfig2, + transport: defaultToConfig2, + httpAgent: defaultToConfig2, + httpsAgent: defaultToConfig2, + cancelToken: defaultToConfig2, + socketPath: defaultToConfig2, + responseEncoding: defaultToConfig2, + validateStatus: mergeDirectKeys, + headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true) + }; + + utils.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) { + const merge = mergeMap[prop] || mergeDeepProperties; + const configValue = merge(config1[prop], config2[prop], prop); + (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue); + }); + + return config; +} diff --git a/node_modules/axios/lib/core/settle.js b/node_modules/axios/lib/core/settle.js new file mode 100644 index 0000000..ac905c4 --- /dev/null +++ b/node_modules/axios/lib/core/settle.js @@ -0,0 +1,27 @@ +'use strict'; + +import AxiosError from './AxiosError.js'; + +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + * + * @returns {object} The response. + */ +export default function settle(resolve, reject, response) { + const validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(new AxiosError( + 'Request failed with status code ' + response.status, + [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4], + response.config, + response.request, + response + )); + } +} diff --git a/node_modules/axios/lib/core/transformData.js b/node_modules/axios/lib/core/transformData.js new file mode 100644 index 0000000..eeb5a8a --- /dev/null +++ b/node_modules/axios/lib/core/transformData.js @@ -0,0 +1,28 @@ +'use strict'; + +import utils from './../utils.js'; +import defaults from '../defaults/index.js'; +import AxiosHeaders from '../core/AxiosHeaders.js'; + +/** + * Transform the data for a request or a response + * + * @param {Array|Function} fns A single function or Array of functions + * @param {?Object} response The response object + * + * @returns {*} The resulting transformed data + */ +export default function transformData(fns, response) { + const config = this || defaults; + const context = response || config; + const headers = AxiosHeaders.from(context.headers); + let data = context.data; + + utils.forEach(fns, function transform(fn) { + data = fn.call(config, data, headers.normalize(), response ? response.status : undefined); + }); + + headers.normalize(); + + return data; +} diff --git a/node_modules/axios/lib/defaults/index.js b/node_modules/axios/lib/defaults/index.js new file mode 100644 index 0000000..cc14a8b --- /dev/null +++ b/node_modules/axios/lib/defaults/index.js @@ -0,0 +1,161 @@ +'use strict'; + +import utils from '../utils.js'; +import AxiosError from '../core/AxiosError.js'; +import transitionalDefaults from './transitional.js'; +import toFormData from '../helpers/toFormData.js'; +import toURLEncodedForm from '../helpers/toURLEncodedForm.js'; +import platform from '../platform/index.js'; +import formDataToJSON from '../helpers/formDataToJSON.js'; + +/** + * It takes a string, tries to parse it, and if it fails, it returns the stringified version + * of the input + * + * @param {any} rawValue - The value to be stringified. + * @param {Function} parser - A function that parses a string into a JavaScript object. + * @param {Function} encoder - A function that takes a value and returns a string. + * + * @returns {string} A stringified version of the rawValue. + */ +function stringifySafely(rawValue, parser, encoder) { + if (utils.isString(rawValue)) { + try { + (parser || JSON.parse)(rawValue); + return utils.trim(rawValue); + } catch (e) { + if (e.name !== 'SyntaxError') { + throw e; + } + } + } + + return (encoder || JSON.stringify)(rawValue); +} + +const defaults = { + + transitional: transitionalDefaults, + + adapter: ['xhr', 'http', 'fetch'], + + transformRequest: [function transformRequest(data, headers) { + const contentType = headers.getContentType() || ''; + const hasJSONContentType = contentType.indexOf('application/json') > -1; + const isObjectPayload = utils.isObject(data); + + if (isObjectPayload && utils.isHTMLForm(data)) { + data = new FormData(data); + } + + const isFormData = utils.isFormData(data); + + if (isFormData) { + return hasJSONContentType ? JSON.stringify(formDataToJSON(data)) : data; + } + + if (utils.isArrayBuffer(data) || + utils.isBuffer(data) || + utils.isStream(data) || + utils.isFile(data) || + utils.isBlob(data) || + utils.isReadableStream(data) + ) { + return data; + } + if (utils.isArrayBufferView(data)) { + return data.buffer; + } + if (utils.isURLSearchParams(data)) { + headers.setContentType('application/x-www-form-urlencoded;charset=utf-8', false); + return data.toString(); + } + + let isFileList; + + if (isObjectPayload) { + if (contentType.indexOf('application/x-www-form-urlencoded') > -1) { + return toURLEncodedForm(data, this.formSerializer).toString(); + } + + if ((isFileList = utils.isFileList(data)) || contentType.indexOf('multipart/form-data') > -1) { + const _FormData = this.env && this.env.FormData; + + return toFormData( + isFileList ? {'files[]': data} : data, + _FormData && new _FormData(), + this.formSerializer + ); + } + } + + if (isObjectPayload || hasJSONContentType ) { + headers.setContentType('application/json', false); + return stringifySafely(data); + } + + return data; + }], + + transformResponse: [function transformResponse(data) { + const transitional = this.transitional || defaults.transitional; + const forcedJSONParsing = transitional && transitional.forcedJSONParsing; + const JSONRequested = this.responseType === 'json'; + + if (utils.isResponse(data) || utils.isReadableStream(data)) { + return data; + } + + if (data && utils.isString(data) && ((forcedJSONParsing && !this.responseType) || JSONRequested)) { + const silentJSONParsing = transitional && transitional.silentJSONParsing; + const strictJSONParsing = !silentJSONParsing && JSONRequested; + + try { + return JSON.parse(data, this.parseReviver); + } catch (e) { + if (strictJSONParsing) { + if (e.name === 'SyntaxError') { + throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response); + } + throw e; + } + } + } + + return data; + }], + + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + maxContentLength: -1, + maxBodyLength: -1, + + env: { + FormData: platform.classes.FormData, + Blob: platform.classes.Blob + }, + + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + }, + + headers: { + common: { + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': undefined + } + } +}; + +utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => { + defaults.headers[method] = {}; +}); + +export default defaults; diff --git a/node_modules/axios/lib/defaults/transitional.js b/node_modules/axios/lib/defaults/transitional.js new file mode 100644 index 0000000..f891331 --- /dev/null +++ b/node_modules/axios/lib/defaults/transitional.js @@ -0,0 +1,7 @@ +'use strict'; + +export default { + silentJSONParsing: true, + forcedJSONParsing: true, + clarifyTimeoutError: false +}; diff --git a/node_modules/axios/lib/env/README.md b/node_modules/axios/lib/env/README.md new file mode 100644 index 0000000..b41baff --- /dev/null +++ b/node_modules/axios/lib/env/README.md @@ -0,0 +1,3 @@ +# axios // env + +The `data.js` file is updated automatically when the package version is upgrading. Please do not edit it manually. diff --git a/node_modules/axios/lib/env/classes/FormData.js b/node_modules/axios/lib/env/classes/FormData.js new file mode 100644 index 0000000..862adb9 --- /dev/null +++ b/node_modules/axios/lib/env/classes/FormData.js @@ -0,0 +1,2 @@ +import _FormData from 'form-data'; +export default typeof FormData !== 'undefined' ? FormData : _FormData; diff --git a/node_modules/axios/lib/env/data.js b/node_modules/axios/lib/env/data.js new file mode 100644 index 0000000..89b13ce --- /dev/null +++ b/node_modules/axios/lib/env/data.js @@ -0,0 +1 @@ +export const VERSION = "1.12.2"; \ No newline at end of file diff --git a/node_modules/axios/lib/helpers/AxiosTransformStream.js b/node_modules/axios/lib/helpers/AxiosTransformStream.js new file mode 100644 index 0000000..4140071 --- /dev/null +++ b/node_modules/axios/lib/helpers/AxiosTransformStream.js @@ -0,0 +1,143 @@ +'use strict'; + +import stream from 'stream'; +import utils from '../utils.js'; + +const kInternals = Symbol('internals'); + +class AxiosTransformStream extends stream.Transform{ + constructor(options) { + options = utils.toFlatObject(options, { + maxRate: 0, + chunkSize: 64 * 1024, + minChunkSize: 100, + timeWindow: 500, + ticksRate: 2, + samplesCount: 15 + }, null, (prop, source) => { + return !utils.isUndefined(source[prop]); + }); + + super({ + readableHighWaterMark: options.chunkSize + }); + + const internals = this[kInternals] = { + timeWindow: options.timeWindow, + chunkSize: options.chunkSize, + maxRate: options.maxRate, + minChunkSize: options.minChunkSize, + bytesSeen: 0, + isCaptured: false, + notifiedBytesLoaded: 0, + ts: Date.now(), + bytes: 0, + onReadCallback: null + }; + + this.on('newListener', event => { + if (event === 'progress') { + if (!internals.isCaptured) { + internals.isCaptured = true; + } + } + }); + } + + _read(size) { + const internals = this[kInternals]; + + if (internals.onReadCallback) { + internals.onReadCallback(); + } + + return super._read(size); + } + + _transform(chunk, encoding, callback) { + const internals = this[kInternals]; + const maxRate = internals.maxRate; + + const readableHighWaterMark = this.readableHighWaterMark; + + const timeWindow = internals.timeWindow; + + const divider = 1000 / timeWindow; + const bytesThreshold = (maxRate / divider); + const minChunkSize = internals.minChunkSize !== false ? Math.max(internals.minChunkSize, bytesThreshold * 0.01) : 0; + + const pushChunk = (_chunk, _callback) => { + const bytes = Buffer.byteLength(_chunk); + internals.bytesSeen += bytes; + internals.bytes += bytes; + + internals.isCaptured && this.emit('progress', internals.bytesSeen); + + if (this.push(_chunk)) { + process.nextTick(_callback); + } else { + internals.onReadCallback = () => { + internals.onReadCallback = null; + process.nextTick(_callback); + }; + } + } + + const transformChunk = (_chunk, _callback) => { + const chunkSize = Buffer.byteLength(_chunk); + let chunkRemainder = null; + let maxChunkSize = readableHighWaterMark; + let bytesLeft; + let passed = 0; + + if (maxRate) { + const now = Date.now(); + + if (!internals.ts || (passed = (now - internals.ts)) >= timeWindow) { + internals.ts = now; + bytesLeft = bytesThreshold - internals.bytes; + internals.bytes = bytesLeft < 0 ? -bytesLeft : 0; + passed = 0; + } + + bytesLeft = bytesThreshold - internals.bytes; + } + + if (maxRate) { + if (bytesLeft <= 0) { + // next time window + return setTimeout(() => { + _callback(null, _chunk); + }, timeWindow - passed); + } + + if (bytesLeft < maxChunkSize) { + maxChunkSize = bytesLeft; + } + } + + if (maxChunkSize && chunkSize > maxChunkSize && (chunkSize - maxChunkSize) > minChunkSize) { + chunkRemainder = _chunk.subarray(maxChunkSize); + _chunk = _chunk.subarray(0, maxChunkSize); + } + + pushChunk(_chunk, chunkRemainder ? () => { + process.nextTick(_callback, null, chunkRemainder); + } : _callback); + }; + + transformChunk(chunk, function transformNextChunk(err, _chunk) { + if (err) { + return callback(err); + } + + if (_chunk) { + transformChunk(_chunk, transformNextChunk); + } else { + callback(null); + } + }); + } +} + +export default AxiosTransformStream; diff --git a/node_modules/axios/lib/helpers/AxiosURLSearchParams.js b/node_modules/axios/lib/helpers/AxiosURLSearchParams.js new file mode 100644 index 0000000..b9aa9f0 --- /dev/null +++ b/node_modules/axios/lib/helpers/AxiosURLSearchParams.js @@ -0,0 +1,58 @@ +'use strict'; + +import toFormData from './toFormData.js'; + +/** + * It encodes a string by replacing all characters that are not in the unreserved set with + * their percent-encoded equivalents + * + * @param {string} str - The string to encode. + * + * @returns {string} The encoded string. + */ +function encode(str) { + const charMap = { + '!': '%21', + "'": '%27', + '(': '%28', + ')': '%29', + '~': '%7E', + '%20': '+', + '%00': '\x00' + }; + return encodeURIComponent(str).replace(/[!'()~]|%20|%00/g, function replacer(match) { + return charMap[match]; + }); +} + +/** + * It takes a params object and converts it to a FormData object + * + * @param {Object} params - The parameters to be converted to a FormData object. + * @param {Object} options - The options object passed to the Axios constructor. + * + * @returns {void} + */ +function AxiosURLSearchParams(params, options) { + this._pairs = []; + + params && toFormData(params, this, options); +} + +const prototype = AxiosURLSearchParams.prototype; + +prototype.append = function append(name, value) { + this._pairs.push([name, value]); +}; + +prototype.toString = function toString(encoder) { + const _encode = encoder ? function(value) { + return encoder.call(this, value, encode); + } : encode; + + return this._pairs.map(function each(pair) { + return _encode(pair[0]) + '=' + _encode(pair[1]); + }, '').join('&'); +}; + +export default AxiosURLSearchParams; diff --git a/node_modules/axios/lib/helpers/HttpStatusCode.js b/node_modules/axios/lib/helpers/HttpStatusCode.js new file mode 100644 index 0000000..b3e7adc --- /dev/null +++ b/node_modules/axios/lib/helpers/HttpStatusCode.js @@ -0,0 +1,71 @@ +const HttpStatusCode = { + Continue: 100, + SwitchingProtocols: 101, + Processing: 102, + EarlyHints: 103, + Ok: 200, + Created: 201, + Accepted: 202, + NonAuthoritativeInformation: 203, + NoContent: 204, + ResetContent: 205, + PartialContent: 206, + MultiStatus: 207, + AlreadyReported: 208, + ImUsed: 226, + MultipleChoices: 300, + MovedPermanently: 301, + Found: 302, + SeeOther: 303, + NotModified: 304, + UseProxy: 305, + Unused: 306, + TemporaryRedirect: 307, + PermanentRedirect: 308, + BadRequest: 400, + Unauthorized: 401, + PaymentRequired: 402, + Forbidden: 403, + NotFound: 404, + MethodNotAllowed: 405, + NotAcceptable: 406, + ProxyAuthenticationRequired: 407, + RequestTimeout: 408, + Conflict: 409, + Gone: 410, + LengthRequired: 411, + PreconditionFailed: 412, + PayloadTooLarge: 413, + UriTooLong: 414, + UnsupportedMediaType: 415, + RangeNotSatisfiable: 416, + ExpectationFailed: 417, + ImATeapot: 418, + MisdirectedRequest: 421, + UnprocessableEntity: 422, + Locked: 423, + FailedDependency: 424, + TooEarly: 425, + UpgradeRequired: 426, + PreconditionRequired: 428, + TooManyRequests: 429, + RequestHeaderFieldsTooLarge: 431, + UnavailableForLegalReasons: 451, + InternalServerError: 500, + NotImplemented: 501, + BadGateway: 502, + ServiceUnavailable: 503, + GatewayTimeout: 504, + HttpVersionNotSupported: 505, + VariantAlsoNegotiates: 506, + InsufficientStorage: 507, + LoopDetected: 508, + NotExtended: 510, + NetworkAuthenticationRequired: 511, +}; + +Object.entries(HttpStatusCode).forEach(([key, value]) => { + HttpStatusCode[value] = key; +}); + +export default HttpStatusCode; diff --git a/node_modules/axios/lib/helpers/README.md b/node_modules/axios/lib/helpers/README.md new file mode 100644 index 0000000..4ae3419 --- /dev/null +++ b/node_modules/axios/lib/helpers/README.md @@ -0,0 +1,7 @@ +# axios // helpers + +The modules found in `helpers/` should be generic modules that are _not_ specific to the domain logic of axios. These modules could theoretically be published to npm on their own and consumed by other modules or apps. Some examples of generic modules are things like: + +- Browser polyfills +- Managing cookies +- Parsing HTTP headers diff --git a/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js b/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js new file mode 100644 index 0000000..d1791f0 --- /dev/null +++ b/node_modules/axios/lib/helpers/ZlibHeaderTransformStream.js @@ -0,0 +1,28 @@ +"use strict"; + +import stream from "stream"; + +class ZlibHeaderTransformStream extends stream.Transform { + __transform(chunk, encoding, callback) { + this.push(chunk); + callback(); + } + + _transform(chunk, encoding, callback) { + if (chunk.length !== 0) { + this._transform = this.__transform; + + // Add Default Compression headers if no zlib headers are present + if (chunk[0] !== 120) { // Hex: 78 + const header = Buffer.alloc(2); + header[0] = 120; // Hex: 78 + header[1] = 156; // Hex: 9C + this.push(header, encoding); + } + } + + this.__transform(chunk, encoding, callback); + } +} + +export default ZlibHeaderTransformStream; diff --git a/node_modules/axios/lib/helpers/bind.js b/node_modules/axios/lib/helpers/bind.js new file mode 100644 index 0000000..b3aa83b --- /dev/null +++ b/node_modules/axios/lib/helpers/bind.js @@ -0,0 +1,7 @@ +'use strict'; + +export default function bind(fn, thisArg) { + return function wrap() { + return fn.apply(thisArg, arguments); + }; +} diff --git a/node_modules/axios/lib/helpers/buildURL.js b/node_modules/axios/lib/helpers/buildURL.js new file mode 100644 index 0000000..4f9c0d1 --- /dev/null +++ b/node_modules/axios/lib/helpers/buildURL.js @@ -0,0 +1,67 @@ +'use strict'; + +import utils from '../utils.js'; +import AxiosURLSearchParams from '../helpers/AxiosURLSearchParams.js'; + +/** + * It replaces all instances of the characters `:`, `$`, `,`, `+`, `[`, and `]` with their + * URI encoded counterparts + * + * @param {string} val The value to be encoded. + * + * @returns {string} The encoded value. + */ +function encode(val) { + return encodeURIComponent(val). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'); +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @param {?(object|Function)} options + * + * @returns {string} The formatted url + */ +export default function buildURL(url, params, options) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + + const _encode = options && options.encode || encode; + + if (utils.isFunction(options)) { + options = { + serialize: options + }; + } + + const serializeFn = options && options.serialize; + + let serializedParams; + + if (serializeFn) { + serializedParams = serializeFn(params, options); + } else { + serializedParams = utils.isURLSearchParams(params) ? + params.toString() : + new AxiosURLSearchParams(params, options).toString(_encode); + } + + if (serializedParams) { + const hashmarkIndex = url.indexOf("#"); + + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + + return url; +} diff --git a/node_modules/axios/lib/helpers/callbackify.js b/node_modules/axios/lib/helpers/callbackify.js new file mode 100644 index 0000000..4603bad --- /dev/null +++ b/node_modules/axios/lib/helpers/callbackify.js @@ -0,0 +1,16 @@ +import utils from "../utils.js"; + +const callbackify = (fn, reducer) => { + return utils.isAsyncFn(fn) ? function (...args) { + const cb = args.pop(); + fn.apply(this, args).then((value) => { + try { + reducer ? cb(null, ...reducer(value)) : cb(null, value); + } catch (err) { + cb(err); + } + }, cb); + } : fn; +} + +export default callbackify; diff --git a/node_modules/axios/lib/helpers/combineURLs.js b/node_modules/axios/lib/helpers/combineURLs.js new file mode 100644 index 0000000..9f04f02 --- /dev/null +++ b/node_modules/axios/lib/helpers/combineURLs.js @@ -0,0 +1,15 @@ +'use strict'; + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * + * @returns {string} The combined URL + */ +export default function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/?\/$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; +} diff --git a/node_modules/axios/lib/helpers/composeSignals.js b/node_modules/axios/lib/helpers/composeSignals.js new file mode 100644 index 0000000..84087c8 --- /dev/null +++ b/node_modules/axios/lib/helpers/composeSignals.js @@ -0,0 +1,48 @@ +import CanceledError from "../cancel/CanceledError.js"; +import AxiosError from "../core/AxiosError.js"; +import utils from '../utils.js'; + +const composeSignals = (signals, timeout) => { + const {length} = (signals = signals ? signals.filter(Boolean) : []); + + if (timeout || length) { + let controller = new AbortController(); + + let aborted; + + const onabort = function (reason) { + if (!aborted) { + aborted = true; + unsubscribe(); + const err = reason instanceof Error ? reason : this.reason; + controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err)); + } + } + + let timer = timeout && setTimeout(() => { + timer = null; + onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT)) + }, timeout) + + const unsubscribe = () => { + if (signals) { + timer && clearTimeout(timer); + timer = null; + signals.forEach(signal => { + signal.unsubscribe ? signal.unsubscribe(onabort) : signal.removeEventListener('abort', onabort); + }); + signals = null; + } + } + + signals.forEach((signal) => signal.addEventListener('abort', onabort)); + + const {signal} = controller; + + signal.unsubscribe = () => utils.asap(unsubscribe); + + return signal; + } +} + +export default composeSignals; diff --git a/node_modules/axios/lib/helpers/cookies.js b/node_modules/axios/lib/helpers/cookies.js new file mode 100644 index 0000000..d039ac4 --- /dev/null +++ b/node_modules/axios/lib/helpers/cookies.js @@ -0,0 +1,42 @@ +import utils from './../utils.js'; +import platform from '../platform/index.js'; + +export default platform.hasStandardBrowserEnv ? + + // Standard browser envs support document.cookie + { + write(name, value, expires, path, domain, secure) { + const cookie = [name + '=' + encodeURIComponent(value)]; + + utils.isNumber(expires) && cookie.push('expires=' + new Date(expires).toGMTString()); + + utils.isString(path) && cookie.push('path=' + path); + + utils.isString(domain) && cookie.push('domain=' + domain); + + secure === true && cookie.push('secure'); + + document.cookie = cookie.join('; '); + }, + + read(name) { + const match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return (match ? decodeURIComponent(match[3]) : null); + }, + + remove(name) { + this.write(name, '', Date.now() - 86400000); + } + } + + : + + // Non-standard browser env (web workers, react-native) lack needed support. + { + write() {}, + read() { + return null; + }, + remove() {} + }; + diff --git a/node_modules/axios/lib/helpers/deprecatedMethod.js b/node_modules/axios/lib/helpers/deprecatedMethod.js new file mode 100644 index 0000000..9e8fae6 --- /dev/null +++ b/node_modules/axios/lib/helpers/deprecatedMethod.js @@ -0,0 +1,26 @@ +'use strict'; + +/*eslint no-console:0*/ + +/** + * Supply a warning to the developer that a method they are using + * has been deprecated. + * + * @param {string} method The name of the deprecated method + * @param {string} [instead] The alternate method to use if applicable + * @param {string} [docs] The documentation URL to get further details + * + * @returns {void} + */ +export default function deprecatedMethod(method, instead, docs) { + try { + console.warn( + 'DEPRECATED method `' + method + '`.' + + (instead ? ' Use `' + instead + '` instead.' : '') + + ' This method will be removed in a future release.'); + + if (docs) { + console.warn('For more information about usage see ' + docs); + } + } catch (e) { /* Ignore */ } +} diff --git a/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js b/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js new file mode 100644 index 0000000..f29a817 --- /dev/null +++ b/node_modules/axios/lib/helpers/estimateDataURLDecodedBytes.js @@ -0,0 +1,73 @@ +/** + * Estimate decoded byte length of a data:// URL *without* allocating large buffers. + * - For base64: compute exact decoded size using length and padding; + * handle %XX at the character-count level (no string allocation). + * - For non-base64: use UTF-8 byteLength of the encoded body as a safe upper bound. + * + * @param {string} url + * @returns {number} + */ +export default function estimateDataURLDecodedBytes(url) { + if (!url || typeof url !== 'string') return 0; + if (!url.startsWith('data:')) return 0; + + const comma = url.indexOf(','); + if (comma < 0) return 0; + + const meta = url.slice(5, comma); + const body = url.slice(comma + 1); + const isBase64 = /;base64/i.test(meta); + + if (isBase64) { + let effectiveLen = body.length; + const len = body.length; // cache length + + for (let i = 0; i < len; i++) { + if (body.charCodeAt(i) === 37 /* '%' */ && i + 2 < len) { + const a = body.charCodeAt(i + 1); + const b = body.charCodeAt(i + 2); + const isHex = + ((a >= 48 && a <= 57) || (a >= 65 && a <= 70) || (a >= 97 && a <= 102)) && + ((b >= 48 && b <= 57) || (b >= 65 && b <= 70) || (b >= 97 && b <= 102)); + + if (isHex) { + effectiveLen -= 2; + i += 2; + } + } + } + + let pad = 0; + let idx = len - 1; + + const tailIsPct3D = (j) => + j >= 2 && + body.charCodeAt(j - 2) === 37 && // '%' + body.charCodeAt(j - 1) === 51 && // '3' + (body.charCodeAt(j) === 68 || body.charCodeAt(j) === 100); // 'D' or 'd' + + if (idx >= 0) { + if (body.charCodeAt(idx) === 61 /* '=' */) { + pad++; + idx--; + } else if (tailIsPct3D(idx)) { + pad++; + idx -= 3; + } + } + + if (pad === 1 && idx >= 0) { + if (body.charCodeAt(idx) === 61 /* '=' */) { + pad++; + } else if (tailIsPct3D(idx)) { + pad++; + } + } + + const groups = Math.floor(effectiveLen / 4); + const bytes = groups * 3 - (pad || 0); + return bytes > 0 ? bytes : 0; + } + + return Buffer.byteLength(body, 'utf8'); +} diff --git a/node_modules/axios/lib/helpers/formDataToJSON.js b/node_modules/axios/lib/helpers/formDataToJSON.js new file mode 100644 index 0000000..906ce60 --- /dev/null +++ b/node_modules/axios/lib/helpers/formDataToJSON.js @@ -0,0 +1,95 @@ +'use strict'; + +import utils from '../utils.js'; + +/** + * It takes a string like `foo[x][y][z]` and returns an array like `['foo', 'x', 'y', 'z'] + * + * @param {string} name - The name of the property to get. + * + * @returns An array of strings. + */ +function parsePropPath(name) { + // foo[x][y][z] + // foo.x.y.z + // foo-x-y-z + // foo x y z + return utils.matchAll(/\w+|\[(\w*)]/g, name).map(match => { + return match[0] === '[]' ? '' : match[1] || match[0]; + }); +} + +/** + * Convert an array to an object. + * + * @param {Array} arr - The array to convert to an object. + * + * @returns An object with the same keys and values as the array. + */ +function arrayToObject(arr) { + const obj = {}; + const keys = Object.keys(arr); + let i; + const len = keys.length; + let key; + for (i = 0; i < len; i++) { + key = keys[i]; + obj[key] = arr[key]; + } + return obj; +} + +/** + * It takes a FormData object and returns a JavaScript object + * + * @param {string} formData The FormData object to convert to JSON. + * + * @returns {Object | null} The converted object. + */ +function formDataToJSON(formData) { + function buildPath(path, value, target, index) { + let name = path[index++]; + + if (name === '__proto__') return true; + + const isNumericKey = Number.isFinite(+name); + const isLast = index >= path.length; + name = !name && utils.isArray(target) ? target.length : name; + + if (isLast) { + if (utils.hasOwnProp(target, name)) { + target[name] = [target[name], value]; + } else { + target[name] = value; + } + + return !isNumericKey; + } + + if (!target[name] || !utils.isObject(target[name])) { + target[name] = []; + } + + const result = buildPath(path, value, target[name], index); + + if (result && utils.isArray(target[name])) { + target[name] = arrayToObject(target[name]); + } + + return !isNumericKey; + } + + if (utils.isFormData(formData) && utils.isFunction(formData.entries)) { + const obj = {}; + + utils.forEachEntry(formData, (name, value) => { + buildPath(parsePropPath(name), value, obj, 0); + }); + + return obj; + } + + return null; +} + +export default formDataToJSON; diff --git a/node_modules/axios/lib/helpers/formDataToStream.js b/node_modules/axios/lib/helpers/formDataToStream.js new file mode 100644 index 0000000..afc6174 --- /dev/null +++ b/node_modules/axios/lib/helpers/formDataToStream.js @@ -0,0 +1,112 @@ +import util from 'util'; +import {Readable} from 'stream'; +import utils from "../utils.js"; +import readBlob from "./readBlob.js"; +import platform from "../platform/index.js"; + +const BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_'; + +const textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util.TextEncoder(); + +const CRLF = '\r\n'; +const CRLF_BYTES = textEncoder.encode(CRLF); +const CRLF_BYTES_COUNT = 2; + +class FormDataPart { + constructor(name, value) { + const {escapeName} = this.constructor; + const isStringValue = utils.isString(value); + + let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${ + !isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : '' + }${CRLF}`; + + if (isStringValue) { + value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF)); + } else { + headers += `Content-Type: ${value.type || "application/octet-stream"}${CRLF}` + } + + this.headers = textEncoder.encode(headers + CRLF); + + this.contentLength = isStringValue ? value.byteLength : value.size; + + this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT; + + this.name = name; + this.value = value; + } + + async *encode(){ + yield this.headers; + + const {value} = this; + + if(utils.isTypedArray(value)) { + yield value; + } else { + yield* readBlob(value); + } + + yield CRLF_BYTES; + } + + static escapeName(name) { + return String(name).replace(/[\r\n"]/g, (match) => ({ + '\r' : '%0D', + '\n' : '%0A', + '"' : '%22', + }[match])); + } +} + +const formDataToStream = (form, headersHandler, options) => { + const { + tag = 'form-data-boundary', + size = 25, + boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET) + } = options || {}; + + if(!utils.isFormData(form)) { + throw TypeError('FormData instance required'); + } + + if (boundary.length < 1 || boundary.length > 70) { + throw Error('boundary must be 10-70 characters long') + } + + const boundaryBytes = textEncoder.encode('--' + boundary + CRLF); + const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF); + let contentLength = footerBytes.byteLength; + + const parts = Array.from(form.entries()).map(([name, value]) => { + const part = new FormDataPart(name, value); + contentLength += part.size; + return part; + }); + + contentLength += boundaryBytes.byteLength * parts.length; + + contentLength = utils.toFiniteNumber(contentLength); + + const computedHeaders = { + 'Content-Type': `multipart/form-data; boundary=${boundary}` + } + + if (Number.isFinite(contentLength)) { + computedHeaders['Content-Length'] = contentLength; + } + + headersHandler && headersHandler(computedHeaders); + + return Readable.from((async function *() { + for(const part of parts) { + yield boundaryBytes; + yield* part.encode(); + } + + yield footerBytes; + })()); +}; + +export default formDataToStream; diff --git a/node_modules/axios/lib/helpers/fromDataURI.js b/node_modules/axios/lib/helpers/fromDataURI.js new file mode 100644 index 0000000..eb71d3f --- /dev/null +++ b/node_modules/axios/lib/helpers/fromDataURI.js @@ -0,0 +1,53 @@ +'use strict'; + +import AxiosError from '../core/AxiosError.js'; +import parseProtocol from './parseProtocol.js'; +import platform from '../platform/index.js'; + +const DATA_URL_PATTERN = /^(?:([^;]+);)?(?:[^;]+;)?(base64|),([\s\S]*)$/; + +/** + * Parse data uri to a Buffer or Blob + * + * @param {String} uri + * @param {?Boolean} asBlob + * @param {?Object} options + * @param {?Function} options.Blob + * + * @returns {Buffer|Blob} + */ +export default function fromDataURI(uri, asBlob, options) { + const _Blob = options && options.Blob || platform.classes.Blob; + const protocol = parseProtocol(uri); + + if (asBlob === undefined && _Blob) { + asBlob = true; + } + + if (protocol === 'data') { + uri = protocol.length ? uri.slice(protocol.length + 1) : uri; + + const match = DATA_URL_PATTERN.exec(uri); + + if (!match) { + throw new AxiosError('Invalid URL', AxiosError.ERR_INVALID_URL); + } + + const mime = match[1]; + const isBase64 = match[2]; + const body = match[3]; + const buffer = Buffer.from(decodeURIComponent(body), isBase64 ? 'base64' : 'utf8'); + + if (asBlob) { + if (!_Blob) { + throw new AxiosError('Blob is not supported', AxiosError.ERR_NOT_SUPPORT); + } + + return new _Blob([buffer], {type: mime}); + } + + return buffer; + } + + throw new AxiosError('Unsupported protocol ' + protocol, AxiosError.ERR_NOT_SUPPORT); +} diff --git a/node_modules/axios/lib/helpers/isAbsoluteURL.js b/node_modules/axios/lib/helpers/isAbsoluteURL.js new file mode 100644 index 0000000..4747a45 --- /dev/null +++ b/node_modules/axios/lib/helpers/isAbsoluteURL.js @@ -0,0 +1,15 @@ +'use strict'; + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +export default function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url); +} diff --git a/node_modules/axios/lib/helpers/isAxiosError.js b/node_modules/axios/lib/helpers/isAxiosError.js new file mode 100644 index 0000000..da6cd63 --- /dev/null +++ b/node_modules/axios/lib/helpers/isAxiosError.js @@ -0,0 +1,14 @@ +'use strict'; + +import utils from './../utils.js'; + +/** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ +export default function isAxiosError(payload) { + return utils.isObject(payload) && (payload.isAxiosError === true); +} diff --git a/node_modules/axios/lib/helpers/isURLSameOrigin.js b/node_modules/axios/lib/helpers/isURLSameOrigin.js new file mode 100644 index 0000000..6a92aa1 --- /dev/null +++ b/node_modules/axios/lib/helpers/isURLSameOrigin.js @@ -0,0 +1,14 @@ +import platform from '../platform/index.js'; + +export default platform.hasStandardBrowserEnv ? ((origin, isMSIE) => (url) => { + url = new URL(url, platform.origin); + + return ( + origin.protocol === url.protocol && + origin.host === url.host && + (isMSIE || origin.port === url.port) + ); +})( + new URL(platform.origin), + platform.navigator && /(msie|trident)/i.test(platform.navigator.userAgent) +) : () => true; diff --git a/node_modules/axios/lib/helpers/null.js b/node_modules/axios/lib/helpers/null.js new file mode 100644 index 0000000..b9f82c4 --- /dev/null +++ b/node_modules/axios/lib/helpers/null.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line strict +export default null; diff --git a/node_modules/axios/lib/helpers/parseHeaders.js b/node_modules/axios/lib/helpers/parseHeaders.js new file mode 100644 index 0000000..50af948 --- /dev/null +++ b/node_modules/axios/lib/helpers/parseHeaders.js @@ -0,0 +1,55 @@ +'use strict'; + +import utils from './../utils.js'; + +// RawAxiosHeaders whose duplicates are ignored by node +// c.f. https://nodejs.org/api/http.html#http_message_headers +const ignoreDuplicateOf = utils.toObjectSet([ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' +]); + +/** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} rawHeaders Headers needing to be parsed + * + * @returns {Object} Headers parsed into an object + */ +export default rawHeaders => { + const parsed = {}; + let key; + let val; + let i; + + rawHeaders && rawHeaders.split('\n').forEach(function parser(line) { + i = line.indexOf(':'); + key = line.substring(0, i).trim().toLowerCase(); + val = line.substring(i + 1).trim(); + + if (!key || (parsed[key] && ignoreDuplicateOf[key])) { + return; + } + + if (key === 'set-cookie') { + if (parsed[key]) { + parsed[key].push(val); + } else { + parsed[key] = [val]; + } + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + }); + + return parsed; +}; diff --git a/node_modules/axios/lib/helpers/parseProtocol.js b/node_modules/axios/lib/helpers/parseProtocol.js new file mode 100644 index 0000000..586ec96 --- /dev/null +++ b/node_modules/axios/lib/helpers/parseProtocol.js @@ -0,0 +1,6 @@ +'use strict'; + +export default function parseProtocol(url) { + const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url); + return match && match[1] || ''; +} diff --git a/node_modules/axios/lib/helpers/progressEventReducer.js b/node_modules/axios/lib/helpers/progressEventReducer.js new file mode 100644 index 0000000..ff601cc --- /dev/null +++ b/node_modules/axios/lib/helpers/progressEventReducer.js @@ -0,0 +1,44 @@ +import speedometer from "./speedometer.js"; +import throttle from "./throttle.js"; +import utils from "../utils.js"; + +export const progressEventReducer = (listener, isDownloadStream, freq = 3) => { + let bytesNotified = 0; + const _speedometer = speedometer(50, 250); + + return throttle(e => { + const loaded = e.loaded; + const total = e.lengthComputable ? e.total : undefined; + const progressBytes = loaded - bytesNotified; + const rate = _speedometer(progressBytes); + const inRange = loaded <= total; + + bytesNotified = loaded; + + const data = { + loaded, + total, + progress: total ? (loaded / total) : undefined, + bytes: progressBytes, + rate: rate ? rate : undefined, + estimated: rate && total && inRange ? (total - loaded) / rate : undefined, + event: e, + lengthComputable: total != null, + [isDownloadStream ? 'download' : 'upload']: true + }; + + listener(data); + }, freq); +} + +export const progressEventDecorator = (total, throttled) => { + const lengthComputable = total != null; + + return [(loaded) => throttled[0]({ + lengthComputable, + total, + loaded + }), throttled[1]]; +} + +export const asyncDecorator = (fn) => (...args) => utils.asap(() => fn(...args)); diff --git a/node_modules/axios/lib/helpers/readBlob.js b/node_modules/axios/lib/helpers/readBlob.js new file mode 100644 index 0000000..6de748e --- /dev/null +++ b/node_modules/axios/lib/helpers/readBlob.js @@ -0,0 +1,15 @@ +const {asyncIterator} = Symbol; + +const readBlob = async function* (blob) { + if (blob.stream) { + yield* blob.stream() + } else if (blob.arrayBuffer) { + yield await blob.arrayBuffer() + } else if (blob[asyncIterator]) { + yield* blob[asyncIterator](); + } else { + yield blob; + } +} + +export default readBlob; diff --git a/node_modules/axios/lib/helpers/resolveConfig.js b/node_modules/axios/lib/helpers/resolveConfig.js new file mode 100644 index 0000000..26bce9d --- /dev/null +++ b/node_modules/axios/lib/helpers/resolveConfig.js @@ -0,0 +1,61 @@ +import platform from "../platform/index.js"; +import utils from "../utils.js"; +import isURLSameOrigin from "./isURLSameOrigin.js"; +import cookies from "./cookies.js"; +import buildFullPath from "../core/buildFullPath.js"; +import mergeConfig from "../core/mergeConfig.js"; +import AxiosHeaders from "../core/AxiosHeaders.js"; +import buildURL from "./buildURL.js"; + +export default (config) => { + const newConfig = mergeConfig({}, config); + + let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig; + + newConfig.headers = headers = AxiosHeaders.from(headers); + + newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url, newConfig.allowAbsoluteUrls), config.params, config.paramsSerializer); + + // HTTP basic authentication + if (auth) { + headers.set('Authorization', 'Basic ' + + btoa((auth.username || '') + ':' + (auth.password ? unescape(encodeURIComponent(auth.password)) : '')) + ); + } + + if (utils.isFormData(data)) { + if (platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv) { + headers.setContentType(undefined); // browser handles it + } else if (utils.isFunction(data.getHeaders)) { + // Node.js FormData (like form-data package) + const formHeaders = data.getHeaders(); + // Only set safe headers to avoid overwriting security headers + const allowedHeaders = ['content-type', 'content-length']; + Object.entries(formHeaders).forEach(([key, val]) => { + if (allowedHeaders.includes(key.toLowerCase())) { + headers.set(key, val); + } + }); + } + } + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + + if (platform.hasStandardBrowserEnv) { + withXSRFToken && utils.isFunction(withXSRFToken) && (withXSRFToken = withXSRFToken(newConfig)); + + if (withXSRFToken || (withXSRFToken !== false && isURLSameOrigin(newConfig.url))) { + // Add xsrf header + const xsrfValue = xsrfHeaderName && xsrfCookieName && cookies.read(xsrfCookieName); + + if (xsrfValue) { + headers.set(xsrfHeaderName, xsrfValue); + } + } + } + + return newConfig; +} + diff --git a/node_modules/axios/lib/helpers/speedometer.js b/node_modules/axios/lib/helpers/speedometer.js new file mode 100644 index 0000000..3b3c666 --- /dev/null +++ b/node_modules/axios/lib/helpers/speedometer.js @@ -0,0 +1,55 @@ +'use strict'; + +/** + * Calculate data maxRate + * @param {Number} [samplesCount= 10] + * @param {Number} [min= 1000] + * @returns {Function} + */ +function speedometer(samplesCount, min) { + samplesCount = samplesCount || 10; + const bytes = new Array(samplesCount); + const timestamps = new Array(samplesCount); + let head = 0; + let tail = 0; + let firstSampleTS; + + min = min !== undefined ? min : 1000; + + return function push(chunkLength) { + const now = Date.now(); + + const startedAt = timestamps[tail]; + + if (!firstSampleTS) { + firstSampleTS = now; + } + + bytes[head] = chunkLength; + timestamps[head] = now; + + let i = tail; + let bytesCount = 0; + + while (i !== head) { + bytesCount += bytes[i++]; + i = i % samplesCount; + } + + head = (head + 1) % samplesCount; + + if (head === tail) { + tail = (tail + 1) % samplesCount; + } + + if (now - firstSampleTS < min) { + return; + } + + const passed = startedAt && now - startedAt; + + return passed ? Math.round(bytesCount * 1000 / passed) : undefined; + }; +} + +export default speedometer; diff --git a/node_modules/axios/lib/helpers/spread.js b/node_modules/axios/lib/helpers/spread.js new file mode 100644 index 0000000..13479cb --- /dev/null +++ b/node_modules/axios/lib/helpers/spread.js @@ -0,0 +1,28 @@ +'use strict'; + +/** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * + * @returns {Function} + */ +export default function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; +} diff --git a/node_modules/axios/lib/helpers/throttle.js b/node_modules/axios/lib/helpers/throttle.js new file mode 100644 index 0000000..73e263d --- /dev/null +++ b/node_modules/axios/lib/helpers/throttle.js @@ -0,0 +1,44 @@ +/** + * Throttle decorator + * @param {Function} fn + * @param {Number} freq + * @return {Function} + */ +function throttle(fn, freq) { + let timestamp = 0; + let threshold = 1000 / freq; + let lastArgs; + let timer; + + const invoke = (args, now = Date.now()) => { + timestamp = now; + lastArgs = null; + if (timer) { + clearTimeout(timer); + timer = null; + } + fn(...args); + } + + const throttled = (...args) => { + const now = Date.now(); + const passed = now - timestamp; + if ( passed >= threshold) { + invoke(args, now); + } else { + lastArgs = args; + if (!timer) { + timer = setTimeout(() => { + timer = null; + invoke(lastArgs) + }, threshold - passed); + } + } + } + + const flush = () => lastArgs && invoke(lastArgs); + + return [throttled, flush]; +} + +export default throttle; diff --git a/node_modules/axios/lib/helpers/toFormData.js b/node_modules/axios/lib/helpers/toFormData.js new file mode 100644 index 0000000..ec47d8c --- /dev/null +++ b/node_modules/axios/lib/helpers/toFormData.js @@ -0,0 +1,223 @@ +'use strict'; + +import utils from '../utils.js'; +import AxiosError from '../core/AxiosError.js'; +// temporary hotfix to avoid circular references until AxiosURLSearchParams is refactored +import PlatformFormData from '../platform/node/classes/FormData.js'; + +/** + * Determines if the given thing is a array or js object. + * + * @param {string} thing - The object or array to be visited. + * + * @returns {boolean} + */ +function isVisitable(thing) { + return utils.isPlainObject(thing) || utils.isArray(thing); +} + +/** + * It removes the brackets from the end of a string + * + * @param {string} key - The key of the parameter. + * + * @returns {string} the key without the brackets. + */ +function removeBrackets(key) { + return utils.endsWith(key, '[]') ? key.slice(0, -2) : key; +} + +/** + * It takes a path, a key, and a boolean, and returns a string + * + * @param {string} path - The path to the current key. + * @param {string} key - The key of the current object being iterated over. + * @param {string} dots - If true, the key will be rendered with dots instead of brackets. + * + * @returns {string} The path to the current key. + */ +function renderKey(path, key, dots) { + if (!path) return key; + return path.concat(key).map(function each(token, i) { + // eslint-disable-next-line no-param-reassign + token = removeBrackets(token); + return !dots && i ? '[' + token + ']' : token; + }).join(dots ? '.' : ''); +} + +/** + * If the array is an array and none of its elements are visitable, then it's a flat array. + * + * @param {Array} arr - The array to check + * + * @returns {boolean} + */ +function isFlatArray(arr) { + return utils.isArray(arr) && !arr.some(isVisitable); +} + +const predicates = utils.toFlatObject(utils, {}, null, function filter(prop) { + return /^is[A-Z]/.test(prop); +}); + +/** + * Convert a data object to FormData + * + * @param {Object} obj + * @param {?Object} [formData] + * @param {?Object} [options] + * @param {Function} [options.visitor] + * @param {Boolean} [options.metaTokens = true] + * @param {Boolean} [options.dots = false] + * @param {?Boolean} [options.indexes = false] + * + * @returns {Object} + **/ + +/** + * It converts an object into a FormData object + * + * @param {Object} obj - The object to convert to form data. + * @param {string} formData - The FormData object to append to. + * @param {Object} options + * + * @returns + */ +function toFormData(obj, formData, options) { + if (!utils.isObject(obj)) { + throw new TypeError('target must be an object'); + } + + // eslint-disable-next-line no-param-reassign + formData = formData || new (PlatformFormData || FormData)(); + + // eslint-disable-next-line no-param-reassign + options = utils.toFlatObject(options, { + metaTokens: true, + dots: false, + indexes: false + }, false, function defined(option, source) { + // eslint-disable-next-line no-eq-null,eqeqeq + return !utils.isUndefined(source[option]); + }); + + const metaTokens = options.metaTokens; + // eslint-disable-next-line no-use-before-define + const visitor = options.visitor || defaultVisitor; + const dots = options.dots; + const indexes = options.indexes; + const _Blob = options.Blob || typeof Blob !== 'undefined' && Blob; + const useBlob = _Blob && utils.isSpecCompliantForm(formData); + + if (!utils.isFunction(visitor)) { + throw new TypeError('visitor must be a function'); + } + + function convertValue(value) { + if (value === null) return ''; + + if (utils.isDate(value)) { + return value.toISOString(); + } + + if (utils.isBoolean(value)) { + return value.toString(); + } + + if (!useBlob && utils.isBlob(value)) { + throw new AxiosError('Blob is not supported. Use a Buffer instead.'); + } + + if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) { + return useBlob && typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value); + } + + return value; + } + + /** + * Default visitor. + * + * @param {*} value + * @param {String|Number} key + * @param {Array} path + * @this {FormData} + * + * @returns {boolean} return true to visit the each prop of the value recursively + */ + function defaultVisitor(value, key, path) { + let arr = value; + + if (value && !path && typeof value === 'object') { + if (utils.endsWith(key, '{}')) { + // eslint-disable-next-line no-param-reassign + key = metaTokens ? key : key.slice(0, -2); + // eslint-disable-next-line no-param-reassign + value = JSON.stringify(value); + } else if ( + (utils.isArray(value) && isFlatArray(value)) || + ((utils.isFileList(value) || utils.endsWith(key, '[]')) && (arr = utils.toArray(value)) + )) { + // eslint-disable-next-line no-param-reassign + key = removeBrackets(key); + + arr.forEach(function each(el, index) { + !(utils.isUndefined(el) || el === null) && formData.append( + // eslint-disable-next-line no-nested-ternary + indexes === true ? renderKey([key], index, dots) : (indexes === null ? key : key + '[]'), + convertValue(el) + ); + }); + return false; + } + } + + if (isVisitable(value)) { + return true; + } + + formData.append(renderKey(path, key, dots), convertValue(value)); + + return false; + } + + const stack = []; + + const exposedHelpers = Object.assign(predicates, { + defaultVisitor, + convertValue, + isVisitable + }); + + function build(value, path) { + if (utils.isUndefined(value)) return; + + if (stack.indexOf(value) !== -1) { + throw Error('Circular reference detected in ' + path.join('.')); + } + + stack.push(value); + + utils.forEach(value, function each(el, key) { + const result = !(utils.isUndefined(el) || el === null) && visitor.call( + formData, el, utils.isString(key) ? key.trim() : key, path, exposedHelpers + ); + + if (result === true) { + build(el, path ? path.concat(key) : [key]); + } + }); + + stack.pop(); + } + + if (!utils.isObject(obj)) { + throw new TypeError('data must be an object'); + } + + build(obj); + + return formData; +} + +export default toFormData; diff --git a/node_modules/axios/lib/helpers/toURLEncodedForm.js b/node_modules/axios/lib/helpers/toURLEncodedForm.js new file mode 100644 index 0000000..ffa95ec --- /dev/null +++ b/node_modules/axios/lib/helpers/toURLEncodedForm.js @@ -0,0 +1,19 @@ +'use strict'; + +import utils from '../utils.js'; +import toFormData from './toFormData.js'; +import platform from '../platform/index.js'; + +export default function toURLEncodedForm(data, options) { + return toFormData(data, new platform.classes.URLSearchParams(), { + visitor: function(value, key, path, helpers) { + if (platform.isNode && utils.isBuffer(value)) { + this.append(key, value.toString('base64')); + return false; + } + + return helpers.defaultVisitor.apply(this, arguments); + }, + ...options + }); +} diff --git a/node_modules/axios/lib/helpers/trackStream.js b/node_modules/axios/lib/helpers/trackStream.js new file mode 100644 index 0000000..95d6008 --- /dev/null +++ b/node_modules/axios/lib/helpers/trackStream.js @@ -0,0 +1,87 @@ + +export const streamChunk = function* (chunk, chunkSize) { + let len = chunk.byteLength; + + if (!chunkSize || len < chunkSize) { + yield chunk; + return; + } + + let pos = 0; + let end; + + while (pos < len) { + end = pos + chunkSize; + yield chunk.slice(pos, end); + pos = end; + } +} + +export const readBytes = async function* (iterable, chunkSize) { + for await (const chunk of readStream(iterable)) { + yield* streamChunk(chunk, chunkSize); + } +} + +const readStream = async function* (stream) { + if (stream[Symbol.asyncIterator]) { + yield* stream; + return; + } + + const reader = stream.getReader(); + try { + for (;;) { + const {done, value} = await reader.read(); + if (done) { + break; + } + yield value; + } + } finally { + await reader.cancel(); + } +} + +export const trackStream = (stream, chunkSize, onProgress, onFinish) => { + const iterator = readBytes(stream, chunkSize); + + let bytes = 0; + let done; + let _onFinish = (e) => { + if (!done) { + done = true; + onFinish && onFinish(e); + } + } + + return new ReadableStream({ + async pull(controller) { + try { + const {done, value} = await iterator.next(); + + if (done) { + _onFinish(); + controller.close(); + return; + } + + let len = value.byteLength; + if (onProgress) { + let loadedBytes = bytes += len; + onProgress(loadedBytes); + } + controller.enqueue(new Uint8Array(value)); + } catch (err) { + _onFinish(err); + throw err; + } + }, + cancel(reason) { + _onFinish(reason); + return iterator.return(); + } + }, { + highWaterMark: 2 + }) +} diff --git a/node_modules/axios/lib/helpers/validator.js b/node_modules/axios/lib/helpers/validator.js new file mode 100644 index 0000000..1270568 --- /dev/null +++ b/node_modules/axios/lib/helpers/validator.js @@ -0,0 +1,99 @@ +'use strict'; + +import {VERSION} from '../env/data.js'; +import AxiosError from '../core/AxiosError.js'; + +const validators = {}; + +// eslint-disable-next-line func-names +['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach((type, i) => { + validators[type] = function validator(thing) { + return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type; + }; +}); + +const deprecatedWarnings = {}; + +/** + * Transitional option validator + * + * @param {function|boolean?} validator - set to false if the transitional option has been removed + * @param {string?} version - deprecated version / removed since version + * @param {string?} message - some message with additional info + * + * @returns {function} + */ +validators.transitional = function transitional(validator, version, message) { + function formatMessage(opt, desc) { + return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + (message ? '. ' + message : ''); + } + + // eslint-disable-next-line func-names + return (value, opt, opts) => { + if (validator === false) { + throw new AxiosError( + formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')), + AxiosError.ERR_DEPRECATED + ); + } + + if (version && !deprecatedWarnings[opt]) { + deprecatedWarnings[opt] = true; + // eslint-disable-next-line no-console + console.warn( + formatMessage( + opt, + ' has been deprecated since v' + version + ' and will be removed in the near future' + ) + ); + } + + return validator ? validator(value, opt, opts) : true; + }; +}; + +validators.spelling = function spelling(correctSpelling) { + return (value, opt) => { + // eslint-disable-next-line no-console + console.warn(`${opt} is likely a misspelling of ${correctSpelling}`); + return true; + } +}; + +/** + * Assert object's properties type + * + * @param {object} options + * @param {object} schema + * @param {boolean?} allowUnknown + * + * @returns {object} + */ + +function assertOptions(options, schema, allowUnknown) { + if (typeof options !== 'object') { + throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE); + } + const keys = Object.keys(options); + let i = keys.length; + while (i-- > 0) { + const opt = keys[i]; + const validator = schema[opt]; + if (validator) { + const value = options[opt]; + const result = value === undefined || validator(value, opt, options); + if (result !== true) { + throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE); + } + continue; + } + if (allowUnknown !== true) { + throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION); + } + } +} + +export default { + assertOptions, + validators +}; diff --git a/node_modules/axios/lib/platform/browser/classes/Blob.js b/node_modules/axios/lib/platform/browser/classes/Blob.js new file mode 100644 index 0000000..6c506c4 --- /dev/null +++ b/node_modules/axios/lib/platform/browser/classes/Blob.js @@ -0,0 +1,3 @@ +'use strict' + +export default typeof Blob !== 'undefined' ? Blob : null diff --git a/node_modules/axios/lib/platform/browser/classes/FormData.js b/node_modules/axios/lib/platform/browser/classes/FormData.js new file mode 100644 index 0000000..f36d31b --- /dev/null +++ b/node_modules/axios/lib/platform/browser/classes/FormData.js @@ -0,0 +1,3 @@ +'use strict'; + +export default typeof FormData !== 'undefined' ? FormData : null; diff --git a/node_modules/axios/lib/platform/browser/classes/URLSearchParams.js b/node_modules/axios/lib/platform/browser/classes/URLSearchParams.js new file mode 100644 index 0000000..b7dae95 --- /dev/null +++ b/node_modules/axios/lib/platform/browser/classes/URLSearchParams.js @@ -0,0 +1,4 @@ +'use strict'; + +import AxiosURLSearchParams from '../../../helpers/AxiosURLSearchParams.js'; +export default typeof URLSearchParams !== 'undefined' ? URLSearchParams : AxiosURLSearchParams; diff --git a/node_modules/axios/lib/platform/browser/index.js b/node_modules/axios/lib/platform/browser/index.js new file mode 100644 index 0000000..08c206f --- /dev/null +++ b/node_modules/axios/lib/platform/browser/index.js @@ -0,0 +1,13 @@ +import URLSearchParams from './classes/URLSearchParams.js' +import FormData from './classes/FormData.js' +import Blob from './classes/Blob.js' + +export default { + isBrowser: true, + classes: { + URLSearchParams, + FormData, + Blob + }, + protocols: ['http', 'https', 'file', 'blob', 'url', 'data'] +}; diff --git a/node_modules/axios/lib/platform/common/utils.js b/node_modules/axios/lib/platform/common/utils.js new file mode 100644 index 0000000..52a3186 --- /dev/null +++ b/node_modules/axios/lib/platform/common/utils.js @@ -0,0 +1,51 @@ +const hasBrowserEnv = typeof window !== 'undefined' && typeof document !== 'undefined'; + +const _navigator = typeof navigator === 'object' && navigator || undefined; + +/** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + * + * @returns {boolean} + */ +const hasStandardBrowserEnv = hasBrowserEnv && + (!_navigator || ['ReactNative', 'NativeScript', 'NS'].indexOf(_navigator.product) < 0); + +/** + * Determine if we're running in a standard browser webWorker environment + * + * Although the `isStandardBrowserEnv` method indicates that + * `allows axios to run in a web worker`, the WebWorker will still be + * filtered out due to its judgment standard + * `typeof window !== 'undefined' && typeof document !== 'undefined'`. + * This leads to a problem when axios post `FormData` in webWorker + */ +const hasStandardBrowserWebWorkerEnv = (() => { + return ( + typeof WorkerGlobalScope !== 'undefined' && + // eslint-disable-next-line no-undef + self instanceof WorkerGlobalScope && + typeof self.importScripts === 'function' + ); +})(); + +const origin = hasBrowserEnv && window.location.href || 'http://localhost'; + +export { + hasBrowserEnv, + hasStandardBrowserWebWorkerEnv, + hasStandardBrowserEnv, + _navigator as navigator, + origin +} diff --git a/node_modules/axios/lib/platform/index.js b/node_modules/axios/lib/platform/index.js new file mode 100644 index 0000000..860ba21 --- /dev/null +++ b/node_modules/axios/lib/platform/index.js @@ -0,0 +1,7 @@ +import platform from './node/index.js'; +import * as utils from './common/utils.js'; + +export default { + ...utils, + ...platform +} diff --git a/node_modules/axios/lib/platform/node/classes/FormData.js b/node_modules/axios/lib/platform/node/classes/FormData.js new file mode 100644 index 0000000..b07f947 --- /dev/null +++ b/node_modules/axios/lib/platform/node/classes/FormData.js @@ -0,0 +1,3 @@ +import FormData from 'form-data'; + +export default FormData; diff --git a/node_modules/axios/lib/platform/node/classes/URLSearchParams.js b/node_modules/axios/lib/platform/node/classes/URLSearchParams.js new file mode 100644 index 0000000..fba5842 --- /dev/null +++ b/node_modules/axios/lib/platform/node/classes/URLSearchParams.js @@ -0,0 +1,4 @@ +'use strict'; + +import url from 'url'; +export default url.URLSearchParams; diff --git a/node_modules/axios/lib/platform/node/index.js b/node_modules/axios/lib/platform/node/index.js new file mode 100644 index 0000000..cd1ca0c --- /dev/null +++ b/node_modules/axios/lib/platform/node/index.js @@ -0,0 +1,38 @@ +import crypto from 'crypto'; +import URLSearchParams from './classes/URLSearchParams.js' +import FormData from './classes/FormData.js' + +const ALPHA = 'abcdefghijklmnopqrstuvwxyz' + +const DIGIT = '0123456789'; + +const ALPHABET = { + DIGIT, + ALPHA, + ALPHA_DIGIT: ALPHA + ALPHA.toUpperCase() + DIGIT +} + +const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => { + let str = ''; + const {length} = alphabet; + const randomValues = new Uint32Array(size); + crypto.randomFillSync(randomValues); + for (let i = 0; i < size; i++) { + str += alphabet[randomValues[i] % length]; + } + + return str; +} + + +export default { + isNode: true, + classes: { + URLSearchParams, + FormData, + Blob: typeof Blob !== 'undefined' && Blob || null + }, + ALPHABET, + generateString, + protocols: [ 'http', 'https', 'file', 'data' ] +}; diff --git a/node_modules/axios/lib/utils.js b/node_modules/axios/lib/utils.js new file mode 100644 index 0000000..ade8309 --- /dev/null +++ b/node_modules/axios/lib/utils.js @@ -0,0 +1,782 @@ +'use strict'; + +import bind from './helpers/bind.js'; + +// utils is a library of generic helper functions non-specific to axios + +const {toString} = Object.prototype; +const {getPrototypeOf} = Object; +const {iterator, toStringTag} = Symbol; + +const kindOf = (cache => thing => { + const str = toString.call(thing); + return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase()); +})(Object.create(null)); + +const kindOfTest = (type) => { + type = type.toLowerCase(); + return (thing) => kindOf(thing) === type +} + +const typeOfTest = type => thing => typeof thing === type; + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * + * @returns {boolean} True if value is an Array, otherwise false + */ +const {isArray} = Array; + +/** + * Determine if a value is undefined + * + * @param {*} val The value to test + * + * @returns {boolean} True if the value is undefined, otherwise false + */ +const isUndefined = typeOfTest('undefined'); + +/** + * Determine if a value is a Buffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Buffer, otherwise false + */ +function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && isFunction(val.constructor.isBuffer) && val.constructor.isBuffer(val); +} + +/** + * Determine if a value is an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ +const isArrayBuffer = kindOfTest('ArrayBuffer'); + + +/** + * Determine if a value is a view on an ArrayBuffer + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ +function isArrayBufferView(val) { + let result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (isArrayBuffer(val.buffer)); + } + return result; +} + +/** + * Determine if a value is a String + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a String, otherwise false + */ +const isString = typeOfTest('string'); + +/** + * Determine if a value is a Function + * + * @param {*} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ +const isFunction = typeOfTest('function'); + +/** + * Determine if a value is a Number + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Number, otherwise false + */ +const isNumber = typeOfTest('number'); + +/** + * Determine if a value is an Object + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an Object, otherwise false + */ +const isObject = (thing) => thing !== null && typeof thing === 'object'; + +/** + * Determine if a value is a Boolean + * + * @param {*} thing The value to test + * @returns {boolean} True if value is a Boolean, otherwise false + */ +const isBoolean = thing => thing === true || thing === false; + +/** + * Determine if a value is a plain Object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a plain Object, otherwise false + */ +const isPlainObject = (val) => { + if (kindOf(val) !== 'object') { + return false; + } + + const prototype = getPrototypeOf(val); + return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag in val) && !(iterator in val); +} + +/** + * Determine if a value is an empty object (safely handles Buffers) + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is an empty object, otherwise false + */ +const isEmptyObject = (val) => { + // Early return for non-objects or Buffers to prevent RangeError + if (!isObject(val) || isBuffer(val)) { + return false; + } + + try { + return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype; + } catch (e) { + // Fallback for any other objects that might cause RangeError with Object.keys() + return false; + } +} + +/** + * Determine if a value is a Date + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Date, otherwise false + */ +const isDate = kindOfTest('Date'); + +/** + * Determine if a value is a File + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFile = kindOfTest('File'); + +/** + * Determine if a value is a Blob + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Blob, otherwise false + */ +const isBlob = kindOfTest('Blob'); + +/** + * Determine if a value is a FileList + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a File, otherwise false + */ +const isFileList = kindOfTest('FileList'); + +/** + * Determine if a value is a Stream + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a Stream, otherwise false + */ +const isStream = (val) => isObject(val) && isFunction(val.pipe); + +/** + * Determine if a value is a FormData + * + * @param {*} thing The value to test + * + * @returns {boolean} True if value is an FormData, otherwise false + */ +const isFormData = (thing) => { + let kind; + return thing && ( + (typeof FormData === 'function' && thing instanceof FormData) || ( + isFunction(thing.append) && ( + (kind = kindOf(thing)) === 'formdata' || + // detect form-data instance + (kind === 'object' && isFunction(thing.toString) && thing.toString() === '[object FormData]') + ) + ) + ) +} + +/** + * Determine if a value is a URLSearchParams object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +const isURLSearchParams = kindOfTest('URLSearchParams'); + +const [isReadableStream, isRequest, isResponse, isHeaders] = ['ReadableStream', 'Request', 'Response', 'Headers'].map(kindOfTest); + +/** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * + * @returns {String} The String freed of excess whitespace + */ +const trim = (str) => str.trim ? + str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + * + * @param {Boolean} [allOwnKeys = false] + * @returns {any} + */ +function forEach(obj, fn, {allOwnKeys = false} = {}) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + + let i; + let l; + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + + if (isArray(obj)) { + // Iterate over array values + for (i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Buffer check + if (isBuffer(obj)) { + return; + } + + // Iterate over object keys + const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj); + const len = keys.length; + let key; + + for (i = 0; i < len; i++) { + key = keys[i]; + fn.call(null, obj[key], key, obj); + } + } +} + +function findKey(obj, key) { + if (isBuffer(obj)){ + return null; + } + + key = key.toLowerCase(); + const keys = Object.keys(obj); + let i = keys.length; + let _key; + while (i-- > 0) { + _key = keys[i]; + if (key === _key.toLowerCase()) { + return _key; + } + } + return null; +} + +const _global = (() => { + /*eslint no-undef:0*/ + if (typeof globalThis !== "undefined") return globalThis; + return typeof self !== "undefined" ? self : (typeof window !== 'undefined' ? window : global) +})(); + +const isContextDefined = (context) => !isUndefined(context) && context !== _global; + +/** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * + * @returns {Object} Result of all merge properties + */ +function merge(/* obj1, obj2, obj3, ... */) { + const {caseless, skipUndefined} = isContextDefined(this) && this || {}; + const result = {}; + const assignValue = (val, key) => { + const targetKey = caseless && findKey(result, key) || key; + if (isPlainObject(result[targetKey]) && isPlainObject(val)) { + result[targetKey] = merge(result[targetKey], val); + } else if (isPlainObject(val)) { + result[targetKey] = merge({}, val); + } else if (isArray(val)) { + result[targetKey] = val.slice(); + } else if (!skipUndefined || !isUndefined(val)) { + result[targetKey] = val; + } + } + + for (let i = 0, l = arguments.length; i < l; i++) { + arguments[i] && forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * + * @param {Boolean} [allOwnKeys] + * @returns {Object} The resulting value of object a + */ +const extend = (a, b, thisArg, {allOwnKeys}= {}) => { + forEach(b, (val, key) => { + if (thisArg && isFunction(val)) { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }, {allOwnKeys}); + return a; +} + +/** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * + * @returns {string} content value without BOM + */ +const stripBOM = (content) => { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; +} + +/** + * Inherit the prototype methods from one constructor into another + * @param {function} constructor + * @param {function} superConstructor + * @param {object} [props] + * @param {object} [descriptors] + * + * @returns {void} + */ +const inherits = (constructor, superConstructor, props, descriptors) => { + constructor.prototype = Object.create(superConstructor.prototype, descriptors); + constructor.prototype.constructor = constructor; + Object.defineProperty(constructor, 'super', { + value: superConstructor.prototype + }); + props && Object.assign(constructor.prototype, props); +} + +/** + * Resolve object with deep prototype chain to a flat object + * @param {Object} sourceObj source object + * @param {Object} [destObj] + * @param {Function|Boolean} [filter] + * @param {Function} [propFilter] + * + * @returns {Object} + */ +const toFlatObject = (sourceObj, destObj, filter, propFilter) => { + let props; + let i; + let prop; + const merged = {}; + + destObj = destObj || {}; + // eslint-disable-next-line no-eq-null,eqeqeq + if (sourceObj == null) return destObj; + + do { + props = Object.getOwnPropertyNames(sourceObj); + i = props.length; + while (i-- > 0) { + prop = props[i]; + if ((!propFilter || propFilter(prop, sourceObj, destObj)) && !merged[prop]) { + destObj[prop] = sourceObj[prop]; + merged[prop] = true; + } + } + sourceObj = filter !== false && getPrototypeOf(sourceObj); + } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype); + + return destObj; +} + +/** + * Determines whether a string ends with the characters of a specified string + * + * @param {String} str + * @param {String} searchString + * @param {Number} [position= 0] + * + * @returns {boolean} + */ +const endsWith = (str, searchString, position) => { + str = String(str); + if (position === undefined || position > str.length) { + position = str.length; + } + position -= searchString.length; + const lastIndex = str.indexOf(searchString, position); + return lastIndex !== -1 && lastIndex === position; +} + + +/** + * Returns new array from array like object or null if failed + * + * @param {*} [thing] + * + * @returns {?Array} + */ +const toArray = (thing) => { + if (!thing) return null; + if (isArray(thing)) return thing; + let i = thing.length; + if (!isNumber(i)) return null; + const arr = new Array(i); + while (i-- > 0) { + arr[i] = thing[i]; + } + return arr; +} + +/** + * Checking if the Uint8Array exists and if it does, it returns a function that checks if the + * thing passed in is an instance of Uint8Array + * + * @param {TypedArray} + * + * @returns {Array} + */ +// eslint-disable-next-line func-names +const isTypedArray = (TypedArray => { + // eslint-disable-next-line func-names + return thing => { + return TypedArray && thing instanceof TypedArray; + }; +})(typeof Uint8Array !== 'undefined' && getPrototypeOf(Uint8Array)); + +/** + * For each entry in the object, call the function with the key and value. + * + * @param {Object} obj - The object to iterate over. + * @param {Function} fn - The function to call for each entry. + * + * @returns {void} + */ +const forEachEntry = (obj, fn) => { + const generator = obj && obj[iterator]; + + const _iterator = generator.call(obj); + + let result; + + while ((result = _iterator.next()) && !result.done) { + const pair = result.value; + fn.call(obj, pair[0], pair[1]); + } +} + +/** + * It takes a regular expression and a string, and returns an array of all the matches + * + * @param {string} regExp - The regular expression to match against. + * @param {string} str - The string to search. + * + * @returns {Array} + */ +const matchAll = (regExp, str) => { + let matches; + const arr = []; + + while ((matches = regExp.exec(str)) !== null) { + arr.push(matches); + } + + return arr; +} + +/* Checking if the kindOfTest function returns true when passed an HTMLFormElement. */ +const isHTMLForm = kindOfTest('HTMLFormElement'); + +const toCamelCase = str => { + return str.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g, + function replacer(m, p1, p2) { + return p1.toUpperCase() + p2; + } + ); +}; + +/* Creating a function that will check if an object has a property. */ +const hasOwnProperty = (({hasOwnProperty}) => (obj, prop) => hasOwnProperty.call(obj, prop))(Object.prototype); + +/** + * Determine if a value is a RegExp object + * + * @param {*} val The value to test + * + * @returns {boolean} True if value is a RegExp object, otherwise false + */ +const isRegExp = kindOfTest('RegExp'); + +const reduceDescriptors = (obj, reducer) => { + const descriptors = Object.getOwnPropertyDescriptors(obj); + const reducedDescriptors = {}; + + forEach(descriptors, (descriptor, name) => { + let ret; + if ((ret = reducer(descriptor, name, obj)) !== false) { + reducedDescriptors[name] = ret || descriptor; + } + }); + + Object.defineProperties(obj, reducedDescriptors); +} + +/** + * Makes all methods read-only + * @param {Object} obj + */ + +const freezeMethods = (obj) => { + reduceDescriptors(obj, (descriptor, name) => { + // skip restricted props in strict mode + if (isFunction(obj) && ['arguments', 'caller', 'callee'].indexOf(name) !== -1) { + return false; + } + + const value = obj[name]; + + if (!isFunction(value)) return; + + descriptor.enumerable = false; + + if ('writable' in descriptor) { + descriptor.writable = false; + return; + } + + if (!descriptor.set) { + descriptor.set = () => { + throw Error('Can not rewrite read-only method \'' + name + '\''); + }; + } + }); +} + +const toObjectSet = (arrayOrString, delimiter) => { + const obj = {}; + + const define = (arr) => { + arr.forEach(value => { + obj[value] = true; + }); + } + + isArray(arrayOrString) ? define(arrayOrString) : define(String(arrayOrString).split(delimiter)); + + return obj; +} + +const noop = () => {} + +const toFiniteNumber = (value, defaultValue) => { + return value != null && Number.isFinite(value = +value) ? value : defaultValue; +} + + + +/** + * If the thing is a FormData object, return true, otherwise return false. + * + * @param {unknown} thing - The thing to check. + * + * @returns {boolean} + */ +function isSpecCompliantForm(thing) { + return !!(thing && isFunction(thing.append) && thing[toStringTag] === 'FormData' && thing[iterator]); +} + +const toJSONObject = (obj) => { + const stack = new Array(10); + + const visit = (source, i) => { + + if (isObject(source)) { + if (stack.indexOf(source) >= 0) { + return; + } + + //Buffer check + if (isBuffer(source)) { + return source; + } + + if(!('toJSON' in source)) { + stack[i] = source; + const target = isArray(source) ? [] : {}; + + forEach(source, (value, key) => { + const reducedValue = visit(value, i + 1); + !isUndefined(reducedValue) && (target[key] = reducedValue); + }); + + stack[i] = undefined; + + return target; + } + } + + return source; + } + + return visit(obj, 0); +} + +const isAsyncFn = kindOfTest('AsyncFunction'); + +const isThenable = (thing) => + thing && (isObject(thing) || isFunction(thing)) && isFunction(thing.then) && isFunction(thing.catch); + +// original code +// https://github.com/DigitalBrainJS/AxiosPromise/blob/16deab13710ec09779922131f3fa5954320f83ab/lib/utils.js#L11-L34 + +const _setImmediate = ((setImmediateSupported, postMessageSupported) => { + if (setImmediateSupported) { + return setImmediate; + } + + return postMessageSupported ? ((token, callbacks) => { + _global.addEventListener("message", ({source, data}) => { + if (source === _global && data === token) { + callbacks.length && callbacks.shift()(); + } + }, false); + + return (cb) => { + callbacks.push(cb); + _global.postMessage(token, "*"); + } + })(`axios@${Math.random()}`, []) : (cb) => setTimeout(cb); +})( + typeof setImmediate === 'function', + isFunction(_global.postMessage) +); + +const asap = typeof queueMicrotask !== 'undefined' ? + queueMicrotask.bind(_global) : ( typeof process !== 'undefined' && process.nextTick || _setImmediate); + +// ********************* + + +const isIterable = (thing) => thing != null && isFunction(thing[iterator]); + + +export default { + isArray, + isArrayBuffer, + isBuffer, + isFormData, + isArrayBufferView, + isString, + isNumber, + isBoolean, + isObject, + isPlainObject, + isEmptyObject, + isReadableStream, + isRequest, + isResponse, + isHeaders, + isUndefined, + isDate, + isFile, + isBlob, + isRegExp, + isFunction, + isStream, + isURLSearchParams, + isTypedArray, + isFileList, + forEach, + merge, + extend, + trim, + stripBOM, + inherits, + toFlatObject, + kindOf, + kindOfTest, + endsWith, + toArray, + forEachEntry, + matchAll, + isHTMLForm, + hasOwnProperty, + hasOwnProp: hasOwnProperty, // an alias to avoid ESLint no-prototype-builtins detection + reduceDescriptors, + freezeMethods, + toObjectSet, + toCamelCase, + noop, + toFiniteNumber, + findKey, + global: _global, + isContextDefined, + isSpecCompliantForm, + toJSONObject, + isAsyncFn, + isThenable, + setImmediate: _setImmediate, + asap, + isIterable +}; diff --git a/node_modules/axios/package.json b/node_modules/axios/package.json new file mode 100644 index 0000000..abc314e --- /dev/null +++ b/node_modules/axios/package.json @@ -0,0 +1,234 @@ +{ + "name": "axios", + "version": "1.12.2", + "description": "Promise based HTTP client for the browser and node.js", + "main": "index.js", + "exports": { + ".": { + "types": { + "require": "./index.d.cts", + "default": "./index.d.ts" + }, + "react-native": { + "require": "./dist/browser/axios.cjs", + "default": "./dist/esm/axios.js" + }, + "browser": { + "require": "./dist/browser/axios.cjs", + "default": "./index.js" + }, + "default": { + "require": "./dist/node/axios.cjs", + "default": "./index.js" + } + }, + "./lib/adapters/http.js": "./lib/adapters/http.js", + "./lib/adapters/xhr.js": "./lib/adapters/xhr.js", + "./unsafe/*": "./lib/*", + "./unsafe/core/settle.js": "./lib/core/settle.js", + "./unsafe/core/buildFullPath.js": "./lib/core/buildFullPath.js", + "./unsafe/helpers/isAbsoluteURL.js": "./lib/helpers/isAbsoluteURL.js", + "./unsafe/helpers/buildURL.js": "./lib/helpers/buildURL.js", + "./unsafe/helpers/combineURLs.js": "./lib/helpers/combineURLs.js", + "./unsafe/adapters/http.js": "./lib/adapters/http.js", + "./unsafe/adapters/xhr.js": "./lib/adapters/xhr.js", + "./unsafe/utils.js": "./lib/utils.js", + "./package.json": "./package.json", + "./dist/browser/axios.cjs": "./dist/browser/axios.cjs", + "./dist/node/axios.cjs": "./dist/node/axios.cjs" + }, + "type": "module", + "types": "index.d.ts", + "scripts": { + "test": "npm run test:node && npm run test:browser && npm run test:package", + "test:node": "npm run test:mocha", + "test:browser": "npm run test:karma", + "test:package": "npm run test:eslint && npm run test:dtslint && npm run test:exports", + "test:eslint": "node bin/ssl_hotfix.js eslint lib/**/*.js", + "test:dtslint": "dtslint --localTs node_modules/typescript/lib", + "test:mocha": "node bin/ssl_hotfix.js mocha test/unit/**/*.js --timeout 30000 --exit", + "test:exports": "node bin/ssl_hotfix.js mocha test/module/test.js --timeout 30000 --exit", + "test:karma": "node ./bin/run-karma-tests.js", + "test:karma:firefox": "node bin/ssl_hotfix.js cross-env LISTEN_ADDR=:: Browsers=Firefox karma start karma.conf.cjs --single-run", + "test:karma:server": "node bin/ssl_hotfix.js cross-env karma start karma.conf.cjs", + "test:build:version": "node ./bin/check-build-version.js", + "start": "node ./sandbox/server.js", + "preversion": "gulp version", + "version": "npm run build && git add package.json", + "prepublishOnly": "npm run test:build:version", + "postpublish": "git push && git push --tags", + "build": "gulp clear && cross-env NODE_ENV=production rollup -c -m", + "examples": "node ./examples/server.js", + "coveralls": "cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js", + "fix": "eslint --fix lib/**/*.js", + "prepare": "husky install && npm run prepare:hooks", + "prepare:hooks": "npx husky set .husky/commit-msg \"npx commitlint --edit $1\"", + "release:dry": "release-it --dry-run --no-npm", + "release:info": "release-it --release-version", + "release:beta:no-npm": "release-it --preRelease=beta --no-npm", + "release:beta": "release-it --preRelease=beta", + "release:no-npm": "release-it --no-npm", + "release:changelog:fix": "node ./bin/injectContributorsList.js && git add CHANGELOG.md", + "release": "release-it" + }, + "repository": { + "type": "git", + "url": "https://github.com/axios/axios.git" + }, + "keywords": [ + "xhr", + "http", + "ajax", + "promise", + "node" + ], + "author": "Matt Zabriskie", + "license": "MIT", + "bugs": { + "url": "https://github.com/axios/axios/issues" + }, + "homepage": "https://axios-http.com", + "devDependencies": { + "@babel/core": "^7.23.9", + "@babel/preset-env": "^7.23.9", + "@commitlint/cli": "^17.8.1", + "@commitlint/config-conventional": "^17.8.1", + "@release-it/conventional-changelog": "^5.1.1", + "@rollup/plugin-alias": "^5.1.0", + "@rollup/plugin-babel": "^5.3.1", + "@rollup/plugin-commonjs": "^15.1.0", + "@rollup/plugin-json": "^4.1.0", + "@rollup/plugin-multi-entry": "^4.1.0", + "@rollup/plugin-node-resolve": "^9.0.0", + "abortcontroller-polyfill": "^1.7.5", + "auto-changelog": "^2.4.0", + "body-parser": "^1.20.2", + "chalk": "^5.3.0", + "coveralls": "^3.1.1", + "cross-env": "^7.0.3", + "dev-null": "^0.1.1", + "dtslint": "^4.2.1", + "es6-promise": "^4.2.8", + "eslint": "^8.56.0", + "express": "^4.18.2", + "formdata-node": "^5.0.1", + "formidable": "^2.1.2", + "fs-extra": "^10.1.0", + "get-stream": "^3.0.0", + "gulp": "^4.0.2", + "handlebars": "^4.7.8", + "husky": "^8.0.3", + "istanbul-instrumenter-loader": "^3.0.1", + "jasmine-core": "^2.99.1", + "karma": "^6.3.17", + "karma-chrome-launcher": "^3.2.0", + "karma-firefox-launcher": "^2.1.2", + "karma-jasmine": "^1.1.2", + "karma-jasmine-ajax": "^0.1.13", + "karma-rollup-preprocessor": "^7.0.8", + "karma-safari-launcher": "^1.0.0", + "karma-sauce-launcher": "^4.3.6", + "karma-sinon": "^1.0.5", + "karma-sourcemap-loader": "^0.3.8", + "memoizee": "^0.4.15", + "minimist": "^1.2.8", + "mocha": "^10.3.0", + "multer": "^1.4.4", + "pacote": "^20.0.0", + "pretty-bytes": "^6.1.1", + "release-it": "^15.11.0", + "rollup": "^2.79.1", + "rollup-plugin-auto-external": "^2.0.0", + "rollup-plugin-bundle-size": "^1.0.3", + "rollup-plugin-terser": "^7.0.2", + "sinon": "^4.5.0", + "stream-throttle": "^0.1.3", + "string-replace-async": "^3.0.2", + "tar-stream": "^3.1.7", + "terser-webpack-plugin": "^4.2.3", + "typescript": "^4.9.5" + }, + "browser": { + "./lib/adapters/http.js": "./lib/helpers/null.js", + "./lib/platform/node/index.js": "./lib/platform/browser/index.js", + "./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js" + }, + "react-native": { + "./lib/adapters/http.js": "./lib/helpers/null.js", + "./lib/platform/node/index.js": "./lib/platform/browser/index.js", + "./lib/platform/node/classes/FormData.js": "./lib/helpers/null.js" + }, + "jsdelivr": "dist/axios.min.js", + "unpkg": "dist/axios.min.js", + "typings": "./index.d.ts", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + }, + "bundlesize": [ + { + "path": "./dist/axios.min.js", + "threshold": "5kB" + } + ], + "contributors": [ + "Matt Zabriskie (https://github.com/mzabriskie)", + "Dmitriy Mozgovoy (https://github.com/DigitalBrainJS)", + "Nick Uraltsev (https://github.com/nickuraltsev)", + "Jay (https://github.com/jasonsaayman)", + "Emily Morehouse (https://github.com/emilyemorehouse)", + "Rubén Norte (https://github.com/rubennorte)", + "Justin Beckwith (https://github.com/JustinBeckwith)", + "Martti Laine (https://github.com/codeclown)", + "Xianming Zhong (https://github.com/chinesedfan)", + "Remco Haszing (https://github.com/remcohaszing)", + "Rikki Gibson (https://github.com/RikkiGibson)", + "Willian Agostini (https://github.com/WillianAgostini)", + "Yasu Flores (https://github.com/yasuf)" + ], + "sideEffects": false, + "release-it": { + "git": { + "commitMessage": "chore(release): v${version}", + "push": true, + "commit": true, + "tag": true, + "requireCommits": false, + "requireCleanWorkingDir": false + }, + "github": { + "release": true, + "draft": true + }, + "npm": { + "publish": false, + "ignoreVersion": false + }, + "plugins": { + "@release-it/conventional-changelog": { + "preset": "angular", + "infile": "CHANGELOG.md", + "header": "# Changelog" + } + }, + "hooks": { + "before:init": "npm test", + "after:bump": "gulp version --bump ${version} && npm run build && npm run test:build:version", + "before:release": "npm run release:changelog:fix && git add ./package-lock.json", + "after:release": "echo Successfully released ${name} v${version} to ${repo.repository}." + } + }, + "commitlint": { + "rules": { + "header-max-length": [ + 2, + "always", + 130 + ] + }, + "extends": [ + "@commitlint/config-conventional" + ] + } +} \ No newline at end of file diff --git a/node_modules/backoff/CHANGES.md b/node_modules/backoff/CHANGES.md new file mode 100644 index 0000000..c820200 --- /dev/null +++ b/node_modules/backoff/CHANGES.md @@ -0,0 +1,86 @@ +# Changelog + +## 2.5.0 + +Those changes are not released yet. + +- In the functional API, invoke the wrapped function callback on abort and emit + an `abort` event. This makes it possible to detect when abort is called. +- Add a method on the function API, `call.retryIf(predicate)`, which specifies + a predicate used to determine whether a given error is retriable or not. The + default behavior is unaffected, errors remain retriable by default. + +## 2.4.1 + +- Add support for specifying the factor to use in the `ExponentialStrategy`. + +## 2.4.0 + +- Replace `FunctionCall.getResults` by `FunctionCall.getLastResult` to avoid + storing intermediary results forever as this may lead to memory exhaustion + when used in conjunction with an infinite number of backoffs. +- Add `FunctionCall.getNumRetries` which returns the number of times the + wrapped function was retried. + +## 2.3.0 + +- Add four new methods to `FunctionCall` to query the state of the call. + - isPending + - isRunning + - isCompleted + - isAborted + +## 2.2.0 + +- To match `Backoff` default behavior, `FunctionCall` no longer sets a + default failAfter of 5, i.e. the maximum number of backoffs is now + unbounded by default. + +## 2.1.0 + +- `Backoff.backoff` now accepts an optional error argument that is re-emitted + as the last argument of the `backoff` and `fail` events. This provides some + context to the listeners as to why a given backoff operation was attempted. +- The `backoff` event emitted by the `FunctionCall` class now contains, as its + last argument, the error that caused the backoff operation to be attempted. + This provides some context to the listeners as to why a given backoff + operation was attempted. + +## 2.0.0 + +- `FunctionCall.call` renamed into `FunctionCall.start`. +- `backoff.call` no longer invokes the wrapped function on `nextTick`. That + way, the first attempt is not delayed until the end of the current event + loop. + +## 1.2.1 + +- Make `FunctionCall.backoffFactory` a private member. + +## 1.2.0 + +- Add `backoff.call` and the associated `FunctionCall` class. + +## 1.1.0 + +- Add a `Backoff.failAfter`. + +## 1.0.0 + +- Rename `start` and `done` events `backoff` and `ready`. +- Remove deprecated `backoff.fibonnaci`. + +## 0.2.1 + +- Create `backoff.fibonacci`. +- Deprecate `backoff.fibonnaci`. +- Expose fibonacci and exponential strategies. + +## 0.2.0 + +- Provide exponential and fibonacci backoffs. + +## 0.1.0 + +- Change `initialTimeout` and `maxTimeout` to `initialDelay` and `maxDelay`. +- Use fibonnaci backoff. diff --git a/node_modules/backoff/LICENSE b/node_modules/backoff/LICENSE new file mode 100644 index 0000000..8748698 --- /dev/null +++ b/node_modules/backoff/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2012 Mathieu Turcotte + +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. diff --git a/node_modules/backoff/README.md b/node_modules/backoff/README.md new file mode 100644 index 0000000..f64a6e8 --- /dev/null +++ b/node_modules/backoff/README.md @@ -0,0 +1,382 @@ +# Backoff for Node.js +[![Build Status](https://secure.travis-ci.org/MathieuTurcotte/node-backoff.png?branch=master)](http://travis-ci.org/MathieuTurcotte/node-backoff) +[![NPM version](https://badge.fury.io/js/backoff.png)](http://badge.fury.io/js/backoff) + +Fibonacci and exponential backoffs for Node.js. + +## Installation + +``` +npm install backoff +``` + +## Unit tests + +``` +npm test +``` + +## Usage + +### Object Oriented + +The usual way to instantiate a new `Backoff` object is to use one predefined +factory method: `backoff.fibonacci([options])`, `backoff.exponential([options])`. + +`Backoff` inherits from `EventEmitter`. When a backoff starts, a `backoff` +event is emitted and, when a backoff ends, a `ready` event is emitted. +Handlers for these two events are called with the current backoff number and +delay. + +``` js +var backoff = require('backoff'); + +var fibonacciBackoff = backoff.fibonacci({ + randomisationFactor: 0, + initialDelay: 10, + maxDelay: 300 +}); + +fibonacciBackoff.failAfter(10); + +fibonacciBackoff.on('backoff', function(number, delay) { + // Do something when backoff starts, e.g. show to the + // user the delay before next reconnection attempt. + console.log(number + ' ' + delay + 'ms'); +}); + +fibonacciBackoff.on('ready', function(number, delay) { + // Do something when backoff ends, e.g. retry a failed + // operation (DNS lookup, API call, etc.). If it fails + // again then backoff, otherwise reset the backoff + // instance. + fibonacciBackoff.backoff(); +}); + +fibonacciBackoff.on('fail', function() { + // Do something when the maximum number of backoffs is + // reached, e.g. ask the user to check its connection. + console.log('fail'); +}); + +fibonacciBackoff.backoff(); +``` + +The previous example would print the following. + +``` +0 10ms +1 10ms +2 20ms +3 30ms +4 50ms +5 80ms +6 130ms +7 210ms +8 300ms +9 300ms +fail +``` + +Note that `Backoff` objects are meant to be instantiated once and reused +several times by calling `reset` after a successful "retry". + +### Functional + +It's also possible to avoid some boilerplate code when invoking an asynchronous +function in a backoff loop by using `backoff.call(fn, [args, ...], callback)`. + +Typical usage looks like the following. + +``` js +var call = backoff.call(get, 'https://duplika.ca/', function(err, res) { + console.log('Num retries: ' + call.getNumRetries()); + + if (err) { + console.log('Error: ' + err.message); + } else { + console.log('Status: ' + res.statusCode); + } +}); + +call.retryIf(function(err) { return err.status == 503; }); +call.setStrategy(new backoff.ExponentialStrategy()); +call.failAfter(10); +call.start(); +``` + +## API + +### backoff.fibonacci([options]) + +Constructs a Fibonacci backoff (10, 10, 20, 30, 50, etc.). + +The options are the following. + +- randomisationFactor: defaults to 0, must be between 0 and 1 +- initialDelay: defaults to 100 ms +- maxDelay: defaults to 10000 ms + +With these values, the backoff delay will increase from 100 ms to 10000 ms. The +randomisation factor controls the range of randomness and must be between 0 +and 1. By default, no randomisation is applied on the backoff delay. + +### backoff.exponential([options]) + +Constructs an exponential backoff (10, 20, 40, 80, etc.). + +The options are the following. + +- randomisationFactor: defaults to 0, must be between 0 and 1 +- initialDelay: defaults to 100 ms +- maxDelay: defaults to 10000 ms +- factor: defaults to 2, must be greater than 1 + +With these values, the backoff delay will increase from 100 ms to 10000 ms. The +randomisation factor controls the range of randomness and must be between 0 +and 1. By default, no randomisation is applied on the backoff delay. + +### backoff.call(fn, [args, ...], callback) + +- fn: function to call in a backoff handler, i.e. the wrapped function +- args: function's arguments +- callback: function's callback accepting an error as its first argument + +Constructs a `FunctionCall` instance for the given function. The wrapped +function will get retried until it succeds or reaches the maximum number +of backoffs. In both cases, the callback function will be invoked with the +last result returned by the wrapped function. + +It is the caller's responsability to initiate the call by invoking the +`start` method on the returned `FunctionCall` instance. + +### Class Backoff + +#### new Backoff(strategy) + +- strategy: the backoff strategy to use + +Constructs a new backoff object from a specific backoff strategy. The backoff +strategy must implement the `BackoffStrategy`interface defined bellow. + +#### backoff.failAfter(numberOfBackoffs) + +- numberOfBackoffs: maximum number of backoffs before the fail event gets +emitted, must be greater than 0 + +Sets a limit on the maximum number of backoffs that can be performed before +a fail event gets emitted and the backoff instance is reset. By default, there +is no limit on the number of backoffs that can be performed. + +#### backoff.backoff([err]) + +Starts a backoff operation. If provided, the error parameter will be emitted +as the last argument of the `backoff` and `fail` events to let the listeners +know why the backoff operation was attempted. + +An error will be thrown if a backoff operation is already in progress. + +In practice, this method should be called after a failed attempt to perform a +sensitive operation (connecting to a database, downloading a resource over the +network, etc.). + +#### backoff.reset() + +Resets the backoff delay to the initial backoff delay and stop any backoff +operation in progress. After reset, a backoff instance can and should be +reused. + +In practice, this method should be called after having successfully completed +the sensitive operation guarded by the backoff instance or if the client code +request to stop any reconnection attempt. + +#### Event: 'backoff' + +- number: number of backoffs since last reset, starting at 0 +- delay: backoff delay in milliseconds +- err: optional error parameter passed to `backoff.backoff([err])` + +Emitted when a backoff operation is started. Signals to the client how long +the next backoff delay will be. + +#### Event: 'ready' + +- number: number of backoffs since last reset, starting at 0 +- delay: backoff delay in milliseconds + +Emitted when a backoff operation is done. Signals that the failing operation +should be retried. + +#### Event: 'fail' + +- err: optional error parameter passed to `backoff.backoff([err])` + +Emitted when the maximum number of backoffs is reached. This event will only +be emitted if the client has set a limit on the number of backoffs by calling +`backoff.failAfter(numberOfBackoffs)`. The backoff instance is automatically +reset after this event is emitted. + +### Interface BackoffStrategy + +A backoff strategy must provide the following methods. + +#### strategy.next() + +Computes and returns the next backoff delay. + +#### strategy.reset() + +Resets the backoff delay to its initial value. + +### Class ExponentialStrategy + +Exponential (10, 20, 40, 80, etc.) backoff strategy implementation. + +#### new ExponentialStrategy([options]) + +The options are the following. + +- randomisationFactor: defaults to 0, must be between 0 and 1 +- initialDelay: defaults to 100 ms +- maxDelay: defaults to 10000 ms +- factor: defaults to 2, must be greater than 1 + +### Class FibonacciStrategy + +Fibonnaci (10, 10, 20, 30, 50, etc.) backoff strategy implementation. + +#### new FibonacciStrategy([options]) + +The options are the following. + +- randomisationFactor: defaults to 0, must be between 0 and 1 +- initialDelay: defaults to 100 ms +- maxDelay: defaults to 10000 ms + +### Class FunctionCall + +This class manages the calling of an asynchronous function within a backoff +loop. + +This class should rarely be instantiated directly since the factory method +`backoff.call(fn, [args, ...], callback)` offers a more convenient and safer +way to create `FunctionCall` instances. + +#### new FunctionCall(fn, args, callback) + +- fn: asynchronous function to call +- args: an array containing fn's args +- callback: fn's callback + +Constructs a function handler for the given asynchronous function. + +#### call.isPending() + +Returns whether the call is pending, i.e. hasn't been started. + +#### call.isRunning() + +Returns whether the call is in progress. + +#### call.isCompleted() + +Returns whether the call is completed. + +#### call.isAborted() + +Returns whether the call is aborted. + +#### call.setStrategy(strategy) + +- strategy: strategy instance to use, defaults to `FibonacciStrategy`. + +Sets the backoff strategy to use. This method should be called before +`call.start()` otherwise an exception will be thrown. + +#### call.failAfter(maxNumberOfBackoffs) + +- maxNumberOfBackoffs: maximum number of backoffs before the call is aborted + +Sets the maximum number of backoffs before the call is aborted. By default, +there is no limit on the number of backoffs that can be performed. + +This method should be called before `call.start()` otherwise an exception will +be thrown.. + +#### call.retryIf(predicate) + +- predicate: a function which takes in as its argument the error returned +by the wrapped function and determines whether it is retriable. + +Sets the predicate which will be invoked to determine whether a given error +should be retried or not, e.g. a network error would be retriable while a type +error would stop the function call. By default, all errors are considered to be +retriable. + +This method should be called before `call.start()` otherwise an exception will +be thrown. + +#### call.getLastResult() + +Returns an array containing the last arguments passed to the completion callback +of the wrapped function. For example, to get the error code returned by the last +call, one would do the following. + +``` js +var results = call.getLastResult(); +// The error code is the first parameter of the callback. +var error = results[0]; +``` + +Note that if the call was aborted, it will contain the abort error and not the +last error returned by the wrapped function. + +#### call.getNumRetries() + +Returns the number of times the wrapped function call was retried. For a +wrapped function that succeeded immediately, this would return 0. This +method can be called at any point in time during the call life cycle, i.e. +before, during and after the wrapped function invocation. + +#### call.start() + +Initiates the call the wrapped function. This method should only be called +once otherwise an exception will be thrown. + +#### call.abort() + +Aborts the call and causes the completion callback to be invoked with an abort +error if the call was pending or running; does nothing otherwise. This method +can safely be called mutliple times. + +#### Event: 'call' + +- args: wrapped function's arguments + +Emitted each time the wrapped function is called. + +#### Event: 'callback' + +- results: wrapped function's return values + +Emitted each time the wrapped function invokes its callback. + +#### Event: 'backoff' + +- number: backoff number, starts at 0 +- delay: backoff delay in milliseconds +- err: the error that triggered the backoff operation + +Emitted each time a backoff operation is started. + +#### Event: 'abort' + +Emitted when a call is aborted. + +## Annotated source code + +The annotated source code can be found at [mathieuturcotte.github.io/node-backoff/docs](http://mathieuturcotte.github.io/node-backoff/docs/). + +## License + +This code is free to use under the terms of the [MIT license](http://mturcotte.mit-license.org/). diff --git a/node_modules/backoff/index.js b/node_modules/backoff/index.js new file mode 100644 index 0000000..6281fa6 --- /dev/null +++ b/node_modules/backoff/index.js @@ -0,0 +1,31 @@ +// Copyright (c) 2012 Mathieu Turcotte +// Licensed under the MIT license. + +var Backoff = require('./lib/backoff'); +var ExponentialBackoffStrategy = require('./lib/strategy/exponential'); +var FibonacciBackoffStrategy = require('./lib/strategy/fibonacci'); +var FunctionCall = require('./lib/function_call.js'); + +module.exports.Backoff = Backoff; +module.exports.FunctionCall = FunctionCall; +module.exports.FibonacciStrategy = FibonacciBackoffStrategy; +module.exports.ExponentialStrategy = ExponentialBackoffStrategy; + +// Constructs a Fibonacci backoff. +module.exports.fibonacci = function(options) { + return new Backoff(new FibonacciBackoffStrategy(options)); +}; + +// Constructs an exponential backoff. +module.exports.exponential = function(options) { + return new Backoff(new ExponentialBackoffStrategy(options)); +}; + +// Constructs a FunctionCall for the given function and arguments. +module.exports.call = function(fn, vargs, callback) { + var args = Array.prototype.slice.call(arguments); + fn = args[0]; + vargs = args.slice(1, args.length - 1); + callback = args[args.length - 1]; + return new FunctionCall(fn, vargs, callback); +}; diff --git a/node_modules/backoff/lib/backoff.js b/node_modules/backoff/lib/backoff.js new file mode 100644 index 0000000..202a280 --- /dev/null +++ b/node_modules/backoff/lib/backoff.js @@ -0,0 +1,65 @@ +// Copyright (c) 2012 Mathieu Turcotte +// Licensed under the MIT license. + +var events = require('events'); +var precond = require('precond'); +var util = require('util'); + +// A class to hold the state of a backoff operation. Accepts a backoff strategy +// to generate the backoff delays. +function Backoff(backoffStrategy) { + events.EventEmitter.call(this); + + this.backoffStrategy_ = backoffStrategy; + this.maxNumberOfRetry_ = -1; + this.backoffNumber_ = 0; + this.backoffDelay_ = 0; + this.timeoutID_ = -1; + + this.handlers = { + backoff: this.onBackoff_.bind(this) + }; +} +util.inherits(Backoff, events.EventEmitter); + +// Sets a limit, greater than 0, on the maximum number of backoffs. A 'fail' +// event will be emitted when the limit is reached. +Backoff.prototype.failAfter = function(maxNumberOfRetry) { + precond.checkArgument(maxNumberOfRetry > 0, + 'Expected a maximum number of retry greater than 0 but got %s.', + maxNumberOfRetry); + + this.maxNumberOfRetry_ = maxNumberOfRetry; +}; + +// Starts a backoff operation. Accepts an optional parameter to let the +// listeners know why the backoff operation was started. +Backoff.prototype.backoff = function(err) { + precond.checkState(this.timeoutID_ === -1, 'Backoff in progress.'); + + if (this.backoffNumber_ === this.maxNumberOfRetry_) { + this.emit('fail', err); + this.reset(); + } else { + this.backoffDelay_ = this.backoffStrategy_.next(); + this.timeoutID_ = setTimeout(this.handlers.backoff, this.backoffDelay_); + this.emit('backoff', this.backoffNumber_, this.backoffDelay_, err); + } +}; + +// Handles the backoff timeout completion. +Backoff.prototype.onBackoff_ = function() { + this.timeoutID_ = -1; + this.emit('ready', this.backoffNumber_, this.backoffDelay_); + this.backoffNumber_++; +}; + +// Stops any backoff operation and resets the backoff delay to its inital value. +Backoff.prototype.reset = function() { + this.backoffNumber_ = 0; + this.backoffStrategy_.reset(); + clearTimeout(this.timeoutID_); + this.timeoutID_ = -1; +}; + +module.exports = Backoff; diff --git a/node_modules/backoff/lib/function_call.js b/node_modules/backoff/lib/function_call.js new file mode 100644 index 0000000..37319d7 --- /dev/null +++ b/node_modules/backoff/lib/function_call.js @@ -0,0 +1,190 @@ +// Copyright (c) 2012 Mathieu Turcotte +// Licensed under the MIT license. + +var events = require('events'); +var precond = require('precond'); +var util = require('util'); + +var Backoff = require('./backoff'); +var FibonacciBackoffStrategy = require('./strategy/fibonacci'); + +// Wraps a function to be called in a backoff loop. +function FunctionCall(fn, args, callback) { + events.EventEmitter.call(this); + + precond.checkIsFunction(fn, 'Expected fn to be a function.'); + precond.checkIsArray(args, 'Expected args to be an array.'); + precond.checkIsFunction(callback, 'Expected callback to be a function.'); + + this.function_ = fn; + this.arguments_ = args; + this.callback_ = callback; + this.lastResult_ = []; + this.numRetries_ = 0; + + this.backoff_ = null; + this.strategy_ = null; + this.failAfter_ = -1; + this.retryPredicate_ = FunctionCall.DEFAULT_RETRY_PREDICATE_; + + this.state_ = FunctionCall.State_.PENDING; +} +util.inherits(FunctionCall, events.EventEmitter); + +// States in which the call can be. +FunctionCall.State_ = { + // Call isn't started yet. + PENDING: 0, + // Call is in progress. + RUNNING: 1, + // Call completed successfully which means that either the wrapped function + // returned successfully or the maximal number of backoffs was reached. + COMPLETED: 2, + // The call was aborted. + ABORTED: 3 +}; + +// The default retry predicate which considers any error as retriable. +FunctionCall.DEFAULT_RETRY_PREDICATE_ = function(err) { + return true; +}; + +// Checks whether the call is pending. +FunctionCall.prototype.isPending = function() { + return this.state_ == FunctionCall.State_.PENDING; +}; + +// Checks whether the call is in progress. +FunctionCall.prototype.isRunning = function() { + return this.state_ == FunctionCall.State_.RUNNING; +}; + +// Checks whether the call is completed. +FunctionCall.prototype.isCompleted = function() { + return this.state_ == FunctionCall.State_.COMPLETED; +}; + +// Checks whether the call is aborted. +FunctionCall.prototype.isAborted = function() { + return this.state_ == FunctionCall.State_.ABORTED; +}; + +// Sets the backoff strategy to use. Can only be called before the call is +// started otherwise an exception will be thrown. +FunctionCall.prototype.setStrategy = function(strategy) { + precond.checkState(this.isPending(), 'FunctionCall in progress.'); + this.strategy_ = strategy; + return this; // Return this for chaining. +}; + +// Sets the predicate which will be used to determine whether the errors +// returned from the wrapped function should be retried or not, e.g. a +// network error would be retriable while a type error would stop the +// function call. +FunctionCall.prototype.retryIf = function(retryPredicate) { + precond.checkState(this.isPending(), 'FunctionCall in progress.'); + this.retryPredicate_ = retryPredicate; + return this; +}; + +// Returns all intermediary results returned by the wrapped function since +// the initial call. +FunctionCall.prototype.getLastResult = function() { + return this.lastResult_.concat(); +}; + +// Returns the number of times the wrapped function call was retried. +FunctionCall.prototype.getNumRetries = function() { + return this.numRetries_; +}; + +// Sets the backoff limit. +FunctionCall.prototype.failAfter = function(maxNumberOfRetry) { + precond.checkState(this.isPending(), 'FunctionCall in progress.'); + this.failAfter_ = maxNumberOfRetry; + return this; // Return this for chaining. +}; + +// Aborts the call. +FunctionCall.prototype.abort = function() { + if (this.isCompleted() || this.isAborted()) { + return; + } + + if (this.isRunning()) { + this.backoff_.reset(); + } + + this.state_ = FunctionCall.State_.ABORTED; + this.lastResult_ = [new Error('Backoff aborted.')]; + this.emit('abort'); + this.doCallback_(); +}; + +// Initiates the call to the wrapped function. Accepts an optional factory +// function used to create the backoff instance; used when testing. +FunctionCall.prototype.start = function(backoffFactory) { + precond.checkState(!this.isAborted(), 'FunctionCall is aborted.'); + precond.checkState(this.isPending(), 'FunctionCall already started.'); + + var strategy = this.strategy_ || new FibonacciBackoffStrategy(); + + this.backoff_ = backoffFactory ? + backoffFactory(strategy) : + new Backoff(strategy); + + this.backoff_.on('ready', this.doCall_.bind(this, true /* isRetry */)); + this.backoff_.on('fail', this.doCallback_.bind(this)); + this.backoff_.on('backoff', this.handleBackoff_.bind(this)); + + if (this.failAfter_ > 0) { + this.backoff_.failAfter(this.failAfter_); + } + + this.state_ = FunctionCall.State_.RUNNING; + this.doCall_(false /* isRetry */); +}; + +// Calls the wrapped function. +FunctionCall.prototype.doCall_ = function(isRetry) { + if (isRetry) { + this.numRetries_++; + } + var eventArgs = ['call'].concat(this.arguments_); + events.EventEmitter.prototype.emit.apply(this, eventArgs); + var callback = this.handleFunctionCallback_.bind(this); + this.function_.apply(null, this.arguments_.concat(callback)); +}; + +// Calls the wrapped function's callback with the last result returned by the +// wrapped function. +FunctionCall.prototype.doCallback_ = function() { + this.callback_.apply(null, this.lastResult_); +}; + +// Handles wrapped function's completion. This method acts as a replacement +// for the original callback function. +FunctionCall.prototype.handleFunctionCallback_ = function() { + if (this.isAborted()) { + return; + } + + var args = Array.prototype.slice.call(arguments); + this.lastResult_ = args; // Save last callback arguments. + events.EventEmitter.prototype.emit.apply(this, ['callback'].concat(args)); + + var err = args[0]; + if (err && this.retryPredicate_(err)) { + this.backoff_.backoff(err); + } else { + this.state_ = FunctionCall.State_.COMPLETED; + this.doCallback_(); + } +}; + +// Handles the backoff event by reemitting it. +FunctionCall.prototype.handleBackoff_ = function(number, delay, err) { + this.emit('backoff', number, delay, err); +}; + +module.exports = FunctionCall; diff --git a/node_modules/backoff/lib/strategy/exponential.js b/node_modules/backoff/lib/strategy/exponential.js new file mode 100644 index 0000000..8074a40 --- /dev/null +++ b/node_modules/backoff/lib/strategy/exponential.js @@ -0,0 +1,41 @@ +// Copyright (c) 2012 Mathieu Turcotte +// Licensed under the MIT license. + +var util = require('util'); +var precond = require('precond'); + +var BackoffStrategy = require('./strategy'); + +// Exponential backoff strategy. +function ExponentialBackoffStrategy(options) { + BackoffStrategy.call(this, options); + this.backoffDelay_ = 0; + this.nextBackoffDelay_ = this.getInitialDelay(); + this.factor_ = ExponentialBackoffStrategy.DEFAULT_FACTOR; + + if (options && options.factor !== undefined) { + precond.checkArgument(options.factor > 1, + 'Exponential factor should be greater than 1 but got %s.', + options.factor); + this.factor_ = options.factor; + } +} +util.inherits(ExponentialBackoffStrategy, BackoffStrategy); + +// Default multiplication factor used to compute the next backoff delay from +// the current one. The value can be overridden by passing a custom factor as +// part of the options. +ExponentialBackoffStrategy.DEFAULT_FACTOR = 2; + +ExponentialBackoffStrategy.prototype.next_ = function() { + this.backoffDelay_ = Math.min(this.nextBackoffDelay_, this.getMaxDelay()); + this.nextBackoffDelay_ = this.backoffDelay_ * this.factor_; + return this.backoffDelay_; +}; + +ExponentialBackoffStrategy.prototype.reset_ = function() { + this.backoffDelay_ = 0; + this.nextBackoffDelay_ = this.getInitialDelay(); +}; + +module.exports = ExponentialBackoffStrategy; diff --git a/node_modules/backoff/lib/strategy/fibonacci.js b/node_modules/backoff/lib/strategy/fibonacci.js new file mode 100644 index 0000000..7c71c03 --- /dev/null +++ b/node_modules/backoff/lib/strategy/fibonacci.js @@ -0,0 +1,28 @@ +// Copyright (c) 2012 Mathieu Turcotte +// Licensed under the MIT license. + +var util = require('util'); + +var BackoffStrategy = require('./strategy'); + +// Fibonacci backoff strategy. +function FibonacciBackoffStrategy(options) { + BackoffStrategy.call(this, options); + this.backoffDelay_ = 0; + this.nextBackoffDelay_ = this.getInitialDelay(); +} +util.inherits(FibonacciBackoffStrategy, BackoffStrategy); + +FibonacciBackoffStrategy.prototype.next_ = function() { + var backoffDelay = Math.min(this.nextBackoffDelay_, this.getMaxDelay()); + this.nextBackoffDelay_ += this.backoffDelay_; + this.backoffDelay_ = backoffDelay; + return backoffDelay; +}; + +FibonacciBackoffStrategy.prototype.reset_ = function() { + this.nextBackoffDelay_ = this.getInitialDelay(); + this.backoffDelay_ = 0; +}; + +module.exports = FibonacciBackoffStrategy; diff --git a/node_modules/backoff/lib/strategy/strategy.js b/node_modules/backoff/lib/strategy/strategy.js new file mode 100644 index 0000000..7adfd75 --- /dev/null +++ b/node_modules/backoff/lib/strategy/strategy.js @@ -0,0 +1,80 @@ +// Copyright (c) 2012 Mathieu Turcotte +// Licensed under the MIT license. + +var events = require('events'); +var util = require('util'); + +function isDef(value) { + return value !== undefined && value !== null; +} + +// Abstract class defining the skeleton for the backoff strategies. Accepts an +// object holding the options for the backoff strategy: +// +// * `randomisationFactor`: The randomisation factor which must be between 0 +// and 1 where 1 equates to a randomization factor of 100% and 0 to no +// randomization. +// * `initialDelay`: The backoff initial delay in milliseconds. +// * `maxDelay`: The backoff maximal delay in milliseconds. +function BackoffStrategy(options) { + options = options || {}; + + if (isDef(options.initialDelay) && options.initialDelay < 1) { + throw new Error('The initial timeout must be greater than 0.'); + } else if (isDef(options.maxDelay) && options.maxDelay < 1) { + throw new Error('The maximal timeout must be greater than 0.'); + } + + this.initialDelay_ = options.initialDelay || 100; + this.maxDelay_ = options.maxDelay || 10000; + + if (this.maxDelay_ <= this.initialDelay_) { + throw new Error('The maximal backoff delay must be ' + + 'greater than the initial backoff delay.'); + } + + if (isDef(options.randomisationFactor) && + (options.randomisationFactor < 0 || options.randomisationFactor > 1)) { + throw new Error('The randomisation factor must be between 0 and 1.'); + } + + this.randomisationFactor_ = options.randomisationFactor || 0; +} + +// Gets the maximal backoff delay. +BackoffStrategy.prototype.getMaxDelay = function() { + return this.maxDelay_; +}; + +// Gets the initial backoff delay. +BackoffStrategy.prototype.getInitialDelay = function() { + return this.initialDelay_; +}; + +// Template method that computes and returns the next backoff delay in +// milliseconds. +BackoffStrategy.prototype.next = function() { + var backoffDelay = this.next_(); + var randomisationMultiple = 1 + Math.random() * this.randomisationFactor_; + var randomizedDelay = Math.round(backoffDelay * randomisationMultiple); + return randomizedDelay; +}; + +// Computes and returns the next backoff delay. Intended to be overridden by +// subclasses. +BackoffStrategy.prototype.next_ = function() { + throw new Error('BackoffStrategy.next_() unimplemented.'); +}; + +// Template method that resets the backoff delay to its initial value. +BackoffStrategy.prototype.reset = function() { + this.reset_(); +}; + +// Resets the backoff delay to its initial value. Intended to be overridden by +// subclasses. +BackoffStrategy.prototype.reset_ = function() { + throw new Error('BackoffStrategy.reset_() unimplemented.'); +}; + +module.exports = BackoffStrategy; diff --git a/node_modules/backoff/package.json b/node_modules/backoff/package.json new file mode 100644 index 0000000..b6d6cb6 --- /dev/null +++ b/node_modules/backoff/package.json @@ -0,0 +1,32 @@ +{ + "name": "backoff", + "description": "Fibonacci and exponential backoffs.", + "version": "2.5.0", + "license": "MIT", + "author": "Mathieu Turcotte ", + "keywords": ["backoff", "retry", "fibonacci", "exponential"], + "repository": { + "type": "git", + "url": "https://github.com/MathieuTurcotte/node-backoff.git" + }, + "dependencies": { + "precond": "0.2" + }, + "devDependencies": { + "sinon": "1.10", + "nodeunit": "0.9" + }, + "scripts": { + "docco" : "docco lib/*.js lib/strategy/* index.js", + "pretest": "jshint lib/ tests/ examples/ index.js", + "test": "node_modules/nodeunit/bin/nodeunit tests/" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "index.js", + "lib", + "tests" + ] +} diff --git a/node_modules/backoff/tests/api.js b/node_modules/backoff/tests/api.js new file mode 100644 index 0000000..835c412 --- /dev/null +++ b/node_modules/backoff/tests/api.js @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var sinon = require('sinon'); + +var backoff = require('../index'); + +exports["API"] = { + "backoff.fibonnaci should be a function that returns a backoff instance": function(test) { + test.ok(backoff.fibonacci, 'backoff.fibonacci should be defined.'); + test.equal(typeof backoff.fibonacci, 'function', + 'backoff.fibonacci should be a function.'); + test.equal(backoff.fibonacci().constructor.name, 'Backoff'); + test.done(); + }, + + "backoff.exponential should be a function that returns a backoff instance": function(test) { + test.ok(backoff.exponential, 'backoff.exponential should be defined.'); + test.equal(typeof backoff.exponential, 'function', + 'backoff.exponential should be a function.'); + test.equal(backoff.exponential().constructor.name, 'Backoff'); + test.done(); + }, + + "backoff.call should be a function that returns a FunctionCall instance": function(test) { + var fn = function() {}; + var callback = function() {}; + test.ok(backoff.Backoff, 'backoff.call should be defined.'); + test.equal(typeof backoff.call, 'function', + 'backoff.call should be a function.'); + test.equal(backoff.call(fn, 1, 2, 3, callback).constructor.name, + 'FunctionCall'); + test.done(); + }, + + "backoff.Backoff should be defined and a function": function(test) { + test.ok(backoff.Backoff, 'backoff.Backoff should be defined.'); + test.equal(typeof backoff.Backoff, 'function', + 'backoff.Backoff should be a function.'); + test.done(); + }, + + "backoff.FunctionCall should be defined and a function": function(test) { + test.ok(backoff.FunctionCall, + 'backoff.FunctionCall should be defined.'); + test.equal(typeof backoff.FunctionCall, 'function', + 'backoff.FunctionCall should be a function.'); + test.done(); + }, + + "backoff.FibonacciStrategy should be defined and a function": function(test) { + test.ok(backoff.FibonacciStrategy, + 'backoff.FibonacciStrategy should be defined.'); + test.equal(typeof backoff.FibonacciStrategy, 'function', + 'backoff.FibonacciStrategy should be a function.'); + test.done(); + }, + + "backoff.ExponentialStrategy should be defined and a function": function(test) { + test.ok(backoff.ExponentialStrategy, + 'backoff.ExponentialStrategy should be defined.'); + test.equal(typeof backoff.ExponentialStrategy, 'function', + 'backoff.ExponentialStrategy should be a function.'); + test.done(); + } +}; diff --git a/node_modules/backoff/tests/backoff.js b/node_modules/backoff/tests/backoff.js new file mode 100644 index 0000000..84bbd16 --- /dev/null +++ b/node_modules/backoff/tests/backoff.js @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var sinon = require('sinon'); + +var Backoff = require('../lib/backoff'); +var BackoffStrategy = require('../lib/strategy/strategy'); + +exports["Backoff"] = { + setUp: function(callback) { + this.backoffStrategy = sinon.stub(new BackoffStrategy()); + this.backoff = new Backoff(this.backoffStrategy); + this.clock = sinon.useFakeTimers(); + this.spy = new sinon.spy(); + callback(); + }, + + tearDown: function(callback) { + this.clock.restore(); + callback(); + }, + + "the backoff event should be emitted when backoff starts": function(test) { + this.backoffStrategy.next.returns(10); + this.backoff.on('backoff', this.spy); + + this.backoff.backoff(); + + test.ok(this.spy.calledOnce, + 'Backoff event should be emitted when backoff starts.'); + test.done(); + }, + + "the ready event should be emitted on backoff completion": function(test) { + this.backoffStrategy.next.returns(10); + this.backoff.on('ready', this.spy); + + this.backoff.backoff(); + this.clock.tick(10); + + test.ok(this.spy.calledOnce, + 'Ready event should be emitted when backoff ends.'); + test.done(); + }, + + "the backoff event should be passed the backoff delay": function(test) { + this.backoffStrategy.next.returns(989); + this.backoff.on('backoff', this.spy); + + this.backoff.backoff(); + + test.equal(this.spy.getCall(0).args[1], 989, 'Backoff event should ' + + 'carry the backoff delay as its second argument.'); + test.done(); + }, + + "the ready event should be passed the backoff delay": function(test) { + this.backoffStrategy.next.returns(989); + this.backoff.on('ready', this.spy); + + this.backoff.backoff(); + this.clock.tick(989); + + test.equal(this.spy.getCall(0).args[1], 989, 'Ready event should ' + + 'carry the backoff delay as its second argument.'); + test.done(); + }, + + "the fail event should be emitted when backoff limit is reached": function(test) { + var err = new Error('Fail'); + + this.backoffStrategy.next.returns(10); + this.backoff.on('fail', this.spy); + + this.backoff.failAfter(2); + + // Consume first 2 backoffs. + for (var i = 0; i < 2; i++) { + this.backoff.backoff(); + this.clock.tick(10); + } + + // Failure should occur on the third call, and not before. + test.ok(!this.spy.calledOnce, 'Fail event shouldn\'t have been emitted.'); + this.backoff.backoff(err); + test.ok(this.spy.calledOnce, 'Fail event should have been emitted.'); + test.equal(this.spy.getCall(0).args[0], err, 'Error should be passed'); + + test.done(); + }, + + "calling backoff while a backoff is in progress should throw an error": function(test) { + this.backoffStrategy.next.returns(10); + var backoff = this.backoff; + + backoff.backoff(); + + test.throws(function() { + backoff.backoff(); + }, /in progress/); + + test.done(); + }, + + "backoff limit should be greater than 0": function(test) { + var backoff = this.backoff; + test.throws(function() { + backoff.failAfter(0); + }, /greater than 0 but got 0/); + test.done(); + }, + + "reset should cancel any backoff in progress": function(test) { + this.backoffStrategy.next.returns(10); + this.backoff.on('ready', this.spy); + + this.backoff.backoff(); + + this.backoff.reset(); + this.clock.tick(100); // 'ready' should not be emitted. + + test.equals(this.spy.callCount, 0, 'Reset should have aborted the backoff.'); + test.done(); + }, + + "reset should reset the backoff strategy": function(test) { + this.backoff.reset(); + test.ok(this.backoffStrategy.reset.calledOnce, + 'The backoff strategy should have been resetted.'); + test.done(); + }, + + "backoff should be reset after fail": function(test) { + this.backoffStrategy.next.returns(10); + + this.backoff.failAfter(1); + + this.backoff.backoff(); + this.clock.tick(10); + this.backoff.backoff(); + + test.ok(this.backoffStrategy.reset.calledOnce, + 'Backoff should have been resetted after failure.'); + test.done(); + }, + + "the backoff number should increase from 0 to N - 1": function(test) { + this.backoffStrategy.next.returns(10); + this.backoff.on('backoff', this.spy); + + var expectedNumbers = [0, 1, 2, 3, 4]; + var actualNumbers = []; + + for (var i = 0; i < expectedNumbers.length; i++) { + this.backoff.backoff(); + this.clock.tick(10); + actualNumbers.push(this.spy.getCall(i).args[0]); + } + + test.deepEqual(expectedNumbers, actualNumbers, + 'Backoff number should increase from 0 to N - 1.'); + test.done(); + } +}; diff --git a/node_modules/backoff/tests/backoff_strategy.js b/node_modules/backoff/tests/backoff_strategy.js new file mode 100644 index 0000000..507f2a0 --- /dev/null +++ b/node_modules/backoff/tests/backoff_strategy.js @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var sinon = require('sinon'); +var util = require('util'); + +var BackoffStrategy = require('../lib/strategy/strategy'); + +function SampleBackoffStrategy(options) { + BackoffStrategy.call(this, options); +} +util.inherits(SampleBackoffStrategy, BackoffStrategy); + +SampleBackoffStrategy.prototype.next_ = function() { + return this.getInitialDelay(); +}; + +SampleBackoffStrategy.prototype.reset_ = function() {}; + +exports["BackoffStrategy"] = { + setUp: function(callback) { + this.random = sinon.stub(Math, 'random'); + callback(); + }, + + tearDown: function(callback) { + this.random.restore(); + callback(); + }, + + "the randomisation factor should be between 0 and 1": function(test) { + test.throws(function() { + new BackoffStrategy({ + randomisationFactor: -0.1 + }); + }); + + test.throws(function() { + new BackoffStrategy({ + randomisationFactor: 1.1 + }); + }); + + test.doesNotThrow(function() { + new BackoffStrategy({ + randomisationFactor: 0.5 + }); + }); + + test.done(); + }, + + "the raw delay should be randomized based on the randomisation factor": function(test) { + var strategy = new SampleBackoffStrategy({ + randomisationFactor: 0.5, + initialDelay: 1000 + }); + this.random.returns(0.5); + + var backoffDelay = strategy.next(); + + test.equals(backoffDelay, 1000 + (1000 * 0.5 * 0.5)); + test.done(); + }, + + "the initial backoff delay should be greater than 0": function(test) { + test.throws(function() { + new BackoffStrategy({ + initialDelay: -1 + }); + }); + + test.throws(function() { + new BackoffStrategy({ + initialDelay: 0 + }); + }); + + test.doesNotThrow(function() { + new BackoffStrategy({ + initialDelay: 1 + }); + }); + + test.done(); + }, + + "the maximal backoff delay should be greater than 0": function(test) { + test.throws(function() { + new BackoffStrategy({ + maxDelay: -1 + }); + }); + + test.throws(function() { + new BackoffStrategy({ + maxDelay: 0 + }); + }); + + test.done(); + }, + + "the maximal backoff delay should be greater than the initial backoff delay": function(test) { + test.throws(function() { + new BackoffStrategy({ + initialDelay: 10, + maxDelay: 10 + }); + }); + + test.doesNotThrow(function() { + new BackoffStrategy({ + initialDelay: 10, + maxDelay: 11 + }); + }); + + test.done(); + } +}; diff --git a/node_modules/backoff/tests/exponential_backoff_strategy.js b/node_modules/backoff/tests/exponential_backoff_strategy.js new file mode 100644 index 0000000..3c83f50 --- /dev/null +++ b/node_modules/backoff/tests/exponential_backoff_strategy.js @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var sinon = require('sinon'); + +var ExponentialBackoffStrategy = require('../lib/strategy/exponential'); + +exports["ExponentialBackoffStrategy"] = { + + "backoff delays should follow an exponential sequence": function(test) { + var strategy = new ExponentialBackoffStrategy({ + initialDelay: 10, + maxDelay: 1000 + }); + + // Exponential sequence: x[i] = x[i-1] * 2. + var expectedDelays = [10, 20, 40, 80, 160, 320, 640, 1000, 1000]; + var actualDelays = expectedDelays.map(function () { + return strategy.next(); + }); + + test.deepEqual(expectedDelays, actualDelays, + 'Generated delays should follow an exponential sequence.'); + test.done(); + }, + + "backoff delay factor should be configurable": function (test) { + var strategy = new ExponentialBackoffStrategy({ + initialDelay: 10, + maxDelay: 270, + factor: 3 + }); + + // Exponential sequence: x[i] = x[i-1] * 3. + var expectedDelays = [10, 30, 90, 270, 270]; + var actualDelays = expectedDelays.map(function () { + return strategy.next(); + }); + + test.deepEqual(expectedDelays, actualDelays, + 'Generated delays should follow a configurable exponential sequence.'); + test.done(); + }, + + "backoff delays should restart from the initial delay after reset": function(test) { + var strategy = new ExponentialBackoffStrategy({ + initialDelay: 10, + maxDelay: 1000 + }); + + strategy.next(); + strategy.reset(); + + var backoffDelay = strategy.next(); + test.equals(backoffDelay, 10, + 'Strategy should return the initial delay after reset.'); + test.done(); + } +}; diff --git a/node_modules/backoff/tests/fibonacci_backoff_strategy.js b/node_modules/backoff/tests/fibonacci_backoff_strategy.js new file mode 100644 index 0000000..cb15197 --- /dev/null +++ b/node_modules/backoff/tests/fibonacci_backoff_strategy.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var sinon = require('sinon'); + +var FibonacciBackoffStrategy = require('../lib/strategy/fibonacci'); + +exports["FibonacciBackoffStrategy"] = { + setUp: function(callback) { + this.strategy = new FibonacciBackoffStrategy({ + initialDelay: 10, + maxDelay: 1000 + }); + callback(); + }, + + "backoff delays should follow a Fibonacci sequence": function(test) { + // Fibonacci sequence: x[i] = x[i-1] + x[i-2]. + var expectedDelays = [10, 10, 20, 30, 50, 80, 130, 210, 340, 550, 890, 1000]; + var actualDelays = []; + + for (var i = 0; i < expectedDelays.length; i++) { + actualDelays.push(this.strategy.next()); + } + + test.deepEqual(expectedDelays, actualDelays, + 'Generated delays should follow a Fibonacci sequence.'); + test.done(); + }, + + "backoff delays should restart from the initial delay after reset": function(test) { + var strategy = new FibonacciBackoffStrategy({ + initialDelay: 10, + maxDelay: 1000 + }); + + strategy.next(); + strategy.reset(); + + var backoffDelay = strategy.next(); + test.equals(backoffDelay, 10, + 'Strategy should return the initial delay after reset.'); + test.done(); + } +}; diff --git a/node_modules/backoff/tests/function_call.js b/node_modules/backoff/tests/function_call.js new file mode 100644 index 0000000..d54f4b0 --- /dev/null +++ b/node_modules/backoff/tests/function_call.js @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var assert = require('assert'); +var events = require('events'); +var sinon = require('sinon'); +var util = require('util'); + +var FunctionCall = require('../lib/function_call'); + +function MockBackoff() { + events.EventEmitter.call(this); + + this.reset = sinon.spy(); + this.backoff = sinon.spy(); + this.failAfter = sinon.spy(); +} +util.inherits(MockBackoff, events.EventEmitter); + +exports["FunctionCall"] = { + setUp: function(callback) { + this.wrappedFn = sinon.stub(); + this.callback = sinon.stub(); + this.backoff = new MockBackoff(); + this.backoffFactory = sinon.stub(); + this.backoffFactory.returns(this.backoff); + callback(); + }, + + tearDown: function(callback) { + callback(); + }, + + "constructor's first argument should be a function": function(test) { + test.throws(function() { + new FunctionCall(1, [], function() {}); + }, /Expected fn to be a function./); + test.done(); + }, + + "constructor's last argument should be a function": function(test) { + test.throws(function() { + new FunctionCall(function() {}, [], 3); + }, /Expected callback to be a function./); + test.done(); + }, + + "isPending should return false once the call is started": function(test) { + this.wrappedFn. + onFirstCall().yields(new Error()). + onSecondCall().yields(null, 'Success!'); + var call = new FunctionCall(this.wrappedFn, [], this.callback); + + test.ok(call.isPending()); + + call.start(this.backoffFactory); + test.ok(!call.isPending()); + + this.backoff.emit('ready'); + test.ok(!call.isPending()); + + test.done(); + }, + + "isRunning should return true when call is in progress": function(test) { + this.wrappedFn. + onFirstCall().yields(new Error()). + onSecondCall().yields(null, 'Success!'); + var call = new FunctionCall(this.wrappedFn, [], this.callback); + + test.ok(!call.isRunning()); + + call.start(this.backoffFactory); + test.ok(call.isRunning()); + + this.backoff.emit('ready'); + test.ok(!call.isRunning()); + + test.done(); + }, + + "isCompleted should return true once the call completes": function(test) { + this.wrappedFn. + onFirstCall().yields(new Error()). + onSecondCall().yields(null, 'Success!'); + var call = new FunctionCall(this.wrappedFn, [], this.callback); + + test.ok(!call.isCompleted()); + + call.start(this.backoffFactory); + test.ok(!call.isCompleted()); + + this.backoff.emit('ready'); + test.ok(call.isCompleted()); + + test.done(); + }, + + "isAborted should return true once the call is aborted": function(test) { + this.wrappedFn. + onFirstCall().yields(new Error()). + onSecondCall().yields(null, 'Success!'); + var call = new FunctionCall(this.wrappedFn, [], this.callback); + + test.ok(!call.isAborted()); + call.abort(); + test.ok(call.isAborted()); + + test.done(); + }, + + "setStrategy should overwrite the default strategy": function(test) { + var replacementStrategy = {}; + var call = new FunctionCall(this.wrappedFn, [], this.callback); + call.setStrategy(replacementStrategy); + call.start(this.backoffFactory); + test.ok(this.backoffFactory.calledWith(replacementStrategy), + 'User defined strategy should be used to instantiate ' + + 'the backoff instance.'); + test.done(); + }, + + "setStrategy should throw if the call is in progress": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + call.start(this.backoffFactory); + test.throws(function() { + call.setStrategy({}); + }, /in progress/); + test.done(); + }, + + "failAfter should not be set by default": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + call.start(this.backoffFactory); + test.equal(0, this.backoff.failAfter.callCount); + test.done(); + }, + + "failAfter should be used as the maximum number of backoffs": function(test) { + var failAfterValue = 99; + var call = new FunctionCall(this.wrappedFn, [], this.callback); + call.failAfter(failAfterValue); + call.start(this.backoffFactory); + test.ok(this.backoff.failAfter.calledWith(failAfterValue), + 'User defined maximum number of backoffs shoud be ' + + 'used to configure the backoff instance.'); + test.done(); + }, + + "failAfter should throw if the call is in progress": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + call.start(this.backoffFactory); + test.throws(function() { + call.failAfter(1234); + }, /in progress/); + test.done(); + }, + + "start shouldn't allow overlapping invocation": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + var backoffFactory = this.backoffFactory; + + call.start(backoffFactory); + test.throws(function() { + call.start(backoffFactory); + }, /already started/); + test.done(); + }, + + "start shouldn't allow invocation of aborted call": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + var backoffFactory = this.backoffFactory; + + call.abort(); + test.throws(function() { + call.start(backoffFactory); + }, /aborted/); + test.done(); + }, + + "call should forward its arguments to the wrapped function": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 2, 3], this.callback); + call.start(this.backoffFactory); + test.ok(this.wrappedFn.calledWith(1, 2, 3)); + test.done(); + }, + + "call should complete when the wrapped function succeeds": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 2, 3], this.callback); + this.wrappedFn. + onCall(0).yields(new Error()). + onCall(1).yields(new Error()). + onCall(2).yields(new Error()). + onCall(3).yields(null, 'Success!'); + + call.start(this.backoffFactory); + + for (var i = 0; i < 2; i++) { + this.backoff.emit('ready'); + } + + test.equals(this.callback.callCount, 0); + this.backoff.emit('ready'); + + test.ok(this.callback.calledWith(null, 'Success!')); + test.ok(this.wrappedFn.alwaysCalledWith(1, 2, 3)); + test.done(); + }, + + "call should fail when the backoff limit is reached": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 2, 3], this.callback); + var error = new Error(); + this.wrappedFn.yields(error); + call.start(this.backoffFactory); + + for (var i = 0; i < 3; i++) { + this.backoff.emit('ready'); + } + + test.equals(this.callback.callCount, 0); + + this.backoff.emit('fail'); + + test.ok(this.callback.calledWith(error)); + test.ok(this.wrappedFn.alwaysCalledWith(1, 2, 3)); + test.done(); + }, + + "call should fail when the retry predicate returns false": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 2, 3], this.callback); + call.retryIf(function(err) { return err.retriable; }); + + var retriableError = new Error(); + retriableError.retriable = true; + + var fatalError = new Error(); + fatalError.retriable = false; + + this.wrappedFn. + onCall(0).yields(retriableError). + onCall(1).yields(retriableError). + onCall(2).yields(fatalError); + + call.start(this.backoffFactory); + + for (var i = 0; i < 2; i++) { + this.backoff.emit('ready'); + } + + test.equals(this.callback.callCount, 1); + test.ok(this.callback.calledWith(fatalError)); + test.ok(this.wrappedFn.alwaysCalledWith(1, 2, 3)); + test.done(); + }, + + "wrapped function's callback shouldn't be called after abort": function(test) { + var call = new FunctionCall(function(callback) { + call.abort(); // Abort in middle of wrapped function's execution. + callback(null, 'ok'); + }, [], this.callback); + + call.start(this.backoffFactory); + + test.equals(this.callback.callCount, 1, + 'Wrapped function\'s callback shouldn\'t be called after abort.'); + test.ok(this.callback.calledWithMatch(sinon.match(function (err) { + return !!err.message.match(/Backoff aborted/); + }, "abort error"))); + test.done(); + }, + + "abort event is emitted once when abort is called": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + this.wrappedFn.yields(new Error()); + var callEventSpy = sinon.spy(); + + call.on('abort', callEventSpy); + call.start(this.backoffFactory); + + call.abort(); + call.abort(); + call.abort(); + + test.equals(callEventSpy.callCount, 1); + test.done(); + }, + + "getLastResult should return the last intermediary result": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + this.wrappedFn.yields(1); + call.start(this.backoffFactory); + + for (var i = 2; i < 5; i++) { + this.wrappedFn.yields(i); + this.backoff.emit('ready'); + test.deepEqual([i], call.getLastResult()); + } + + this.wrappedFn.yields(null); + this.backoff.emit('ready'); + test.deepEqual([null], call.getLastResult()); + + test.done(); + }, + + "getNumRetries should return the number of retries": function(test) { + var call = new FunctionCall(this.wrappedFn, [], this.callback); + + this.wrappedFn.yields(1); + call.start(this.backoffFactory); + // The inital call doesn't count as a retry. + test.equals(0, call.getNumRetries()); + + for (var i = 2; i < 5; i++) { + this.wrappedFn.yields(i); + this.backoff.emit('ready'); + test.equals(i - 1, call.getNumRetries()); + } + + this.wrappedFn.yields(null); + this.backoff.emit('ready'); + test.equals(4, call.getNumRetries()); + + test.done(); + }, + + "wrapped function's errors should be propagated": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 2, 3], this.callback); + this.wrappedFn.throws(new Error()); + test.throws(function() { + call.start(this.backoffFactory); + }, Error); + test.done(); + }, + + "wrapped callback's errors should be propagated": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 2, 3], this.callback); + this.wrappedFn.yields(null, 'Success!'); + this.callback.throws(new Error()); + test.throws(function() { + call.start(this.backoffFactory); + }, Error); + test.done(); + }, + + "call event should be emitted when wrapped function gets called": function(test) { + this.wrappedFn.yields(1); + var callEventSpy = sinon.spy(); + + var call = new FunctionCall(this.wrappedFn, [1, 'two'], this.callback); + call.on('call', callEventSpy); + call.start(this.backoffFactory); + + for (var i = 1; i < 5; i++) { + this.backoff.emit('ready'); + } + + test.equal(5, callEventSpy.callCount, + 'The call event should have been emitted 5 times.'); + test.deepEqual([1, 'two'], callEventSpy.getCall(0).args, + 'The call event should carry function\'s args.'); + test.done(); + }, + + "callback event should be emitted when callback is called": function(test) { + var call = new FunctionCall(this.wrappedFn, [1, 'two'], this.callback); + var callbackSpy = sinon.spy(); + call.on('callback', callbackSpy); + + this.wrappedFn.yields('error'); + call.start(this.backoffFactory); + + this.wrappedFn.yields(null, 'done'); + this.backoff.emit('ready'); + + test.equal(2, callbackSpy.callCount, + 'Callback event should have been emitted 2 times.'); + test.deepEqual(['error'], callbackSpy.firstCall.args, + 'First callback event should carry first call\'s results.'); + test.deepEqual([null, 'done'], callbackSpy.secondCall.args, + 'Second callback event should carry second call\'s results.'); + test.done(); + }, + + "backoff event should be emitted on backoff start": function(test) { + var err = new Error('backoff event error'); + var call = new FunctionCall(this.wrappedFn, [1, 'two'], this.callback); + var backoffSpy = sinon.spy(); + + call.on('backoff', backoffSpy); + + this.wrappedFn.yields(err); + call.start(this.backoffFactory); + this.backoff.emit('backoff', 3, 1234, err); + + test.ok(this.backoff.backoff.calledWith(err), + 'The backoff instance should have been called with the error.'); + test.equal(1, backoffSpy.callCount, + 'Backoff event should have been emitted 1 time.'); + test.deepEqual([3, 1234, err], backoffSpy.firstCall.args, + 'Backoff event should carry the backoff number, delay and error.'); + test.done(); + } +}; diff --git a/node_modules/call-bind-apply-helpers/.eslintrc b/node_modules/call-bind-apply-helpers/.eslintrc new file mode 100644 index 0000000..201e859 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/.eslintrc @@ -0,0 +1,17 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "func-name-matching": 0, + "id-length": 0, + "new-cap": [2, { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + "no-extra-parens": 0, + "no-magic-numbers": 0, + }, +} diff --git a/node_modules/call-bind-apply-helpers/.github/FUNDING.yml b/node_modules/call-bind-apply-helpers/.github/FUNDING.yml new file mode 100644 index 0000000..0011e9d --- /dev/null +++ b/node_modules/call-bind-apply-helpers/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/call-bind-apply-helpers +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/call-bind-apply-helpers/.nycrc b/node_modules/call-bind-apply-helpers/.nycrc new file mode 100644 index 0000000..bdd626c --- /dev/null +++ b/node_modules/call-bind-apply-helpers/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/call-bind-apply-helpers/CHANGELOG.md b/node_modules/call-bind-apply-helpers/CHANGELOG.md new file mode 100644 index 0000000..2484942 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/CHANGELOG.md @@ -0,0 +1,30 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.2](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.1...v1.0.2) - 2025-02-12 + +### Commits + +- [types] improve inferred types [`e6f9586`](https://github.com/ljharb/call-bind-apply-helpers/commit/e6f95860a3c72879cb861a858cdfb8138fbedec1) +- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`e43d540`](https://github.com/ljharb/call-bind-apply-helpers/commit/e43d5409f97543bfbb11f345d47d8ce4e066d8c1) + +## [v1.0.1](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.0...v1.0.1) - 2024-12-08 + +### Commits + +- [types] `reflectApply`: fix types [`4efc396`](https://github.com/ljharb/call-bind-apply-helpers/commit/4efc3965351a4f02cc55e836fa391d3d11ef2ef8) +- [Fix] `reflectApply`: oops, Reflect is not a function [`83cc739`](https://github.com/ljharb/call-bind-apply-helpers/commit/83cc7395de6b79b7730bdf092f1436f0b1263c75) +- [Dev Deps] update `@arethetypeswrong/cli` [`80bd5d3`](https://github.com/ljharb/call-bind-apply-helpers/commit/80bd5d3ae58b4f6b6995ce439dd5a1bcb178a940) + +## v1.0.0 - 2024-12-05 + +### Commits + +- Initial implementation, tests, readme [`7879629`](https://github.com/ljharb/call-bind-apply-helpers/commit/78796290f9b7430c9934d6f33d94ae9bc89fce04) +- Initial commit [`3f1dc16`](https://github.com/ljharb/call-bind-apply-helpers/commit/3f1dc164afc43285631b114a5f9dd9137b2b952f) +- npm init [`081df04`](https://github.com/ljharb/call-bind-apply-helpers/commit/081df048c312fcee400922026f6e97281200a603) +- Only apps should have lockfiles [`5b9ca0f`](https://github.com/ljharb/call-bind-apply-helpers/commit/5b9ca0fe8101ebfaf309c549caac4e0a017ed930) diff --git a/node_modules/call-bind-apply-helpers/LICENSE b/node_modules/call-bind-apply-helpers/LICENSE new file mode 100644 index 0000000..f82f389 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jordan Harband + +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. diff --git a/node_modules/call-bind-apply-helpers/README.md b/node_modules/call-bind-apply-helpers/README.md new file mode 100644 index 0000000..8fc0dae --- /dev/null +++ b/node_modules/call-bind-apply-helpers/README.md @@ -0,0 +1,62 @@ +# call-bind-apply-helpers [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![dependency status][deps-svg]][deps-url] +[![dev dependency status][dev-deps-svg]][dev-deps-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Helper functions around Function call/apply/bind, for use in `call-bind`. + +The only packages that should likely ever use this package directly are `call-bind` and `get-intrinsic`. +Please use `call-bind` unless you have a very good reason not to. + +## Getting started + +```sh +npm install --save call-bind-apply-helpers +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const callBindBasic = require('call-bind-apply-helpers'); + +function f(a, b) { + assert.equal(this, 1); + assert.equal(a, 2); + assert.equal(b, 3); + assert.equal(arguments.length, 2); +} + +const fBound = callBindBasic([f, 1]); + +delete Function.prototype.call; +delete Function.prototype.bind; + +fBound(2, 3); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/call-bind-apply-helpers +[npm-version-svg]: https://versionbadg.es/ljharb/call-bind-apply-helpers.svg +[deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers.svg +[deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers +[dev-deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/call-bind-apply-helpers.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/call-bind-apply-helpers.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/call-bind-apply-helpers.svg +[downloads-url]: https://npm-stat.com/charts.html?package=call-bind-apply-helpers +[codecov-image]: https://codecov.io/gh/ljharb/call-bind-apply-helpers/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/call-bind-apply-helpers/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bind-apply-helpers +[actions-url]: https://github.com/ljharb/call-bind-apply-helpers/actions diff --git a/node_modules/call-bind-apply-helpers/actualApply.d.ts b/node_modules/call-bind-apply-helpers/actualApply.d.ts new file mode 100644 index 0000000..b87286a --- /dev/null +++ b/node_modules/call-bind-apply-helpers/actualApply.d.ts @@ -0,0 +1 @@ +export = Reflect.apply; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/actualApply.js b/node_modules/call-bind-apply-helpers/actualApply.js new file mode 100644 index 0000000..ffa5135 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/actualApply.js @@ -0,0 +1,10 @@ +'use strict'; + +var bind = require('function-bind'); + +var $apply = require('./functionApply'); +var $call = require('./functionCall'); +var $reflectApply = require('./reflectApply'); + +/** @type {import('./actualApply')} */ +module.exports = $reflectApply || bind.call($call, $apply); diff --git a/node_modules/call-bind-apply-helpers/applyBind.d.ts b/node_modules/call-bind-apply-helpers/applyBind.d.ts new file mode 100644 index 0000000..d176c1a --- /dev/null +++ b/node_modules/call-bind-apply-helpers/applyBind.d.ts @@ -0,0 +1,19 @@ +import actualApply from './actualApply'; + +type TupleSplitHead = T['length'] extends N + ? T + : T extends [...infer R, any] + ? TupleSplitHead + : never + +type TupleSplitTail = O['length'] extends N + ? T + : T extends [infer F, ...infer R] + ? TupleSplitTail<[...R], N, [...O, F]> + : never + +type TupleSplit = [TupleSplitHead, TupleSplitTail] + +declare function applyBind(...args: TupleSplit, 2>[1]): ReturnType; + +export = applyBind; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/applyBind.js b/node_modules/call-bind-apply-helpers/applyBind.js new file mode 100644 index 0000000..d2b7723 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/applyBind.js @@ -0,0 +1,10 @@ +'use strict'; + +var bind = require('function-bind'); +var $apply = require('./functionApply'); +var actualApply = require('./actualApply'); + +/** @type {import('./applyBind')} */ +module.exports = function applyBind() { + return actualApply(bind, $apply, arguments); +}; diff --git a/node_modules/call-bind-apply-helpers/functionApply.d.ts b/node_modules/call-bind-apply-helpers/functionApply.d.ts new file mode 100644 index 0000000..1f6e11b --- /dev/null +++ b/node_modules/call-bind-apply-helpers/functionApply.d.ts @@ -0,0 +1 @@ +export = Function.prototype.apply; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/functionApply.js b/node_modules/call-bind-apply-helpers/functionApply.js new file mode 100644 index 0000000..c71df9c --- /dev/null +++ b/node_modules/call-bind-apply-helpers/functionApply.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./functionApply')} */ +module.exports = Function.prototype.apply; diff --git a/node_modules/call-bind-apply-helpers/functionCall.d.ts b/node_modules/call-bind-apply-helpers/functionCall.d.ts new file mode 100644 index 0000000..15e93df --- /dev/null +++ b/node_modules/call-bind-apply-helpers/functionCall.d.ts @@ -0,0 +1 @@ +export = Function.prototype.call; \ No newline at end of file diff --git a/node_modules/call-bind-apply-helpers/functionCall.js b/node_modules/call-bind-apply-helpers/functionCall.js new file mode 100644 index 0000000..7a8d873 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/functionCall.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./functionCall')} */ +module.exports = Function.prototype.call; diff --git a/node_modules/call-bind-apply-helpers/index.d.ts b/node_modules/call-bind-apply-helpers/index.d.ts new file mode 100644 index 0000000..541516b --- /dev/null +++ b/node_modules/call-bind-apply-helpers/index.d.ts @@ -0,0 +1,64 @@ +type RemoveFromTuple< + Tuple extends readonly unknown[], + RemoveCount extends number, + Index extends 1[] = [] +> = Index["length"] extends RemoveCount + ? Tuple + : Tuple extends [infer First, ...infer Rest] + ? RemoveFromTuple + : Tuple; + +type ConcatTuples< + Prefix extends readonly unknown[], + Suffix extends readonly unknown[] +> = [...Prefix, ...Suffix]; + +type ExtractFunctionParams = T extends (this: infer TThis, ...args: infer P extends readonly unknown[]) => infer R + ? { thisArg: TThis; params: P; returnType: R } + : never; + +type BindFunction< + T extends (this: any, ...args: any[]) => any, + TThis, + TBoundArgs extends readonly unknown[], + ReceiverBound extends boolean +> = ExtractFunctionParams extends { + thisArg: infer OrigThis; + params: infer P extends readonly unknown[]; + returnType: infer R; +} + ? ReceiverBound extends true + ? (...args: RemoveFromTuple>) => R extends [OrigThis, ...infer Rest] + ? [TThis, ...Rest] // Replace `this` with `thisArg` + : R + : >>( + thisArg: U, + ...args: RemainingArgs + ) => R extends [OrigThis, ...infer Rest] + ? [U, ...ConcatTuples] // Preserve bound args in return type + : R + : never; + +declare function callBind< + const T extends (this: any, ...args: any[]) => any, + Extracted extends ExtractFunctionParams, + const TBoundArgs extends Partial & readonly unknown[], + const TThis extends Extracted["thisArg"] +>( + args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs] +): BindFunction; + +declare function callBind< + const T extends (this: any, ...args: any[]) => any, + Extracted extends ExtractFunctionParams, + const TBoundArgs extends Partial & readonly unknown[] +>( + args: [fn: T, ...boundArgs: TBoundArgs] +): BindFunction; + +declare function callBind( + args: [fn: Exclude, ...rest: TArgs] +): never; + +// export as namespace callBind; +export = callBind; diff --git a/node_modules/call-bind-apply-helpers/index.js b/node_modules/call-bind-apply-helpers/index.js new file mode 100644 index 0000000..2f6dab4 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/index.js @@ -0,0 +1,15 @@ +'use strict'; + +var bind = require('function-bind'); +var $TypeError = require('es-errors/type'); + +var $call = require('./functionCall'); +var $actualApply = require('./actualApply'); + +/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */ +module.exports = function callBindBasic(args) { + if (args.length < 1 || typeof args[0] !== 'function') { + throw new $TypeError('a function is required'); + } + return $actualApply(bind, $call, args); +}; diff --git a/node_modules/call-bind-apply-helpers/package.json b/node_modules/call-bind-apply-helpers/package.json new file mode 100644 index 0000000..923b8be --- /dev/null +++ b/node_modules/call-bind-apply-helpers/package.json @@ -0,0 +1,85 @@ +{ + "name": "call-bind-apply-helpers", + "version": "1.0.2", + "description": "Helper functions around Function call/apply/bind, for use in `call-bind`", + "main": "index.js", + "exports": { + ".": "./index.js", + "./actualApply": "./actualApply.js", + "./applyBind": "./applyBind.js", + "./functionApply": "./functionApply.js", + "./functionCall": "./functionCall.js", + "./reflectApply": "./reflectApply.js", + "./package.json": "./package.json" + }, + "scripts": { + "prepack": "npmignore --auto --commentLines=auto", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "prelint": "evalmd README.md", + "lint": "eslint --ext=.js,.mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/call-bind-apply-helpers.git" + }, + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/call-bind-apply-helpers/issues" + }, + "homepage": "https://github.com/ljharb/call-bind-apply-helpers#readme", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.3", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.3", + "@types/for-each": "^0.3.3", + "@types/function-bind": "^1.1.10", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.8.1", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "es-value-fixtures": "^1.7.1", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "for-each": "^0.3.5", + "has-strict-mode": "^1.1.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "object-inspect": "^1.13.4", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "testling": { + "files": "test/index.js" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/call-bind-apply-helpers/reflectApply.d.ts b/node_modules/call-bind-apply-helpers/reflectApply.d.ts new file mode 100644 index 0000000..6b2ae76 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/reflectApply.d.ts @@ -0,0 +1,3 @@ +declare const reflectApply: false | typeof Reflect.apply; + +export = reflectApply; diff --git a/node_modules/call-bind-apply-helpers/reflectApply.js b/node_modules/call-bind-apply-helpers/reflectApply.js new file mode 100644 index 0000000..3d03caa --- /dev/null +++ b/node_modules/call-bind-apply-helpers/reflectApply.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./reflectApply')} */ +module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply; diff --git a/node_modules/call-bind-apply-helpers/test/index.js b/node_modules/call-bind-apply-helpers/test/index.js new file mode 100644 index 0000000..1cdc89e --- /dev/null +++ b/node_modules/call-bind-apply-helpers/test/index.js @@ -0,0 +1,63 @@ +'use strict'; + +var callBind = require('../'); +var hasStrictMode = require('has-strict-mode')(); +var forEach = require('for-each'); +var inspect = require('object-inspect'); +var v = require('es-value-fixtures'); + +var test = require('tape'); + +test('callBindBasic', function (t) { + forEach(v.nonFunctions, function (nonFunction) { + t['throws']( + // @ts-expect-error + function () { callBind([nonFunction]); }, + TypeError, + inspect(nonFunction) + ' is not a function' + ); + }); + + var sentinel = { sentinel: true }; + /** @type {(this: T, a: A, b: B) => [T | undefined, A, B]} */ + var func = function (a, b) { + // eslint-disable-next-line no-invalid-this + return [!hasStrictMode && this === global ? undefined : this, a, b]; + }; + t.equal(func.length, 2, 'original function length is 2'); + + /** type {(thisArg: unknown, a: number, b: number) => [unknown, number, number]} */ + var bound = callBind([func]); + /** type {((a: number, b: number) => [typeof sentinel, typeof a, typeof b])} */ + var boundR = callBind([func, sentinel]); + /** type {((b: number) => [typeof sentinel, number, typeof b])} */ + var boundArg = callBind([func, sentinel, /** @type {const} */ (1)]); + + // @ts-expect-error + t.deepEqual(bound(), [undefined, undefined, undefined], 'bound func with no args'); + + // @ts-expect-error + t.deepEqual(func(), [undefined, undefined, undefined], 'unbound func with too few args'); + // @ts-expect-error + t.deepEqual(bound(1, 2), [hasStrictMode ? 1 : Object(1), 2, undefined], 'bound func too few args'); + // @ts-expect-error + t.deepEqual(boundR(), [sentinel, undefined, undefined], 'bound func with receiver, with too few args'); + // @ts-expect-error + t.deepEqual(boundArg(), [sentinel, 1, undefined], 'bound func with receiver and arg, with too few args'); + + t.deepEqual(func(1, 2), [undefined, 1, 2], 'unbound func with right args'); + t.deepEqual(bound(1, 2, 3), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with right args'); + t.deepEqual(boundR(1, 2), [sentinel, 1, 2], 'bound func with receiver, with right args'); + t.deepEqual(boundArg(2), [sentinel, 1, 2], 'bound func with receiver and arg, with right arg'); + + // @ts-expect-error + t.deepEqual(func(1, 2, 3), [undefined, 1, 2], 'unbound func with too many args'); + // @ts-expect-error + t.deepEqual(bound(1, 2, 3, 4), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with too many args'); + // @ts-expect-error + t.deepEqual(boundR(1, 2, 3), [sentinel, 1, 2], 'bound func with receiver, with too many args'); + // @ts-expect-error + t.deepEqual(boundArg(2, 3), [sentinel, 1, 2], 'bound func with receiver and arg, with too many args'); + + t.end(); +}); diff --git a/node_modules/call-bind-apply-helpers/tsconfig.json b/node_modules/call-bind-apply-helpers/tsconfig.json new file mode 100644 index 0000000..aef9993 --- /dev/null +++ b/node_modules/call-bind-apply-helpers/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} \ No newline at end of file diff --git a/node_modules/combined-stream/License b/node_modules/combined-stream/License new file mode 100644 index 0000000..4804b7a --- /dev/null +++ b/node_modules/combined-stream/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Debuggable Limited + +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. diff --git a/node_modules/combined-stream/Readme.md b/node_modules/combined-stream/Readme.md new file mode 100644 index 0000000..9e367b5 --- /dev/null +++ b/node_modules/combined-stream/Readme.md @@ -0,0 +1,138 @@ +# combined-stream + +A stream that emits multiple other streams one after another. + +**NB** Currently `combined-stream` works with streams version 1 only. There is ongoing effort to switch this library to streams version 2. Any help is welcome. :) Meanwhile you can explore other libraries that provide streams2 support with more or less compatibility with `combined-stream`. + +- [combined-stream2](https://www.npmjs.com/package/combined-stream2): A drop-in streams2-compatible replacement for the combined-stream module. + +- [multistream](https://www.npmjs.com/package/multistream): A stream that emits multiple other streams one after another. + +## Installation + +``` bash +npm install combined-stream +``` + +## Usage + +Here is a simple example that shows how you can use combined-stream to combine +two files into one: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create(); +combinedStream.append(fs.createReadStream('file1.txt')); +combinedStream.append(fs.createReadStream('file2.txt')); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +While the example above works great, it will pause all source streams until +they are needed. If you don't want that to happen, you can set `pauseStreams` +to `false`: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create({pauseStreams: false}); +combinedStream.append(fs.createReadStream('file1.txt')); +combinedStream.append(fs.createReadStream('file2.txt')); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +However, what if you don't have all the source streams yet, or you don't want +to allocate the resources (file descriptors, memory, etc.) for them right away? +Well, in that case you can simply provide a callback that supplies the stream +by calling a `next()` function: + +``` javascript +var CombinedStream = require('combined-stream'); +var fs = require('fs'); + +var combinedStream = CombinedStream.create(); +combinedStream.append(function(next) { + next(fs.createReadStream('file1.txt')); +}); +combinedStream.append(function(next) { + next(fs.createReadStream('file2.txt')); +}); + +combinedStream.pipe(fs.createWriteStream('combined.txt')); +``` + +## API + +### CombinedStream.create([options]) + +Returns a new combined stream object. Available options are: + +* `maxDataSize` +* `pauseStreams` + +The effect of those options is described below. + +### combinedStream.pauseStreams = `true` + +Whether to apply back pressure to the underlaying streams. If set to `false`, +the underlaying streams will never be paused. If set to `true`, the +underlaying streams will be paused right after being appended, as well as when +`delayedStream.pipe()` wants to throttle. + +### combinedStream.maxDataSize = `2 * 1024 * 1024` + +The maximum amount of bytes (or characters) to buffer for all source streams. +If this value is exceeded, `combinedStream` emits an `'error'` event. + +### combinedStream.dataSize = `0` + +The amount of bytes (or characters) currently buffered by `combinedStream`. + +### combinedStream.append(stream) + +Appends the given `stream` to the combinedStream object. If `pauseStreams` is +set to `true, this stream will also be paused right away. + +`streams` can also be a function that takes one parameter called `next`. `next` +is a function that must be invoked in order to provide the `next` stream, see +example above. + +Regardless of how the `stream` is appended, combined-stream always attaches an +`'error'` listener to it, so you don't have to do that manually. + +Special case: `stream` can also be a String or Buffer. + +### combinedStream.write(data) + +You should not call this, `combinedStream` takes care of piping the appended +streams into itself for you. + +### combinedStream.resume() + +Causes `combinedStream` to start drain the streams it manages. The function is +idempotent, and also emits a `'resume'` event each time which usually goes to +the stream that is currently being drained. + +### combinedStream.pause(); + +If `combinedStream.pauseStreams` is set to `false`, this does nothing. +Otherwise a `'pause'` event is emitted, this goes to the stream that is +currently being drained, so you can use it to apply back pressure. + +### combinedStream.end(); + +Sets `combinedStream.writable` to false, emits an `'end'` event, and removes +all streams from the queue. + +### combinedStream.destroy(); + +Same as `combinedStream.end()`, except it emits a `'close'` event instead of +`'end'`. + +## License + +combined-stream is licensed under the MIT license. diff --git a/node_modules/combined-stream/lib/combined_stream.js b/node_modules/combined-stream/lib/combined_stream.js new file mode 100644 index 0000000..125f097 --- /dev/null +++ b/node_modules/combined-stream/lib/combined_stream.js @@ -0,0 +1,208 @@ +var util = require('util'); +var Stream = require('stream').Stream; +var DelayedStream = require('delayed-stream'); + +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; + + this._released = false; + this._streams = []; + this._currentStream = null; + this._insideLoop = false; + this._pendingNext = false; +} +util.inherits(CombinedStream, Stream); + +CombinedStream.create = function(options) { + var combinedStream = new this(); + + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; + } + + return combinedStream; +}; + +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); +}; + +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, + }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; + } + + this._handleErrors(stream); + + if (this.pauseStreams) { + stream.pause(); + } + } + + this._streams.push(stream); + return this; +}; + +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; + +CombinedStream.prototype._getNext = function() { + this._currentStream = null; + + if (this._insideLoop) { + this._pendingNext = true; + return; // defer call + } + + this._insideLoop = true; + try { + do { + this._pendingNext = false; + this._realGetNext(); + } while (this._pendingNext); + } finally { + this._insideLoop = false; + } +}; + +CombinedStream.prototype._realGetNext = function() { + var stream = this._streams.shift(); + + + if (typeof stream == 'undefined') { + this.end(); + return; + } + + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; + } + + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); + } + + this._pipeNext(stream); + }.bind(this)); +}; + +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; + + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); + return; + } + + var value = stream; + this.write(value); + this._getNext(); +}; + +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); + }); +}; + +CombinedStream.prototype.write = function(data) { + this.emit('data', data); +}; + +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; + } + + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; + +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); + } + + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); +}; + +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); +}; + +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); +}; + +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; +}; + +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; + } + + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; + +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; + + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; + } + + self.dataSize += stream.dataSize; + }); + + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; + } +}; + +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; diff --git a/node_modules/combined-stream/package.json b/node_modules/combined-stream/package.json new file mode 100644 index 0000000..6982b6d --- /dev/null +++ b/node_modules/combined-stream/package.json @@ -0,0 +1,25 @@ +{ + "author": "Felix Geisendörfer (http://debuggable.com/)", + "name": "combined-stream", + "description": "A stream that emits multiple other streams one after another.", + "version": "1.0.8", + "homepage": "https://github.com/felixge/node-combined-stream", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-combined-stream.git" + }, + "main": "./lib/combined_stream", + "scripts": { + "test": "node test/run.js" + }, + "engines": { + "node": ">= 0.8" + }, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "devDependencies": { + "far": "~0.0.7" + }, + "license": "MIT" +} diff --git a/node_modules/combined-stream/yarn.lock b/node_modules/combined-stream/yarn.lock new file mode 100644 index 0000000..7edf418 --- /dev/null +++ b/node_modules/combined-stream/yarn.lock @@ -0,0 +1,17 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +far@~0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/far/-/far-0.0.7.tgz#01c1fd362bcd26ce9cf161af3938aa34619f79a7" + dependencies: + oop "0.0.3" + +oop@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/oop/-/oop-0.0.3.tgz#70fa405a5650891a194fdc82ca68dad6dabf4401" diff --git a/node_modules/core-util-is/LICENSE b/node_modules/core-util-is/LICENSE new file mode 100644 index 0000000..d8d7f94 --- /dev/null +++ b/node_modules/core-util-is/LICENSE @@ -0,0 +1,19 @@ +Copyright Node.js contributors. All rights reserved. + +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. diff --git a/node_modules/core-util-is/README.md b/node_modules/core-util-is/README.md new file mode 100644 index 0000000..5a76b41 --- /dev/null +++ b/node_modules/core-util-is/README.md @@ -0,0 +1,3 @@ +# core-util-is + +The `util.is*` functions introduced in Node v0.12. diff --git a/node_modules/core-util-is/float.patch b/node_modules/core-util-is/float.patch new file mode 100644 index 0000000..a06d5c0 --- /dev/null +++ b/node_modules/core-util-is/float.patch @@ -0,0 +1,604 @@ +diff --git a/lib/util.js b/lib/util.js +index a03e874..9074e8e 100644 +--- a/lib/util.js ++++ b/lib/util.js +@@ -19,430 +19,6 @@ + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + +-var formatRegExp = /%[sdj%]/g; +-exports.format = function(f) { +- if (!isString(f)) { +- var objects = []; +- for (var i = 0; i < arguments.length; i++) { +- objects.push(inspect(arguments[i])); +- } +- return objects.join(' '); +- } +- +- var i = 1; +- var args = arguments; +- var len = args.length; +- var str = String(f).replace(formatRegExp, function(x) { +- if (x === '%%') return '%'; +- if (i >= len) return x; +- switch (x) { +- case '%s': return String(args[i++]); +- case '%d': return Number(args[i++]); +- case '%j': +- try { +- return JSON.stringify(args[i++]); +- } catch (_) { +- return '[Circular]'; +- } +- default: +- return x; +- } +- }); +- for (var x = args[i]; i < len; x = args[++i]) { +- if (isNull(x) || !isObject(x)) { +- str += ' ' + x; +- } else { +- str += ' ' + inspect(x); +- } +- } +- return str; +-}; +- +- +-// Mark that a method should not be used. +-// Returns a modified function which warns once by default. +-// If --no-deprecation is set, then it is a no-op. +-exports.deprecate = function(fn, msg) { +- // Allow for deprecating things in the process of starting up. +- if (isUndefined(global.process)) { +- return function() { +- return exports.deprecate(fn, msg).apply(this, arguments); +- }; +- } +- +- if (process.noDeprecation === true) { +- return fn; +- } +- +- var warned = false; +- function deprecated() { +- if (!warned) { +- if (process.throwDeprecation) { +- throw new Error(msg); +- } else if (process.traceDeprecation) { +- console.trace(msg); +- } else { +- console.error(msg); +- } +- warned = true; +- } +- return fn.apply(this, arguments); +- } +- +- return deprecated; +-}; +- +- +-var debugs = {}; +-var debugEnviron; +-exports.debuglog = function(set) { +- if (isUndefined(debugEnviron)) +- debugEnviron = process.env.NODE_DEBUG || ''; +- set = set.toUpperCase(); +- if (!debugs[set]) { +- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { +- var pid = process.pid; +- debugs[set] = function() { +- var msg = exports.format.apply(exports, arguments); +- console.error('%s %d: %s', set, pid, msg); +- }; +- } else { +- debugs[set] = function() {}; +- } +- } +- return debugs[set]; +-}; +- +- +-/** +- * Echos the value of a value. Trys to print the value out +- * in the best way possible given the different types. +- * +- * @param {Object} obj The object to print out. +- * @param {Object} opts Optional options object that alters the output. +- */ +-/* legacy: obj, showHidden, depth, colors*/ +-function inspect(obj, opts) { +- // default options +- var ctx = { +- seen: [], +- stylize: stylizeNoColor +- }; +- // legacy... +- if (arguments.length >= 3) ctx.depth = arguments[2]; +- if (arguments.length >= 4) ctx.colors = arguments[3]; +- if (isBoolean(opts)) { +- // legacy... +- ctx.showHidden = opts; +- } else if (opts) { +- // got an "options" object +- exports._extend(ctx, opts); +- } +- // set default options +- if (isUndefined(ctx.showHidden)) ctx.showHidden = false; +- if (isUndefined(ctx.depth)) ctx.depth = 2; +- if (isUndefined(ctx.colors)) ctx.colors = false; +- if (isUndefined(ctx.customInspect)) ctx.customInspect = true; +- if (ctx.colors) ctx.stylize = stylizeWithColor; +- return formatValue(ctx, obj, ctx.depth); +-} +-exports.inspect = inspect; +- +- +-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +-inspect.colors = { +- 'bold' : [1, 22], +- 'italic' : [3, 23], +- 'underline' : [4, 24], +- 'inverse' : [7, 27], +- 'white' : [37, 39], +- 'grey' : [90, 39], +- 'black' : [30, 39], +- 'blue' : [34, 39], +- 'cyan' : [36, 39], +- 'green' : [32, 39], +- 'magenta' : [35, 39], +- 'red' : [31, 39], +- 'yellow' : [33, 39] +-}; +- +-// Don't use 'blue' not visible on cmd.exe +-inspect.styles = { +- 'special': 'cyan', +- 'number': 'yellow', +- 'boolean': 'yellow', +- 'undefined': 'grey', +- 'null': 'bold', +- 'string': 'green', +- 'date': 'magenta', +- // "name": intentionally not styling +- 'regexp': 'red' +-}; +- +- +-function stylizeWithColor(str, styleType) { +- var style = inspect.styles[styleType]; +- +- if (style) { +- return '\u001b[' + inspect.colors[style][0] + 'm' + str + +- '\u001b[' + inspect.colors[style][1] + 'm'; +- } else { +- return str; +- } +-} +- +- +-function stylizeNoColor(str, styleType) { +- return str; +-} +- +- +-function arrayToHash(array) { +- var hash = {}; +- +- array.forEach(function(val, idx) { +- hash[val] = true; +- }); +- +- return hash; +-} +- +- +-function formatValue(ctx, value, recurseTimes) { +- // Provide a hook for user-specified inspect functions. +- // Check that value is an object with an inspect function on it +- if (ctx.customInspect && +- value && +- isFunction(value.inspect) && +- // Filter out the util module, it's inspect function is special +- value.inspect !== exports.inspect && +- // Also filter out any prototype objects using the circular check. +- !(value.constructor && value.constructor.prototype === value)) { +- var ret = value.inspect(recurseTimes, ctx); +- if (!isString(ret)) { +- ret = formatValue(ctx, ret, recurseTimes); +- } +- return ret; +- } +- +- // Primitive types cannot have properties +- var primitive = formatPrimitive(ctx, value); +- if (primitive) { +- return primitive; +- } +- +- // Look up the keys of the object. +- var keys = Object.keys(value); +- var visibleKeys = arrayToHash(keys); +- +- if (ctx.showHidden) { +- keys = Object.getOwnPropertyNames(value); +- } +- +- // Some type of object without properties can be shortcutted. +- if (keys.length === 0) { +- if (isFunction(value)) { +- var name = value.name ? ': ' + value.name : ''; +- return ctx.stylize('[Function' + name + ']', 'special'); +- } +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } +- if (isDate(value)) { +- return ctx.stylize(Date.prototype.toString.call(value), 'date'); +- } +- if (isError(value)) { +- return formatError(value); +- } +- } +- +- var base = '', array = false, braces = ['{', '}']; +- +- // Make Array say that they are Array +- if (isArray(value)) { +- array = true; +- braces = ['[', ']']; +- } +- +- // Make functions say that they are functions +- if (isFunction(value)) { +- var n = value.name ? ': ' + value.name : ''; +- base = ' [Function' + n + ']'; +- } +- +- // Make RegExps say that they are RegExps +- if (isRegExp(value)) { +- base = ' ' + RegExp.prototype.toString.call(value); +- } +- +- // Make dates with properties first say the date +- if (isDate(value)) { +- base = ' ' + Date.prototype.toUTCString.call(value); +- } +- +- // Make error with message first say the error +- if (isError(value)) { +- base = ' ' + formatError(value); +- } +- +- if (keys.length === 0 && (!array || value.length == 0)) { +- return braces[0] + base + braces[1]; +- } +- +- if (recurseTimes < 0) { +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } else { +- return ctx.stylize('[Object]', 'special'); +- } +- } +- +- ctx.seen.push(value); +- +- var output; +- if (array) { +- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); +- } else { +- output = keys.map(function(key) { +- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); +- }); +- } +- +- ctx.seen.pop(); +- +- return reduceToSingleString(output, base, braces); +-} +- +- +-function formatPrimitive(ctx, value) { +- if (isUndefined(value)) +- return ctx.stylize('undefined', 'undefined'); +- if (isString(value)) { +- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') +- .replace(/'/g, "\\'") +- .replace(/\\"/g, '"') + '\''; +- return ctx.stylize(simple, 'string'); +- } +- if (isNumber(value)) { +- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, +- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . +- if (value === 0 && 1 / value < 0) +- return ctx.stylize('-0', 'number'); +- return ctx.stylize('' + value, 'number'); +- } +- if (isBoolean(value)) +- return ctx.stylize('' + value, 'boolean'); +- // For some reason typeof null is "object", so special case here. +- if (isNull(value)) +- return ctx.stylize('null', 'null'); +-} +- +- +-function formatError(value) { +- return '[' + Error.prototype.toString.call(value) + ']'; +-} +- +- +-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { +- var output = []; +- for (var i = 0, l = value.length; i < l; ++i) { +- if (hasOwnProperty(value, String(i))) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- String(i), true)); +- } else { +- output.push(''); +- } +- } +- keys.forEach(function(key) { +- if (!key.match(/^\d+$/)) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- key, true)); +- } +- }); +- return output; +-} +- +- +-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { +- var name, str, desc; +- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; +- if (desc.get) { +- if (desc.set) { +- str = ctx.stylize('[Getter/Setter]', 'special'); +- } else { +- str = ctx.stylize('[Getter]', 'special'); +- } +- } else { +- if (desc.set) { +- str = ctx.stylize('[Setter]', 'special'); +- } +- } +- if (!hasOwnProperty(visibleKeys, key)) { +- name = '[' + key + ']'; +- } +- if (!str) { +- if (ctx.seen.indexOf(desc.value) < 0) { +- if (isNull(recurseTimes)) { +- str = formatValue(ctx, desc.value, null); +- } else { +- str = formatValue(ctx, desc.value, recurseTimes - 1); +- } +- if (str.indexOf('\n') > -1) { +- if (array) { +- str = str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n').substr(2); +- } else { +- str = '\n' + str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n'); +- } +- } +- } else { +- str = ctx.stylize('[Circular]', 'special'); +- } +- } +- if (isUndefined(name)) { +- if (array && key.match(/^\d+$/)) { +- return str; +- } +- name = JSON.stringify('' + key); +- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { +- name = name.substr(1, name.length - 2); +- name = ctx.stylize(name, 'name'); +- } else { +- name = name.replace(/'/g, "\\'") +- .replace(/\\"/g, '"') +- .replace(/(^"|"$)/g, "'"); +- name = ctx.stylize(name, 'string'); +- } +- } +- +- return name + ': ' + str; +-} +- +- +-function reduceToSingleString(output, base, braces) { +- var numLinesEst = 0; +- var length = output.reduce(function(prev, cur) { +- numLinesEst++; +- if (cur.indexOf('\n') >= 0) numLinesEst++; +- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; +- }, 0); +- +- if (length > 60) { +- return braces[0] + +- (base === '' ? '' : base + '\n ') + +- ' ' + +- output.join(',\n ') + +- ' ' + +- braces[1]; +- } +- +- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +-} +- +- + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { +@@ -522,166 +98,10 @@ function isPrimitive(arg) { + exports.isPrimitive = isPrimitive; + + function isBuffer(arg) { +- return arg instanceof Buffer; ++ return Buffer.isBuffer(arg); + } + exports.isBuffer = isBuffer; + + function objectToString(o) { + return Object.prototype.toString.call(o); +-} +- +- +-function pad(n) { +- return n < 10 ? '0' + n.toString(10) : n.toString(10); +-} +- +- +-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', +- 'Oct', 'Nov', 'Dec']; +- +-// 26 Feb 16:19:34 +-function timestamp() { +- var d = new Date(); +- var time = [pad(d.getHours()), +- pad(d.getMinutes()), +- pad(d.getSeconds())].join(':'); +- return [d.getDate(), months[d.getMonth()], time].join(' '); +-} +- +- +-// log is just a thin wrapper to console.log that prepends a timestamp +-exports.log = function() { +- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +-}; +- +- +-/** +- * Inherit the prototype methods from one constructor into another. +- * +- * The Function.prototype.inherits from lang.js rewritten as a standalone +- * function (not on Function.prototype). NOTE: If this file is to be loaded +- * during bootstrapping this function needs to be rewritten using some native +- * functions as prototype setup using normal JavaScript does not work as +- * expected during bootstrapping (see mirror.js in r114903). +- * +- * @param {function} ctor Constructor function which needs to inherit the +- * prototype. +- * @param {function} superCtor Constructor function to inherit prototype from. +- */ +-exports.inherits = function(ctor, superCtor) { +- ctor.super_ = superCtor; +- ctor.prototype = Object.create(superCtor.prototype, { +- constructor: { +- value: ctor, +- enumerable: false, +- writable: true, +- configurable: true +- } +- }); +-}; +- +-exports._extend = function(origin, add) { +- // Don't do anything if add isn't an object +- if (!add || !isObject(add)) return origin; +- +- var keys = Object.keys(add); +- var i = keys.length; +- while (i--) { +- origin[keys[i]] = add[keys[i]]; +- } +- return origin; +-}; +- +-function hasOwnProperty(obj, prop) { +- return Object.prototype.hasOwnProperty.call(obj, prop); +-} +- +- +-// Deprecated old stuff. +- +-exports.p = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- console.error(exports.inspect(arguments[i])); +- } +-}, 'util.p: Use console.error() instead'); +- +- +-exports.exec = exports.deprecate(function() { +- return require('child_process').exec.apply(this, arguments); +-}, 'util.exec is now called `child_process.exec`.'); +- +- +-exports.print = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(String(arguments[i])); +- } +-}, 'util.print: Use console.log instead'); +- +- +-exports.puts = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(arguments[i] + '\n'); +- } +-}, 'util.puts: Use console.log instead'); +- +- +-exports.debug = exports.deprecate(function(x) { +- process.stderr.write('DEBUG: ' + x + '\n'); +-}, 'util.debug: Use console.error instead'); +- +- +-exports.error = exports.deprecate(function(x) { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stderr.write(arguments[i] + '\n'); +- } +-}, 'util.error: Use console.error instead'); +- +- +-exports.pump = exports.deprecate(function(readStream, writeStream, callback) { +- var callbackCalled = false; +- +- function call(a, b, c) { +- if (callback && !callbackCalled) { +- callback(a, b, c); +- callbackCalled = true; +- } +- } +- +- readStream.addListener('data', function(chunk) { +- if (writeStream.write(chunk) === false) readStream.pause(); +- }); +- +- writeStream.addListener('drain', function() { +- readStream.resume(); +- }); +- +- readStream.addListener('end', function() { +- writeStream.end(); +- }); +- +- readStream.addListener('close', function() { +- call(); +- }); +- +- readStream.addListener('error', function(err) { +- writeStream.end(); +- call(err); +- }); +- +- writeStream.addListener('error', function(err) { +- readStream.destroy(); +- call(err); +- }); +-}, 'util.pump(): Use readableStream.pipe() instead'); +- +- +-var uv; +-exports._errnoException = function(err, syscall) { +- if (isUndefined(uv)) uv = process.binding('uv'); +- var errname = uv.errname(err); +- var e = new Error(syscall + ' ' + errname); +- e.code = errname; +- e.errno = errname; +- e.syscall = syscall; +- return e; +-}; ++} \ No newline at end of file diff --git a/node_modules/core-util-is/lib/util.js b/node_modules/core-util-is/lib/util.js new file mode 100644 index 0000000..ff4c851 --- /dev/null +++ b/node_modules/core-util-is/lib/util.js @@ -0,0 +1,107 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/node_modules/core-util-is/package.json b/node_modules/core-util-is/package.json new file mode 100644 index 0000000..3368e95 --- /dev/null +++ b/node_modules/core-util-is/package.json @@ -0,0 +1,32 @@ +{ + "name": "core-util-is", + "version": "1.0.2", + "description": "The `util.is*` functions introduced in Node v0.12.", + "main": "lib/util.js", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/core-util-is" + }, + "keywords": [ + "util", + "isBuffer", + "isArray", + "isNumber", + "isString", + "isRegExp", + "isThis", + "isThat", + "polyfill" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "MIT", + "bugs": { + "url": "https://github.com/isaacs/core-util-is/issues" + }, + "scripts": { + "test": "tap test.js" + }, + "devDependencies": { + "tap": "^2.3.0" + } +} diff --git a/node_modules/core-util-is/test.js b/node_modules/core-util-is/test.js new file mode 100644 index 0000000..1a490c6 --- /dev/null +++ b/node_modules/core-util-is/test.js @@ -0,0 +1,68 @@ +var assert = require('tap'); + +var t = require('./lib/util'); + +assert.equal(t.isArray([]), true); +assert.equal(t.isArray({}), false); + +assert.equal(t.isBoolean(null), false); +assert.equal(t.isBoolean(true), true); +assert.equal(t.isBoolean(false), true); + +assert.equal(t.isNull(null), true); +assert.equal(t.isNull(undefined), false); +assert.equal(t.isNull(false), false); +assert.equal(t.isNull(), false); + +assert.equal(t.isNullOrUndefined(null), true); +assert.equal(t.isNullOrUndefined(undefined), true); +assert.equal(t.isNullOrUndefined(false), false); +assert.equal(t.isNullOrUndefined(), true); + +assert.equal(t.isNumber(null), false); +assert.equal(t.isNumber('1'), false); +assert.equal(t.isNumber(1), true); + +assert.equal(t.isString(null), false); +assert.equal(t.isString('1'), true); +assert.equal(t.isString(1), false); + +assert.equal(t.isSymbol(null), false); +assert.equal(t.isSymbol('1'), false); +assert.equal(t.isSymbol(1), false); +assert.equal(t.isSymbol(Symbol()), true); + +assert.equal(t.isUndefined(null), false); +assert.equal(t.isUndefined(undefined), true); +assert.equal(t.isUndefined(false), false); +assert.equal(t.isUndefined(), true); + +assert.equal(t.isRegExp(null), false); +assert.equal(t.isRegExp('1'), false); +assert.equal(t.isRegExp(new RegExp()), true); + +assert.equal(t.isObject({}), true); +assert.equal(t.isObject([]), true); +assert.equal(t.isObject(new RegExp()), true); +assert.equal(t.isObject(new Date()), true); + +assert.equal(t.isDate(null), false); +assert.equal(t.isDate('1'), false); +assert.equal(t.isDate(new Date()), true); + +assert.equal(t.isError(null), false); +assert.equal(t.isError({ err: true }), false); +assert.equal(t.isError(new Error()), true); + +assert.equal(t.isFunction(null), false); +assert.equal(t.isFunction({ }), false); +assert.equal(t.isFunction(function() {}), true); + +assert.equal(t.isPrimitive(null), true); +assert.equal(t.isPrimitive(''), true); +assert.equal(t.isPrimitive(0), true); +assert.equal(t.isPrimitive(new Date()), false); + +assert.equal(t.isBuffer(null), false); +assert.equal(t.isBuffer({}), false); +assert.equal(t.isBuffer(new Buffer(0)), true); diff --git a/node_modules/delayed-stream/.npmignore b/node_modules/delayed-stream/.npmignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/node_modules/delayed-stream/.npmignore @@ -0,0 +1 @@ +test diff --git a/node_modules/delayed-stream/License b/node_modules/delayed-stream/License new file mode 100644 index 0000000..4804b7a --- /dev/null +++ b/node_modules/delayed-stream/License @@ -0,0 +1,19 @@ +Copyright (c) 2011 Debuggable Limited + +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. diff --git a/node_modules/delayed-stream/Makefile b/node_modules/delayed-stream/Makefile new file mode 100644 index 0000000..b4ff85a --- /dev/null +++ b/node_modules/delayed-stream/Makefile @@ -0,0 +1,7 @@ +SHELL := /bin/bash + +test: + @./test/run.js + +.PHONY: test + diff --git a/node_modules/delayed-stream/Readme.md b/node_modules/delayed-stream/Readme.md new file mode 100644 index 0000000..aca36f9 --- /dev/null +++ b/node_modules/delayed-stream/Readme.md @@ -0,0 +1,141 @@ +# delayed-stream + +Buffers events from a stream until you are ready to handle them. + +## Installation + +``` bash +npm install delayed-stream +``` + +## Usage + +The following example shows how to write a http echo server that delays its +response by 1000 ms. + +``` javascript +var DelayedStream = require('delayed-stream'); +var http = require('http'); + +http.createServer(function(req, res) { + var delayed = DelayedStream.create(req); + + setTimeout(function() { + res.writeHead(200); + delayed.pipe(res); + }, 1000); +}); +``` + +If you are not using `Stream#pipe`, you can also manually release the buffered +events by calling `delayedStream.resume()`: + +``` javascript +var delayed = DelayedStream.create(req); + +setTimeout(function() { + // Emit all buffered events and resume underlaying source + delayed.resume(); +}, 1000); +``` + +## Implementation + +In order to use this meta stream properly, here are a few things you should +know about the implementation. + +### Event Buffering / Proxying + +All events of the `source` stream are hijacked by overwriting the `source.emit` +method. Until node implements a catch-all event listener, this is the only way. + +However, delayed-stream still continues to emit all events it captures on the +`source`, regardless of whether you have released the delayed stream yet or +not. + +Upon creation, delayed-stream captures all `source` events and stores them in +an internal event buffer. Once `delayedStream.release()` is called, all +buffered events are emitted on the `delayedStream`, and the event buffer is +cleared. After that, delayed-stream merely acts as a proxy for the underlaying +source. + +### Error handling + +Error events on `source` are buffered / proxied just like any other events. +However, `delayedStream.create` attaches a no-op `'error'` listener to the +`source`. This way you only have to handle errors on the `delayedStream` +object, rather than in two places. + +### Buffer limits + +delayed-stream provides a `maxDataSize` property that can be used to limit +the amount of data being buffered. In order to protect you from bad `source` +streams that don't react to `source.pause()`, this feature is enabled by +default. + +## API + +### DelayedStream.create(source, [options]) + +Returns a new `delayedStream`. Available options are: + +* `pauseStream` +* `maxDataSize` + +The description for those properties can be found below. + +### delayedStream.source + +The `source` stream managed by this object. This is useful if you are +passing your `delayedStream` around, and you still want to access properties +on the `source` object. + +### delayedStream.pauseStream = true + +Whether to pause the underlaying `source` when calling +`DelayedStream.create()`. Modifying this property afterwards has no effect. + +### delayedStream.maxDataSize = 1024 * 1024 + +The amount of data to buffer before emitting an `error`. + +If the underlaying source is emitting `Buffer` objects, the `maxDataSize` +refers to bytes. + +If the underlaying source is emitting JavaScript strings, the size refers to +characters. + +If you know what you are doing, you can set this property to `Infinity` to +disable this feature. You can also modify this property during runtime. + +### delayedStream.dataSize = 0 + +The amount of data buffered so far. + +### delayedStream.readable + +An ECMA5 getter that returns the value of `source.readable`. + +### delayedStream.resume() + +If the `delayedStream` has not been released so far, `delayedStream.release()` +is called. + +In either case, `source.resume()` is called. + +### delayedStream.pause() + +Calls `source.pause()`. + +### delayedStream.pipe(dest) + +Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`. + +### delayedStream.release() + +Emits and clears all events that have been buffered up so far. This does not +resume the underlaying source, use `delayedStream.resume()` instead. + +## License + +delayed-stream is licensed under the MIT license. diff --git a/node_modules/delayed-stream/lib/delayed_stream.js b/node_modules/delayed-stream/lib/delayed_stream.js new file mode 100644 index 0000000..b38fc85 --- /dev/null +++ b/node_modules/delayed-stream/lib/delayed_stream.js @@ -0,0 +1,107 @@ +var Stream = require('stream').Stream; +var util = require('util'); + +module.exports = DelayedStream; +function DelayedStream() { + this.source = null; + this.dataSize = 0; + this.maxDataSize = 1024 * 1024; + this.pauseStream = true; + + this._maxDataSizeExceeded = false; + this._released = false; + this._bufferedEvents = []; +} +util.inherits(DelayedStream, Stream); + +DelayedStream.create = function(source, options) { + var delayedStream = new this(); + + options = options || {}; + for (var option in options) { + delayedStream[option] = options[option]; + } + + delayedStream.source = source; + + var realEmit = source.emit; + source.emit = function() { + delayedStream._handleEmit(arguments); + return realEmit.apply(source, arguments); + }; + + source.on('error', function() {}); + if (delayedStream.pauseStream) { + source.pause(); + } + + return delayedStream; +}; + +Object.defineProperty(DelayedStream.prototype, 'readable', { + configurable: true, + enumerable: true, + get: function() { + return this.source.readable; + } +}); + +DelayedStream.prototype.setEncoding = function() { + return this.source.setEncoding.apply(this.source, arguments); +}; + +DelayedStream.prototype.resume = function() { + if (!this._released) { + this.release(); + } + + this.source.resume(); +}; + +DelayedStream.prototype.pause = function() { + this.source.pause(); +}; + +DelayedStream.prototype.release = function() { + this._released = true; + + this._bufferedEvents.forEach(function(args) { + this.emit.apply(this, args); + }.bind(this)); + this._bufferedEvents = []; +}; + +DelayedStream.prototype.pipe = function() { + var r = Stream.prototype.pipe.apply(this, arguments); + this.resume(); + return r; +}; + +DelayedStream.prototype._handleEmit = function(args) { + if (this._released) { + this.emit.apply(this, args); + return; + } + + if (args[0] === 'data') { + this.dataSize += args[1].length; + this._checkIfMaxDataSizeExceeded(); + } + + this._bufferedEvents.push(args); +}; + +DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() { + if (this._maxDataSizeExceeded) { + return; + } + + if (this.dataSize <= this.maxDataSize) { + return; + } + + this._maxDataSizeExceeded = true; + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.' + this.emit('error', new Error(message)); +}; diff --git a/node_modules/delayed-stream/package.json b/node_modules/delayed-stream/package.json new file mode 100644 index 0000000..eea3291 --- /dev/null +++ b/node_modules/delayed-stream/package.json @@ -0,0 +1,27 @@ +{ + "author": "Felix Geisendörfer (http://debuggable.com/)", + "contributors": [ + "Mike Atkins " + ], + "name": "delayed-stream", + "description": "Buffers events from a stream until you are ready to handle them.", + "license": "MIT", + "version": "1.0.0", + "homepage": "https://github.com/felixge/node-delayed-stream", + "repository": { + "type": "git", + "url": "git://github.com/felixge/node-delayed-stream.git" + }, + "main": "./lib/delayed_stream", + "engines": { + "node": ">=0.4.0" + }, + "scripts": { + "test": "make test" + }, + "dependencies": {}, + "devDependencies": { + "fake": "0.2.0", + "far": "0.0.1" + } +} diff --git a/node_modules/dunder-proto/.eslintrc b/node_modules/dunder-proto/.eslintrc new file mode 100644 index 0000000..3b5d9e9 --- /dev/null +++ b/node_modules/dunder-proto/.eslintrc @@ -0,0 +1,5 @@ +{ + "root": true, + + "extends": "@ljharb", +} diff --git a/node_modules/dunder-proto/.github/FUNDING.yml b/node_modules/dunder-proto/.github/FUNDING.yml new file mode 100644 index 0000000..8a1d7b0 --- /dev/null +++ b/node_modules/dunder-proto/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/dunder-proto +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/dunder-proto/.nycrc b/node_modules/dunder-proto/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/dunder-proto/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/dunder-proto/CHANGELOG.md b/node_modules/dunder-proto/CHANGELOG.md new file mode 100644 index 0000000..9b8b2f8 --- /dev/null +++ b/node_modules/dunder-proto/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.1](https://github.com/es-shims/dunder-proto/compare/v1.0.0...v1.0.1) - 2024-12-16 + +### Commits + +- [Fix] do not crash when `--disable-proto=throw` [`6c367d9`](https://github.com/es-shims/dunder-proto/commit/6c367d919bc1604778689a297bbdbfea65752847) +- [Tests] ensure noproto tests only use the current version of dunder-proto [`b02365b`](https://github.com/es-shims/dunder-proto/commit/b02365b9cf889c4a2cac7be0c3cfc90a789af36c) +- [Dev Deps] update `@arethetypeswrong/cli`, `@types/tape` [`e3c5c3b`](https://github.com/es-shims/dunder-proto/commit/e3c5c3bd81cf8cef7dff2eca19e558f0e307f666) +- [Deps] update `call-bind-apply-helpers` [`19f1da0`](https://github.com/es-shims/dunder-proto/commit/19f1da028b8dd0d05c85bfd8f7eed2819b686450) + +## v1.0.0 - 2024-12-06 + +### Commits + +- Initial implementation, tests, readme, types [`a5b74b0`](https://github.com/es-shims/dunder-proto/commit/a5b74b0082f5270cb0905cd9a2e533cee7498373) +- Initial commit [`73fb5a3`](https://github.com/es-shims/dunder-proto/commit/73fb5a353b51ac2ab00c9fdeb0114daffd4c07a8) +- npm init [`80152dc`](https://github.com/es-shims/dunder-proto/commit/80152dc98155da4eb046d9f67a87ed96e8280a1d) +- Only apps should have lockfiles [`03e6660`](https://github.com/es-shims/dunder-proto/commit/03e6660a1d70dc401f3e217a031475ec537243dd) diff --git a/node_modules/dunder-proto/LICENSE b/node_modules/dunder-proto/LICENSE new file mode 100644 index 0000000..34995e7 --- /dev/null +++ b/node_modules/dunder-proto/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ECMAScript Shims + +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. diff --git a/node_modules/dunder-proto/README.md b/node_modules/dunder-proto/README.md new file mode 100644 index 0000000..44b80a2 --- /dev/null +++ b/node_modules/dunder-proto/README.md @@ -0,0 +1,54 @@ +# dunder-proto [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +If available, the `Object.prototype.__proto__` accessor and mutator, call-bound. + +## Getting started + +```sh +npm install --save dunder-proto +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getDunder = require('dunder-proto/get'); +const setDunder = require('dunder-proto/set'); + +const obj = {}; + +assert.equal('toString' in obj, true); +assert.equal(getDunder(obj), Object.prototype); + +setDunder(obj, null); + +assert.equal('toString' in obj, false); +assert.equal(getDunder(obj), null); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/dunder-proto +[npm-version-svg]: https://versionbadg.es/es-shims/dunder-proto.svg +[deps-svg]: https://david-dm.org/es-shims/dunder-proto.svg +[deps-url]: https://david-dm.org/es-shims/dunder-proto +[dev-deps-svg]: https://david-dm.org/es-shims/dunder-proto/dev-status.svg +[dev-deps-url]: https://david-dm.org/es-shims/dunder-proto#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/dunder-proto.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/dunder-proto.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/dunder-proto.svg +[downloads-url]: https://npm-stat.com/charts.html?package=dunder-proto +[codecov-image]: https://codecov.io/gh/es-shims/dunder-proto/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/es-shims/dunder-proto/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/dunder-proto +[actions-url]: https://github.com/es-shims/dunder-proto/actions diff --git a/node_modules/dunder-proto/get.d.ts b/node_modules/dunder-proto/get.d.ts new file mode 100644 index 0000000..c7e14d2 --- /dev/null +++ b/node_modules/dunder-proto/get.d.ts @@ -0,0 +1,5 @@ +declare function getDunderProto(target: {}): object | null; + +declare const x: false | typeof getDunderProto; + +export = x; \ No newline at end of file diff --git a/node_modules/dunder-proto/get.js b/node_modules/dunder-proto/get.js new file mode 100644 index 0000000..45093df --- /dev/null +++ b/node_modules/dunder-proto/get.js @@ -0,0 +1,30 @@ +'use strict'; + +var callBind = require('call-bind-apply-helpers'); +var gOPD = require('gopd'); + +var hasProtoAccessor; +try { + // eslint-disable-next-line no-extra-parens, no-proto + hasProtoAccessor = /** @type {{ __proto__?: typeof Array.prototype }} */ ([]).__proto__ === Array.prototype; +} catch (e) { + if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') { + throw e; + } +} + +// eslint-disable-next-line no-extra-parens +var desc = !!hasProtoAccessor && gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__')); + +var $Object = Object; +var $getPrototypeOf = $Object.getPrototypeOf; + +/** @type {import('./get')} */ +module.exports = desc && typeof desc.get === 'function' + ? callBind([desc.get]) + : typeof $getPrototypeOf === 'function' + ? /** @type {import('./get')} */ function getDunder(value) { + // eslint-disable-next-line eqeqeq + return $getPrototypeOf(value == null ? value : $Object(value)); + } + : false; diff --git a/node_modules/dunder-proto/package.json b/node_modules/dunder-proto/package.json new file mode 100644 index 0000000..04a4036 --- /dev/null +++ b/node_modules/dunder-proto/package.json @@ -0,0 +1,76 @@ +{ + "name": "dunder-proto", + "version": "1.0.1", + "description": "If available, the `Object.prototype.__proto__` accessor and mutator, call-bound", + "main": false, + "exports": { + "./get": "./get.js", + "./set": "./set.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "prelint": "evalmd README.md", + "lint": "eslint --ext=.js,.mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>= 10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/es-shims/dunder-proto.git" + }, + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/es-shims/dunder-proto/issues" + }, + "homepage": "https://github.com/es-shims/dunder-proto#readme", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/tape": "^5.7.0", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "testling": { + "files": "test/index.js" + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/dunder-proto/set.d.ts b/node_modules/dunder-proto/set.d.ts new file mode 100644 index 0000000..16bfdfe --- /dev/null +++ b/node_modules/dunder-proto/set.d.ts @@ -0,0 +1,5 @@ +declare function setDunderProto

(target: {}, proto: P): P; + +declare const x: false | typeof setDunderProto; + +export = x; \ No newline at end of file diff --git a/node_modules/dunder-proto/set.js b/node_modules/dunder-proto/set.js new file mode 100644 index 0000000..6085b6e --- /dev/null +++ b/node_modules/dunder-proto/set.js @@ -0,0 +1,35 @@ +'use strict'; + +var callBind = require('call-bind-apply-helpers'); +var gOPD = require('gopd'); +var $TypeError = require('es-errors/type'); + +/** @type {{ __proto__?: object | null }} */ +var obj = {}; +try { + obj.__proto__ = null; // eslint-disable-line no-proto +} catch (e) { + if (!e || typeof e !== 'object' || !('code' in e) || e.code !== 'ERR_PROTO_ACCESS') { + throw e; + } +} + +var hasProtoMutator = !('toString' in obj); + +// eslint-disable-next-line no-extra-parens +var desc = gOPD && gOPD(Object.prototype, /** @type {keyof typeof Object.prototype} */ ('__proto__')); + +/** @type {import('./set')} */ +module.exports = hasProtoMutator && ( +// eslint-disable-next-line no-extra-parens + (!!desc && typeof desc.set === 'function' && /** @type {import('./set')} */ (callBind([desc.set]))) + || /** @type {import('./set')} */ function setDunder(object, proto) { + // this is node v0.10 or older, which doesn't have Object.setPrototypeOf and has undeniable __proto__ + if (object == null) { // eslint-disable-line eqeqeq + throw new $TypeError('set Object.prototype.__proto__ called on null or undefined'); + } + // eslint-disable-next-line no-proto, no-param-reassign, no-extra-parens + /** @type {{ __proto__?: object | null }} */ (object).__proto__ = proto; + return proto; + } +); diff --git a/node_modules/dunder-proto/test/get.js b/node_modules/dunder-proto/test/get.js new file mode 100644 index 0000000..253f183 --- /dev/null +++ b/node_modules/dunder-proto/test/get.js @@ -0,0 +1,34 @@ +'use strict'; + +var test = require('tape'); + +var getDunderProto = require('../get'); + +test('getDunderProto', { skip: !getDunderProto }, function (t) { + if (!getDunderProto) { + throw 'should never happen; this is just for type narrowing'; // eslint-disable-line no-throw-literal + } + + // @ts-expect-error + t['throws'](function () { getDunderProto(); }, TypeError, 'throws if no argument'); + // @ts-expect-error + t['throws'](function () { getDunderProto(undefined); }, TypeError, 'throws with undefined'); + // @ts-expect-error + t['throws'](function () { getDunderProto(null); }, TypeError, 'throws with null'); + + t.equal(getDunderProto({}), Object.prototype); + t.equal(getDunderProto([]), Array.prototype); + t.equal(getDunderProto(function () {}), Function.prototype); + t.equal(getDunderProto(/./g), RegExp.prototype); + t.equal(getDunderProto(42), Number.prototype); + t.equal(getDunderProto(true), Boolean.prototype); + t.equal(getDunderProto('foo'), String.prototype); + + t.end(); +}); + +test('no dunder proto', { skip: !!getDunderProto }, function (t) { + t.notOk('__proto__' in Object.prototype, 'no __proto__ in Object.prototype'); + + t.end(); +}); diff --git a/node_modules/dunder-proto/test/index.js b/node_modules/dunder-proto/test/index.js new file mode 100644 index 0000000..08ff36f --- /dev/null +++ b/node_modules/dunder-proto/test/index.js @@ -0,0 +1,4 @@ +'use strict'; + +require('./get'); +require('./set'); diff --git a/node_modules/dunder-proto/test/set.js b/node_modules/dunder-proto/test/set.js new file mode 100644 index 0000000..c3bfe4d --- /dev/null +++ b/node_modules/dunder-proto/test/set.js @@ -0,0 +1,50 @@ +'use strict'; + +var test = require('tape'); + +var setDunderProto = require('../set'); + +test('setDunderProto', { skip: !setDunderProto }, function (t) { + if (!setDunderProto) { + throw 'should never happen; this is just for type narrowing'; // eslint-disable-line no-throw-literal + } + + // @ts-expect-error + t['throws'](function () { setDunderProto(); }, TypeError, 'throws if no arguments'); + // @ts-expect-error + t['throws'](function () { setDunderProto(undefined); }, TypeError, 'throws with undefined and nothing'); + // @ts-expect-error + t['throws'](function () { setDunderProto(undefined, undefined); }, TypeError, 'throws with undefined and undefined'); + // @ts-expect-error + t['throws'](function () { setDunderProto(null); }, TypeError, 'throws with null and undefined'); + // @ts-expect-error + t['throws'](function () { setDunderProto(null, undefined); }, TypeError, 'throws with null and undefined'); + + /** @type {{ inherited?: boolean }} */ + var obj = {}; + t.ok('toString' in obj, 'object initially has toString'); + + setDunderProto(obj, null); + t.notOk('toString' in obj, 'object no longer has toString'); + + t.notOk('inherited' in obj, 'object lacks inherited property'); + setDunderProto(obj, { inherited: true }); + t.equal(obj.inherited, true, 'object has inherited property'); + + t.end(); +}); + +test('no dunder proto', { skip: !!setDunderProto }, function (t) { + if ('__proto__' in Object.prototype) { + t['throws']( + // @ts-expect-error + function () { ({}).__proto__ = null; }, // eslint-disable-line no-proto + Error, + 'throws when setting Object.prototype.__proto__' + ); + } else { + t.notOk('__proto__' in Object.prototype, 'no __proto__ in Object.prototype'); + } + + t.end(); +}); diff --git a/node_modules/dunder-proto/tsconfig.json b/node_modules/dunder-proto/tsconfig.json new file mode 100644 index 0000000..dabbe23 --- /dev/null +++ b/node_modules/dunder-proto/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "ES2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/es-define-property/.eslintrc b/node_modules/es-define-property/.eslintrc new file mode 100644 index 0000000..46f3b12 --- /dev/null +++ b/node_modules/es-define-property/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "new-cap": ["error", { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + }, +} diff --git a/node_modules/es-define-property/.github/FUNDING.yml b/node_modules/es-define-property/.github/FUNDING.yml new file mode 100644 index 0000000..4445451 --- /dev/null +++ b/node_modules/es-define-property/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/es-define-property +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with a single custom sponsorship URL diff --git a/node_modules/es-define-property/.nycrc b/node_modules/es-define-property/.nycrc new file mode 100644 index 0000000..bdd626c --- /dev/null +++ b/node_modules/es-define-property/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/es-define-property/CHANGELOG.md b/node_modules/es-define-property/CHANGELOG.md new file mode 100644 index 0000000..5f60cc0 --- /dev/null +++ b/node_modules/es-define-property/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.1](https://github.com/ljharb/es-define-property/compare/v1.0.0...v1.0.1) - 2024-12-06 + +### Commits + +- [types] use shared tsconfig [`954a663`](https://github.com/ljharb/es-define-property/commit/954a66360326e508a0e5daa4b07493d58f5e110e) +- [actions] split out node 10-20, and 20+ [`3a8e84b`](https://github.com/ljharb/es-define-property/commit/3a8e84b23883f26ff37b3e82ff283834228e18c6) +- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/get-intrinsic`, `@types/tape`, `auto-changelog`, `gopd`, `tape` [`86ae27b`](https://github.com/ljharb/es-define-property/commit/86ae27bb8cc857b23885136fad9cbe965ae36612) +- [Refactor] avoid using `get-intrinsic` [`02480c0`](https://github.com/ljharb/es-define-property/commit/02480c0353ef6118965282977c3864aff53d98b1) +- [Tests] replace `aud` with `npm audit` [`f6093ff`](https://github.com/ljharb/es-define-property/commit/f6093ff74ab51c98015c2592cd393bd42478e773) +- [Tests] configure testling [`7139e66`](https://github.com/ljharb/es-define-property/commit/7139e66959247a56086d9977359caef27c6849e7) +- [Dev Deps] update `tape` [`b901b51`](https://github.com/ljharb/es-define-property/commit/b901b511a75e001a40ce1a59fef7d9ffcfc87482) +- [Tests] fix types in tests [`469d269`](https://github.com/ljharb/es-define-property/commit/469d269fd141b1e773ec053a9fa35843493583e0) +- [Dev Deps] add missing peer dep [`733acfb`](https://github.com/ljharb/es-define-property/commit/733acfb0c4c96edf337e470b89a25a5b3724c352) + +## v1.0.0 - 2024-02-12 + +### Commits + +- Initial implementation, tests, readme, types [`3e154e1`](https://github.com/ljharb/es-define-property/commit/3e154e11a2fee09127220f5e503bf2c0a31dd480) +- Initial commit [`07d98de`](https://github.com/ljharb/es-define-property/commit/07d98de34a4dc31ff5e83a37c0c3f49e0d85cd50) +- npm init [`c4eb634`](https://github.com/ljharb/es-define-property/commit/c4eb6348b0d3886aac36cef34ad2ee0665ea6f3e) +- Only apps should have lockfiles [`7af86ec`](https://github.com/ljharb/es-define-property/commit/7af86ec1d311ec0b17fdfe616a25f64276903856) diff --git a/node_modules/es-define-property/LICENSE b/node_modules/es-define-property/LICENSE new file mode 100644 index 0000000..f82f389 --- /dev/null +++ b/node_modules/es-define-property/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jordan Harband + +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. diff --git a/node_modules/es-define-property/README.md b/node_modules/es-define-property/README.md new file mode 100644 index 0000000..9b291bd --- /dev/null +++ b/node_modules/es-define-property/README.md @@ -0,0 +1,49 @@ +# es-define-property [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +`Object.defineProperty`, but not IE 8's broken one. + +## Example + +```js +const assert = require('assert'); + +const $defineProperty = require('es-define-property'); + +if ($defineProperty) { + assert.equal($defineProperty, Object.defineProperty); +} else if (Object.defineProperty) { + assert.equal($defineProperty, false, 'this is IE 8'); +} else { + assert.equal($defineProperty, false, 'this is an ES3 engine'); +} +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/es-define-property +[npm-version-svg]: https://versionbadg.es/ljharb/es-define-property.svg +[deps-svg]: https://david-dm.org/ljharb/es-define-property.svg +[deps-url]: https://david-dm.org/ljharb/es-define-property +[dev-deps-svg]: https://david-dm.org/ljharb/es-define-property/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/es-define-property#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-define-property.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-define-property.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-define-property.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-define-property +[codecov-image]: https://codecov.io/gh/ljharb/es-define-property/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/es-define-property/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-define-property +[actions-url]: https://github.com/ljharb/es-define-property/actions diff --git a/node_modules/es-define-property/index.d.ts b/node_modules/es-define-property/index.d.ts new file mode 100644 index 0000000..6012247 --- /dev/null +++ b/node_modules/es-define-property/index.d.ts @@ -0,0 +1,3 @@ +declare const defineProperty: false | typeof Object.defineProperty; + +export = defineProperty; \ No newline at end of file diff --git a/node_modules/es-define-property/index.js b/node_modules/es-define-property/index.js new file mode 100644 index 0000000..e0a2925 --- /dev/null +++ b/node_modules/es-define-property/index.js @@ -0,0 +1,14 @@ +'use strict'; + +/** @type {import('.')} */ +var $defineProperty = Object.defineProperty || false; +if ($defineProperty) { + try { + $defineProperty({}, 'a', { value: 1 }); + } catch (e) { + // IE 8 has a broken defineProperty + $defineProperty = false; + } +} + +module.exports = $defineProperty; diff --git a/node_modules/es-define-property/package.json b/node_modules/es-define-property/package.json new file mode 100644 index 0000000..fbed187 --- /dev/null +++ b/node_modules/es-define-property/package.json @@ -0,0 +1,81 @@ +{ + "name": "es-define-property", + "version": "1.0.1", + "description": "`Object.defineProperty`, but not IE 8's broken one.", + "main": "index.js", + "types": "./index.d.ts", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p .", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>= 10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/es-define-property.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "object", + "define", + "property", + "defineProperty", + "Object.defineProperty" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/es-define-property/issues" + }, + "homepage": "https://github.com/ljharb/es-define-property#readme", + "devDependencies": { + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/gopd": "^1.0.3", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "gopd": "^1.2.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "engines": { + "node": ">= 0.4" + }, + "testling": { + "files": "test/index.js" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + } +} diff --git a/node_modules/es-define-property/test/index.js b/node_modules/es-define-property/test/index.js new file mode 100644 index 0000000..b4b4688 --- /dev/null +++ b/node_modules/es-define-property/test/index.js @@ -0,0 +1,56 @@ +'use strict'; + +var $defineProperty = require('../'); + +var test = require('tape'); +var gOPD = require('gopd'); + +test('defineProperty: supported', { skip: !$defineProperty }, function (t) { + t.plan(4); + + t.equal(typeof $defineProperty, 'function', 'defineProperty is supported'); + if ($defineProperty && gOPD) { // this `if` check is just to shut TS up + /** @type {{ a: number, b?: number, c?: number }} */ + var o = { a: 1 }; + + $defineProperty(o, 'b', { enumerable: true, value: 2 }); + t.deepEqual( + gOPD(o, 'b'), + { + configurable: false, + enumerable: true, + value: 2, + writable: false + }, + 'property descriptor is as expected' + ); + + $defineProperty(o, 'c', { enumerable: false, value: 3, writable: true }); + t.deepEqual( + gOPD(o, 'c'), + { + configurable: false, + enumerable: false, + value: 3, + writable: true + }, + 'property descriptor is as expected' + ); + } + + t.equal($defineProperty, Object.defineProperty, 'defineProperty is Object.defineProperty'); + + t.end(); +}); + +test('defineProperty: not supported', { skip: !!$defineProperty }, function (t) { + t.notOk($defineProperty, 'defineProperty is not supported'); + + t.match( + typeof $defineProperty, + /^(?:undefined|boolean)$/, + '`typeof defineProperty` is `undefined` or `boolean`' + ); + + t.end(); +}); diff --git a/node_modules/es-define-property/tsconfig.json b/node_modules/es-define-property/tsconfig.json new file mode 100644 index 0000000..5a49992 --- /dev/null +++ b/node_modules/es-define-property/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2022", + }, + "exclude": [ + "coverage", + "test/list-exports" + ], +} diff --git a/node_modules/es-errors/.eslintrc b/node_modules/es-errors/.eslintrc new file mode 100644 index 0000000..3b5d9e9 --- /dev/null +++ b/node_modules/es-errors/.eslintrc @@ -0,0 +1,5 @@ +{ + "root": true, + + "extends": "@ljharb", +} diff --git a/node_modules/es-errors/.github/FUNDING.yml b/node_modules/es-errors/.github/FUNDING.yml new file mode 100644 index 0000000..f1b8805 --- /dev/null +++ b/node_modules/es-errors/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/es-errors +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with a single custom sponsorship URL diff --git a/node_modules/es-errors/CHANGELOG.md b/node_modules/es-errors/CHANGELOG.md new file mode 100644 index 0000000..204a9e9 --- /dev/null +++ b/node_modules/es-errors/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.3.0](https://github.com/ljharb/es-errors/compare/v1.2.1...v1.3.0) - 2024-02-05 + +### Commits + +- [New] add `EvalError` and `URIError` [`1927627`](https://github.com/ljharb/es-errors/commit/1927627ba68cb6c829d307231376c967db53acdf) + +## [v1.2.1](https://github.com/ljharb/es-errors/compare/v1.2.0...v1.2.1) - 2024-02-04 + +### Commits + +- [Fix] add missing `exports` entry [`5bb5f28`](https://github.com/ljharb/es-errors/commit/5bb5f280f98922701109d6ebb82eea2257cecc7e) + +## [v1.2.0](https://github.com/ljharb/es-errors/compare/v1.1.0...v1.2.0) - 2024-02-04 + +### Commits + +- [New] add `ReferenceError` [`6d8cf5b`](https://github.com/ljharb/es-errors/commit/6d8cf5bbb6f3f598d02cf6f30e468ba2caa8e143) + +## [v1.1.0](https://github.com/ljharb/es-errors/compare/v1.0.0...v1.1.0) - 2024-02-04 + +### Commits + +- [New] add base Error [`2983ab6`](https://github.com/ljharb/es-errors/commit/2983ab65f7bc5441276cb021dc3aa03c78881698) + +## v1.0.0 - 2024-02-03 + +### Commits + +- Initial implementation, tests, readme, type [`8f47631`](https://github.com/ljharb/es-errors/commit/8f476317e9ad76f40ad648081829b1a1a3a1288b) +- Initial commit [`ea5d099`](https://github.com/ljharb/es-errors/commit/ea5d099ef18e550509ab9e2be000526afd81c385) +- npm init [`6f5ebf9`](https://github.com/ljharb/es-errors/commit/6f5ebf9cead474dadd72b9e63dad315820a089ae) +- Only apps should have lockfiles [`e1a0aeb`](https://github.com/ljharb/es-errors/commit/e1a0aeb7b80f5cfc56be54d6b2100e915d47def8) +- [meta] add `sideEffects` flag [`a9c7d46`](https://github.com/ljharb/es-errors/commit/a9c7d460a492f1d8a241c836bc25a322a19cc043) diff --git a/node_modules/es-errors/LICENSE b/node_modules/es-errors/LICENSE new file mode 100644 index 0000000..f82f389 --- /dev/null +++ b/node_modules/es-errors/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jordan Harband + +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. diff --git a/node_modules/es-errors/README.md b/node_modules/es-errors/README.md new file mode 100644 index 0000000..8dbfacf --- /dev/null +++ b/node_modules/es-errors/README.md @@ -0,0 +1,55 @@ +# es-errors [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +A simple cache for a few of the JS Error constructors. + +## Example + +```js +const assert = require('assert'); + +const Base = require('es-errors'); +const Eval = require('es-errors/eval'); +const Range = require('es-errors/range'); +const Ref = require('es-errors/ref'); +const Syntax = require('es-errors/syntax'); +const Type = require('es-errors/type'); +const URI = require('es-errors/uri'); + +assert.equal(Base, Error); +assert.equal(Eval, EvalError); +assert.equal(Range, RangeError); +assert.equal(Ref, ReferenceError); +assert.equal(Syntax, SyntaxError); +assert.equal(Type, TypeError); +assert.equal(URI, URIError); +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/es-errors +[npm-version-svg]: https://versionbadg.es/ljharb/es-errors.svg +[deps-svg]: https://david-dm.org/ljharb/es-errors.svg +[deps-url]: https://david-dm.org/ljharb/es-errors +[dev-deps-svg]: https://david-dm.org/ljharb/es-errors/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/es-errors#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-errors.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-errors.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-errors.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-errors +[codecov-image]: https://codecov.io/gh/ljharb/es-errors/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/es-errors/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-errors +[actions-url]: https://github.com/ljharb/es-errors/actions diff --git a/node_modules/es-errors/eval.d.ts b/node_modules/es-errors/eval.d.ts new file mode 100644 index 0000000..e4210e0 --- /dev/null +++ b/node_modules/es-errors/eval.d.ts @@ -0,0 +1,3 @@ +declare const EvalError: EvalErrorConstructor; + +export = EvalError; diff --git a/node_modules/es-errors/eval.js b/node_modules/es-errors/eval.js new file mode 100644 index 0000000..725ccb6 --- /dev/null +++ b/node_modules/es-errors/eval.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./eval')} */ +module.exports = EvalError; diff --git a/node_modules/es-errors/index.d.ts b/node_modules/es-errors/index.d.ts new file mode 100644 index 0000000..69bdbc9 --- /dev/null +++ b/node_modules/es-errors/index.d.ts @@ -0,0 +1,3 @@ +declare const Error: ErrorConstructor; + +export = Error; diff --git a/node_modules/es-errors/index.js b/node_modules/es-errors/index.js new file mode 100644 index 0000000..cc0c521 --- /dev/null +++ b/node_modules/es-errors/index.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('.')} */ +module.exports = Error; diff --git a/node_modules/es-errors/package.json b/node_modules/es-errors/package.json new file mode 100644 index 0000000..ff8c2a5 --- /dev/null +++ b/node_modules/es-errors/package.json @@ -0,0 +1,80 @@ +{ + "name": "es-errors", + "version": "1.3.0", + "description": "A simple cache for a few of the JS Error constructors.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./eval": "./eval.js", + "./range": "./range.js", + "./ref": "./ref.js", + "./syntax": "./syntax.js", + "./type": "./type.js", + "./uri": "./uri.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "nyc tape 'test/**/*.js'", + "posttest": "aud --production", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/es-errors.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "error", + "typeerror", + "syntaxerror", + "rangeerror" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/es-errors/issues" + }, + "homepage": "https://github.com/ljharb/es-errors#readme", + "devDependencies": { + "@ljharb/eslint-config": "^21.1.0", + "@types/tape": "^5.6.4", + "aud": "^2.0.4", + "auto-changelog": "^2.4.0", + "eclint": "^2.8.1", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.7.4", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/es-errors/range.d.ts b/node_modules/es-errors/range.d.ts new file mode 100644 index 0000000..3a12e86 --- /dev/null +++ b/node_modules/es-errors/range.d.ts @@ -0,0 +1,3 @@ +declare const RangeError: RangeErrorConstructor; + +export = RangeError; diff --git a/node_modules/es-errors/range.js b/node_modules/es-errors/range.js new file mode 100644 index 0000000..2044fe0 --- /dev/null +++ b/node_modules/es-errors/range.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./range')} */ +module.exports = RangeError; diff --git a/node_modules/es-errors/ref.d.ts b/node_modules/es-errors/ref.d.ts new file mode 100644 index 0000000..a13107e --- /dev/null +++ b/node_modules/es-errors/ref.d.ts @@ -0,0 +1,3 @@ +declare const ReferenceError: ReferenceErrorConstructor; + +export = ReferenceError; diff --git a/node_modules/es-errors/ref.js b/node_modules/es-errors/ref.js new file mode 100644 index 0000000..d7c430f --- /dev/null +++ b/node_modules/es-errors/ref.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./ref')} */ +module.exports = ReferenceError; diff --git a/node_modules/es-errors/syntax.d.ts b/node_modules/es-errors/syntax.d.ts new file mode 100644 index 0000000..6a0c53c --- /dev/null +++ b/node_modules/es-errors/syntax.d.ts @@ -0,0 +1,3 @@ +declare const SyntaxError: SyntaxErrorConstructor; + +export = SyntaxError; diff --git a/node_modules/es-errors/syntax.js b/node_modules/es-errors/syntax.js new file mode 100644 index 0000000..5f5fdde --- /dev/null +++ b/node_modules/es-errors/syntax.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./syntax')} */ +module.exports = SyntaxError; diff --git a/node_modules/es-errors/test/index.js b/node_modules/es-errors/test/index.js new file mode 100644 index 0000000..1ff0277 --- /dev/null +++ b/node_modules/es-errors/test/index.js @@ -0,0 +1,19 @@ +'use strict'; + +var test = require('tape'); + +var E = require('../'); +var R = require('../range'); +var Ref = require('../ref'); +var S = require('../syntax'); +var T = require('../type'); + +test('errors', function (t) { + t.equal(E, Error); + t.equal(R, RangeError); + t.equal(Ref, ReferenceError); + t.equal(S, SyntaxError); + t.equal(T, TypeError); + + t.end(); +}); diff --git a/node_modules/es-errors/tsconfig.json b/node_modules/es-errors/tsconfig.json new file mode 100644 index 0000000..99dfeb6 --- /dev/null +++ b/node_modules/es-errors/tsconfig.json @@ -0,0 +1,49 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + + /* Language and Environment */ + "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": ["types"], /* Specify multiple folders that act like `./node_modules/@types`. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + "noEmit": true, /* Disable emitting files from a compilation. */ + + /* Interop Constraints */ + "allowSyntheticDefaultImports": true, /* Allow `import x from y` when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + + /* Completeness */ + // "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/es-errors/type.d.ts b/node_modules/es-errors/type.d.ts new file mode 100644 index 0000000..576fb51 --- /dev/null +++ b/node_modules/es-errors/type.d.ts @@ -0,0 +1,3 @@ +declare const TypeError: TypeErrorConstructor + +export = TypeError; diff --git a/node_modules/es-errors/type.js b/node_modules/es-errors/type.js new file mode 100644 index 0000000..9769e44 --- /dev/null +++ b/node_modules/es-errors/type.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./type')} */ +module.exports = TypeError; diff --git a/node_modules/es-errors/uri.d.ts b/node_modules/es-errors/uri.d.ts new file mode 100644 index 0000000..c3261c9 --- /dev/null +++ b/node_modules/es-errors/uri.d.ts @@ -0,0 +1,3 @@ +declare const URIError: URIErrorConstructor; + +export = URIError; diff --git a/node_modules/es-errors/uri.js b/node_modules/es-errors/uri.js new file mode 100644 index 0000000..e9cd1c7 --- /dev/null +++ b/node_modules/es-errors/uri.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./uri')} */ +module.exports = URIError; diff --git a/node_modules/es-object-atoms/.eslintrc b/node_modules/es-object-atoms/.eslintrc new file mode 100644 index 0000000..d90a1bc --- /dev/null +++ b/node_modules/es-object-atoms/.eslintrc @@ -0,0 +1,16 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "eqeqeq": ["error", "allow-null"], + "id-length": "off", + "new-cap": ["error", { + "capIsNewExceptions": [ + "RequireObjectCoercible", + "ToObject", + ], + }], + }, +} diff --git a/node_modules/es-object-atoms/.github/FUNDING.yml b/node_modules/es-object-atoms/.github/FUNDING.yml new file mode 100644 index 0000000..352bfda --- /dev/null +++ b/node_modules/es-object-atoms/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/es-object +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with a single custom sponsorship URL diff --git a/node_modules/es-object-atoms/CHANGELOG.md b/node_modules/es-object-atoms/CHANGELOG.md new file mode 100644 index 0000000..fdd2abe --- /dev/null +++ b/node_modules/es-object-atoms/CHANGELOG.md @@ -0,0 +1,37 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.1.1](https://github.com/ljharb/es-object-atoms/compare/v1.1.0...v1.1.1) - 2025-01-14 + +### Commits + +- [types] `ToObject`: improve types [`cfe8c8a`](https://github.com/ljharb/es-object-atoms/commit/cfe8c8a105c44820cb22e26f62d12ef0ad9715c8) + +## [v1.1.0](https://github.com/ljharb/es-object-atoms/compare/v1.0.1...v1.1.0) - 2025-01-14 + +### Commits + +- [New] add `isObject` [`51e4042`](https://github.com/ljharb/es-object-atoms/commit/51e4042df722eb3165f40dc5f4bf33d0197ecb07) + +## [v1.0.1](https://github.com/ljharb/es-object-atoms/compare/v1.0.0...v1.0.1) - 2025-01-13 + +### Commits + +- [Dev Deps] update `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/tape`, `auto-changelog`, `tape` [`38ab9eb`](https://github.com/ljharb/es-object-atoms/commit/38ab9eb00b62c2f4668644f5e513d9b414ebd595) +- [types] improve types [`7d1beb8`](https://github.com/ljharb/es-object-atoms/commit/7d1beb887958b78b6a728a210a1c8370ab7e2aa1) +- [Tests] replace `aud` with `npm audit` [`25863ba`](https://github.com/ljharb/es-object-atoms/commit/25863baf99178f1d1ad33d1120498db28631907e) +- [Dev Deps] add missing peer dep [`c012309`](https://github.com/ljharb/es-object-atoms/commit/c0123091287e6132d6f4240496340c427433df28) + +## v1.0.0 - 2024-03-16 + +### Commits + +- Initial implementation, tests, readme, types [`f1499db`](https://github.com/ljharb/es-object-atoms/commit/f1499db7d3e1741e64979c61d645ab3137705e82) +- Initial commit [`99eedc7`](https://github.com/ljharb/es-object-atoms/commit/99eedc7b5fde38a50a28d3c8b724706e3e4c5f6a) +- [meta] rename repo [`fc851fa`](https://github.com/ljharb/es-object-atoms/commit/fc851fa70616d2d182aaf0bd02c2ed7084dea8fa) +- npm init [`b909377`](https://github.com/ljharb/es-object-atoms/commit/b909377c50049bd0ec575562d20b0f9ebae8947f) +- Only apps should have lockfiles [`7249edd`](https://github.com/ljharb/es-object-atoms/commit/7249edd2178c1b9ddfc66ffcc6d07fdf0d28efc1) diff --git a/node_modules/es-object-atoms/LICENSE b/node_modules/es-object-atoms/LICENSE new file mode 100644 index 0000000..f82f389 --- /dev/null +++ b/node_modules/es-object-atoms/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Jordan Harband + +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. diff --git a/node_modules/es-object-atoms/README.md b/node_modules/es-object-atoms/README.md new file mode 100644 index 0000000..447695b --- /dev/null +++ b/node_modules/es-object-atoms/README.md @@ -0,0 +1,63 @@ +# es-object-atoms [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +ES Object-related atoms: Object, ToObject, RequireObjectCoercible. + +## Example + +```js +const assert = require('assert'); + +const $Object = require('es-object-atoms'); +const isObject = require('es-object-atoms/isObject'); +const ToObject = require('es-object-atoms/ToObject'); +const RequireObjectCoercible = require('es-object-atoms/RequireObjectCoercible'); + +assert.equal($Object, Object); +assert.throws(() => ToObject(null), TypeError); +assert.throws(() => ToObject(undefined), TypeError); +assert.throws(() => RequireObjectCoercible(null), TypeError); +assert.throws(() => RequireObjectCoercible(undefined), TypeError); + +assert.equal(isObject(undefined), false); +assert.equal(isObject(null), false); +assert.equal(isObject({}), true); +assert.equal(isObject([]), true); +assert.equal(isObject(function () {}), true); + +assert.deepEqual(RequireObjectCoercible(true), true); +assert.deepEqual(ToObject(true), Object(true)); + +const obj = {}; +assert.equal(RequireObjectCoercible(obj), obj); +assert.equal(ToObject(obj), obj); +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/es-object-atoms +[npm-version-svg]: https://versionbadg.es/ljharb/es-object-atoms.svg +[deps-svg]: https://david-dm.org/ljharb/es-object-atoms.svg +[deps-url]: https://david-dm.org/ljharb/es-object-atoms +[dev-deps-svg]: https://david-dm.org/ljharb/es-object-atoms/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/es-object-atoms#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-object-atoms.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-object-atoms.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-object.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-object-atoms +[codecov-image]: https://codecov.io/gh/ljharb/es-object-atoms/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/es-object-atoms/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/es-object-atoms +[actions-url]: https://github.com/ljharb/es-object-atoms/actions diff --git a/node_modules/es-object-atoms/RequireObjectCoercible.d.ts b/node_modules/es-object-atoms/RequireObjectCoercible.d.ts new file mode 100644 index 0000000..7e26c45 --- /dev/null +++ b/node_modules/es-object-atoms/RequireObjectCoercible.d.ts @@ -0,0 +1,3 @@ +declare function RequireObjectCoercible(value: T, optMessage?: string): T; + +export = RequireObjectCoercible; diff --git a/node_modules/es-object-atoms/RequireObjectCoercible.js b/node_modules/es-object-atoms/RequireObjectCoercible.js new file mode 100644 index 0000000..8e191c6 --- /dev/null +++ b/node_modules/es-object-atoms/RequireObjectCoercible.js @@ -0,0 +1,11 @@ +'use strict'; + +var $TypeError = require('es-errors/type'); + +/** @type {import('./RequireObjectCoercible')} */ +module.exports = function RequireObjectCoercible(value) { + if (value == null) { + throw new $TypeError((arguments.length > 0 && arguments[1]) || ('Cannot call method on ' + value)); + } + return value; +}; diff --git a/node_modules/es-object-atoms/ToObject.d.ts b/node_modules/es-object-atoms/ToObject.d.ts new file mode 100644 index 0000000..d6dd302 --- /dev/null +++ b/node_modules/es-object-atoms/ToObject.d.ts @@ -0,0 +1,7 @@ +declare function ToObject(value: number): Number; +declare function ToObject(value: boolean): Boolean; +declare function ToObject(value: string): String; +declare function ToObject(value: bigint): BigInt; +declare function ToObject(value: T): T; + +export = ToObject; diff --git a/node_modules/es-object-atoms/ToObject.js b/node_modules/es-object-atoms/ToObject.js new file mode 100644 index 0000000..2b99a7d --- /dev/null +++ b/node_modules/es-object-atoms/ToObject.js @@ -0,0 +1,10 @@ +'use strict'; + +var $Object = require('./'); +var RequireObjectCoercible = require('./RequireObjectCoercible'); + +/** @type {import('./ToObject')} */ +module.exports = function ToObject(value) { + RequireObjectCoercible(value); + return $Object(value); +}; diff --git a/node_modules/es-object-atoms/index.d.ts b/node_modules/es-object-atoms/index.d.ts new file mode 100644 index 0000000..8bdbfc8 --- /dev/null +++ b/node_modules/es-object-atoms/index.d.ts @@ -0,0 +1,3 @@ +declare const Object: ObjectConstructor; + +export = Object; diff --git a/node_modules/es-object-atoms/index.js b/node_modules/es-object-atoms/index.js new file mode 100644 index 0000000..1d33cef --- /dev/null +++ b/node_modules/es-object-atoms/index.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('.')} */ +module.exports = Object; diff --git a/node_modules/es-object-atoms/isObject.d.ts b/node_modules/es-object-atoms/isObject.d.ts new file mode 100644 index 0000000..43bee3b --- /dev/null +++ b/node_modules/es-object-atoms/isObject.d.ts @@ -0,0 +1,3 @@ +declare function isObject(x: unknown): x is object; + +export = isObject; diff --git a/node_modules/es-object-atoms/isObject.js b/node_modules/es-object-atoms/isObject.js new file mode 100644 index 0000000..ec49bf1 --- /dev/null +++ b/node_modules/es-object-atoms/isObject.js @@ -0,0 +1,6 @@ +'use strict'; + +/** @type {import('./isObject')} */ +module.exports = function isObject(x) { + return !!x && (typeof x === 'function' || typeof x === 'object'); +}; diff --git a/node_modules/es-object-atoms/package.json b/node_modules/es-object-atoms/package.json new file mode 100644 index 0000000..f4cec71 --- /dev/null +++ b/node_modules/es-object-atoms/package.json @@ -0,0 +1,80 @@ +{ + "name": "es-object-atoms", + "version": "1.1.1", + "description": "ES Object-related atoms: Object, ToObject, RequireObjectCoercible", + "main": "index.js", + "exports": { + ".": "./index.js", + "./RequireObjectCoercible": "./RequireObjectCoercible.js", + "./isObject": "./isObject.js", + "./ToObject": "./ToObject.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "nyc tape 'test/**/*.js'", + "posttest": "npx npm@\">= 10.2\" audit --production", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/es-object-atoms.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "object", + "toobject", + "coercible" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/es-object-atoms/issues" + }, + "homepage": "https://github.com/ljharb/es-object-atoms#readme", + "dependencies": { + "es-errors": "^1.3.0" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.3", + "@types/tape": "^5.8.1", + "auto-changelog": "^2.5.0", + "eclint": "^2.8.1", + "encoding": "^0.1.13", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/es-object-atoms/test/index.js b/node_modules/es-object-atoms/test/index.js new file mode 100644 index 0000000..430b705 --- /dev/null +++ b/node_modules/es-object-atoms/test/index.js @@ -0,0 +1,38 @@ +'use strict'; + +var test = require('tape'); + +var $Object = require('../'); +var isObject = require('../isObject'); +var ToObject = require('../ToObject'); +var RequireObjectCoercible = require('..//RequireObjectCoercible'); + +test('errors', function (t) { + t.equal($Object, Object); + // @ts-expect-error + t['throws'](function () { ToObject(null); }, TypeError); + // @ts-expect-error + t['throws'](function () { ToObject(undefined); }, TypeError); + // @ts-expect-error + t['throws'](function () { RequireObjectCoercible(null); }, TypeError); + // @ts-expect-error + t['throws'](function () { RequireObjectCoercible(undefined); }, TypeError); + + t.deepEqual(RequireObjectCoercible(true), true); + t.deepEqual(ToObject(true), Object(true)); + t.deepEqual(ToObject(42), Object(42)); + var f = function () {}; + t.equal(ToObject(f), f); + + t.equal(isObject(undefined), false); + t.equal(isObject(null), false); + t.equal(isObject({}), true); + t.equal(isObject([]), true); + t.equal(isObject(function () {}), true); + + var obj = {}; + t.equal(RequireObjectCoercible(obj), obj); + t.equal(ToObject(obj), obj); + + t.end(); +}); diff --git a/node_modules/es-object-atoms/tsconfig.json b/node_modules/es-object-atoms/tsconfig.json new file mode 100644 index 0000000..1f73cb7 --- /dev/null +++ b/node_modules/es-object-atoms/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es5", + }, +} diff --git a/node_modules/es-set-tostringtag/.eslintrc b/node_modules/es-set-tostringtag/.eslintrc new file mode 100644 index 0000000..2612ed8 --- /dev/null +++ b/node_modules/es-set-tostringtag/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "new-cap": [2, { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + }, +} diff --git a/node_modules/es-set-tostringtag/.nycrc b/node_modules/es-set-tostringtag/.nycrc new file mode 100644 index 0000000..bdd626c --- /dev/null +++ b/node_modules/es-set-tostringtag/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/es-set-tostringtag/CHANGELOG.md b/node_modules/es-set-tostringtag/CHANGELOG.md new file mode 100644 index 0000000..00bdc03 --- /dev/null +++ b/node_modules/es-set-tostringtag/CHANGELOG.md @@ -0,0 +1,67 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v2.1.0](https://github.com/es-shims/es-set-tostringtag/compare/v2.0.3...v2.1.0) - 2025-01-01 + +### Commits + +- [actions] split out node 10-20, and 20+ [`ede033c`](https://github.com/es-shims/es-set-tostringtag/commit/ede033cc4e506c3966d2d482d4ac5987e329162a) +- [types] use shared config [`28ef164`](https://github.com/es-shims/es-set-tostringtag/commit/28ef164ad7c5bc21837c79f7ef25542a1f258ade) +- [New] add `nonConfigurable` option [`3bee3f0`](https://github.com/es-shims/es-set-tostringtag/commit/3bee3f04caddd318f3932912212ed20b2d62aad7) +- [Fix] validate boolean option argument [`3c8a609`](https://github.com/es-shims/es-set-tostringtag/commit/3c8a609c795a305ccca163f0ff6956caa88cdc0e) +- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/eslint-config`, `@ljharb/tsconfig`, `@types/get-intrinsic`, `@types/tape`, `auto-changelog`, `tape` [`501a969`](https://github.com/es-shims/es-set-tostringtag/commit/501a96998484226e07f5ffd447e8f305a998f1d8) +- [Tests] add coverage [`18af289`](https://github.com/es-shims/es-set-tostringtag/commit/18af2897b4e937373c9b8c8831bc338932246470) +- [readme] document `force` option [`bd446a1`](https://github.com/es-shims/es-set-tostringtag/commit/bd446a107b71a2270278442e5124f45590d3ee64) +- [Tests] use `@arethetypeswrong/cli` [`7c2c2fa`](https://github.com/es-shims/es-set-tostringtag/commit/7c2c2fa3cca0f4d263603adb75426b239514598f) +- [Tests] replace `aud` with `npm audit` [`9e372d7`](https://github.com/es-shims/es-set-tostringtag/commit/9e372d7e6db3dab405599a14d9074a99a03b8242) +- [Deps] update `get-intrinsic` [`7df1216`](https://github.com/es-shims/es-set-tostringtag/commit/7df12167295385c2a547410e687cb0c04f3a34b9) +- [Deps] update `hasown` [`993a7d2`](https://github.com/es-shims/es-set-tostringtag/commit/993a7d200e2059fd857ec1a25d0a49c2c34ae6e2) +- [Dev Deps] add missing peer dep [`148ed8d`](https://github.com/es-shims/es-set-tostringtag/commit/148ed8db99a7a94f9af3823fd083e6e437fa1587) + +## [v2.0.3](https://github.com/es-shims/es-set-tostringtag/compare/v2.0.2...v2.0.3) - 2024-02-20 + +### Commits + +- add types [`d538513`](https://github.com/es-shims/es-set-tostringtag/commit/d5385133592a32a0a416cb535327918af7fbc4ad) +- [Deps] update `get-intrinsic`, `has-tostringtag`, `hasown` [`d129b29`](https://github.com/es-shims/es-set-tostringtag/commit/d129b29536bccc8a9d03a47887ca4d1f7ad0c5b9) +- [Dev Deps] update `aud`, `npmignore`, `tape` [`132ed23`](https://github.com/es-shims/es-set-tostringtag/commit/132ed23c964a41ed55e4ab4a5a2c3fe185e821c1) +- [Tests] fix hasOwn require [`f89c831`](https://github.com/es-shims/es-set-tostringtag/commit/f89c831fe5f3edf1f979c597b56fee1be6111f56) + +## [v2.0.2](https://github.com/es-shims/es-set-tostringtag/compare/v2.0.1...v2.0.2) - 2023-10-20 + +### Commits + +- [Refactor] use `hasown` instead of `has` [`0cc6c4e`](https://github.com/es-shims/es-set-tostringtag/commit/0cc6c4e61fd13e8f00b85424ae6e541ebf289e74) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`70e447c`](https://github.com/es-shims/es-set-tostringtag/commit/70e447cf9f82b896ddf359fda0a0498c16cf3ed2) +- [Deps] update `get-intrinsic` [`826aab7`](https://github.com/es-shims/es-set-tostringtag/commit/826aab76180392871c8efa99acc0f0bbf775c64e) + +## [v2.0.1](https://github.com/es-shims/es-set-tostringtag/compare/v2.0.0...v2.0.1) - 2023-01-05 + +### Fixed + +- [Fix] move `has` to prod deps [`#2`](https://github.com/es-shims/es-set-tostringtag/issues/2) + +### Commits + +- [Dev Deps] update `@ljharb/eslint-config` [`b9eecd2`](https://github.com/es-shims/es-set-tostringtag/commit/b9eecd23c10b7b43ba75089ac8ff8cc6b295798b) + +## [v2.0.0](https://github.com/es-shims/es-set-tostringtag/compare/v1.0.0...v2.0.0) - 2022-12-21 + +### Commits + +- [Tests] refactor tests [`168dcfb`](https://github.com/es-shims/es-set-tostringtag/commit/168dcfbb535c279dc48ccdc89419155125aaec18) +- [Breaking] do not set toStringTag if it is already set [`226ab87`](https://github.com/es-shims/es-set-tostringtag/commit/226ab874192c625d9e5f0e599d3f60d2b2aa83b5) +- [New] add `force` option to set even if already set [`1abd4ec`](https://github.com/es-shims/es-set-tostringtag/commit/1abd4ecb282f19718c4518284b0293a343564505) + +## v1.0.0 - 2022-12-21 + +### Commits + +- Initial implementation, tests, readme [`a0e1147`](https://github.com/es-shims/es-set-tostringtag/commit/a0e11473f79a233b46374525c962ea1b4d42418a) +- Initial commit [`ffd4aff`](https://github.com/es-shims/es-set-tostringtag/commit/ffd4afffbeebf29aff0d87a7cfc3f7844e09fe68) +- npm init [`fffe5bd`](https://github.com/es-shims/es-set-tostringtag/commit/fffe5bd1d1146d084730a387a9c672371f4a8fff) +- Only apps should have lockfiles [`d363871`](https://github.com/es-shims/es-set-tostringtag/commit/d36387139465623e161a15dbd39120537f150c62) diff --git a/node_modules/es-set-tostringtag/LICENSE b/node_modules/es-set-tostringtag/LICENSE new file mode 100644 index 0000000..c2a8460 --- /dev/null +++ b/node_modules/es-set-tostringtag/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 ECMAScript Shims + +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. diff --git a/node_modules/es-set-tostringtag/README.md b/node_modules/es-set-tostringtag/README.md new file mode 100644 index 0000000..c27bc9f --- /dev/null +++ b/node_modules/es-set-tostringtag/README.md @@ -0,0 +1,53 @@ +# es-set-tostringtag [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +A helper to optimistically set Symbol.toStringTag, when possible. + +## Example +Most common usage: +```js +var assert = require('assert'); +var setToStringTag = require('es-set-tostringtag'); + +var obj = {}; + +assert.equal(Object.prototype.toString.call(obj), '[object Object]'); + +setToStringTag(obj, 'tagged!'); + +assert.equal(Object.prototype.toString.call(obj), '[object tagged!]'); +``` + +## Options +An optional options argument can be provided as the third argument. The available options are: + +### `force` +If the `force` option is set to `true`, the toStringTag will be set even if it is already set. + +### `nonConfigurable` +If the `nonConfigurable` option is set to `true`, the toStringTag will be defined as non-configurable when possible. + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.com/package/es-set-tostringtag +[npm-version-svg]: https://versionbadg.es/es-shims/es-set-tostringtag.svg +[deps-svg]: https://david-dm.org/es-shims/es-set-tostringtag.svg +[deps-url]: https://david-dm.org/es-shims/es-set-tostringtag +[dev-deps-svg]: https://david-dm.org/es-shims/es-set-tostringtag/dev-status.svg +[dev-deps-url]: https://david-dm.org/es-shims/es-set-tostringtag#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/es-set-tostringtag.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/es-set-tostringtag.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-set-tostringtag.svg +[downloads-url]: https://npm-stat.com/charts.html?package=es-set-tostringtag +[codecov-image]: https://codecov.io/gh/es-shims/es-set-tostringtag/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/es-shims/es-set-tostringtag/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/es-set-tostringtag +[actions-url]: https://github.com/es-shims/es-set-tostringtag/actions diff --git a/node_modules/es-set-tostringtag/index.d.ts b/node_modules/es-set-tostringtag/index.d.ts new file mode 100644 index 0000000..c9a8fc4 --- /dev/null +++ b/node_modules/es-set-tostringtag/index.d.ts @@ -0,0 +1,10 @@ +declare function setToStringTag( + object: object & { [Symbol.toStringTag]?: unknown }, + value: string | unknown, + options?: { + force?: boolean; + nonConfigurable?: boolean; + }, +): void; + +export = setToStringTag; \ No newline at end of file diff --git a/node_modules/es-set-tostringtag/index.js b/node_modules/es-set-tostringtag/index.js new file mode 100644 index 0000000..6b6b49c --- /dev/null +++ b/node_modules/es-set-tostringtag/index.js @@ -0,0 +1,35 @@ +'use strict'; + +var GetIntrinsic = require('get-intrinsic'); + +var $defineProperty = GetIntrinsic('%Object.defineProperty%', true); + +var hasToStringTag = require('has-tostringtag/shams')(); +var hasOwn = require('hasown'); +var $TypeError = require('es-errors/type'); + +var toStringTag = hasToStringTag ? Symbol.toStringTag : null; + +/** @type {import('.')} */ +module.exports = function setToStringTag(object, value) { + var overrideIfSet = arguments.length > 2 && !!arguments[2] && arguments[2].force; + var nonConfigurable = arguments.length > 2 && !!arguments[2] && arguments[2].nonConfigurable; + if ( + (typeof overrideIfSet !== 'undefined' && typeof overrideIfSet !== 'boolean') + || (typeof nonConfigurable !== 'undefined' && typeof nonConfigurable !== 'boolean') + ) { + throw new $TypeError('if provided, the `overrideIfSet` and `nonConfigurable` options must be booleans'); + } + if (toStringTag && (overrideIfSet || !hasOwn(object, toStringTag))) { + if ($defineProperty) { + $defineProperty(object, toStringTag, { + configurable: !nonConfigurable, + enumerable: false, + value: value, + writable: false + }); + } else { + object[toStringTag] = value; // eslint-disable-line no-param-reassign + } + } +}; diff --git a/node_modules/es-set-tostringtag/package.json b/node_modules/es-set-tostringtag/package.json new file mode 100644 index 0000000..277c3e5 --- /dev/null +++ b/node_modules/es-set-tostringtag/package.json @@ -0,0 +1,78 @@ +{ + "name": "es-set-tostringtag", + "version": "2.1.0", + "description": "A helper to optimistically set Symbol.toStringTag, when possible.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@\">= 10.2\" audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/es-shims/es-set-tostringtag.git" + }, + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/es-shims/es-set-tostringtag/issues" + }, + "homepage": "https://github.com/es-shims/es-set-tostringtag#readme", + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.2", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.3", + "@types/get-intrinsic": "^1.2.3", + "@types/has-symbols": "^1.0.2", + "@types/tape": "^5.8.0", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "testling": { + "files": "./test/index.js" + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + } +} diff --git a/node_modules/es-set-tostringtag/test/index.js b/node_modules/es-set-tostringtag/test/index.js new file mode 100644 index 0000000..f1757b3 --- /dev/null +++ b/node_modules/es-set-tostringtag/test/index.js @@ -0,0 +1,85 @@ +'use strict'; + +var test = require('tape'); +var hasToStringTag = require('has-tostringtag/shams')(); +var hasOwn = require('hasown'); + +var setToStringTag = require('../'); + +test('setToStringTag', function (t) { + t.equal(typeof setToStringTag, 'function', 'is a function'); + + /** @type {{ [Symbol.toStringTag]?: typeof sentinel }} */ + var obj = {}; + var sentinel = {}; + + setToStringTag(obj, sentinel); + + t['throws']( + // @ts-expect-error + function () { setToStringTag(obj, sentinel, { force: 'yes' }); }, + TypeError, + 'throws if options is not an object' + ); + + t.test('has Symbol.toStringTag', { skip: !hasToStringTag }, function (st) { + st.ok(hasOwn(obj, Symbol.toStringTag), 'has toStringTag property'); + + st.equal(obj[Symbol.toStringTag], sentinel, 'toStringTag property is as expected'); + + st.equal(String(obj), '[object Object]', 'toStringTag works'); + + /** @type {{ [Symbol.toStringTag]?: string }} */ + var tagged = {}; + tagged[Symbol.toStringTag] = 'already tagged'; + st.equal(String(tagged), '[object already tagged]', 'toStringTag works'); + + setToStringTag(tagged, 'new tag'); + st.equal(String(tagged), '[object already tagged]', 'toStringTag is unchanged'); + + setToStringTag(tagged, 'new tag', { force: true }); + st.equal(String(tagged), '[object new tag]', 'toStringTag is changed with force: true'); + + st.deepEqual( + Object.getOwnPropertyDescriptor(tagged, Symbol.toStringTag), + { + configurable: true, + enumerable: false, + value: 'new tag', + writable: false + }, + 'has expected property descriptor' + ); + + setToStringTag(tagged, 'new tag', { force: true, nonConfigurable: true }); + st.deepEqual( + Object.getOwnPropertyDescriptor(tagged, Symbol.toStringTag), + { + configurable: false, + enumerable: false, + value: 'new tag', + writable: false + }, + 'is nonconfigurable' + ); + + st.end(); + }); + + t.test('does not have Symbol.toStringTag', { skip: hasToStringTag }, function (st) { + var passed = true; + for (var key in obj) { // eslint-disable-line no-restricted-syntax + if (hasOwn(obj, key)) { + st.fail('object has own key ' + key); + passed = false; + } + } + if (passed) { + st.ok(true, 'object has no enumerable own keys'); + } + + st.end(); + }); + + t.end(); +}); diff --git a/node_modules/es-set-tostringtag/tsconfig.json b/node_modules/es-set-tostringtag/tsconfig.json new file mode 100644 index 0000000..d9a6668 --- /dev/null +++ b/node_modules/es-set-tostringtag/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/extsprintf/.gitmodules b/node_modules/extsprintf/.gitmodules new file mode 100644 index 0000000..401f01a --- /dev/null +++ b/node_modules/extsprintf/.gitmodules @@ -0,0 +1,3 @@ +[submodule "deps/catest"] + path = deps/catest + url = https://github.com/joyent/catest diff --git a/node_modules/extsprintf/CHANGES.md b/node_modules/extsprintf/CHANGES.md new file mode 100644 index 0000000..91c057e --- /dev/null +++ b/node_modules/extsprintf/CHANGES.md @@ -0,0 +1,10 @@ +# Changelog + +## Not yet released + +None yet. + +## v1.4.0 + +* #13 could provide better error messages for programmer errors +* #14 bring extsprintf into the modern world diff --git a/node_modules/extsprintf/CONTRIBUTING.md b/node_modules/extsprintf/CONTRIBUTING.md new file mode 100644 index 0000000..f550dc3 --- /dev/null +++ b/node_modules/extsprintf/CONTRIBUTING.md @@ -0,0 +1,17 @@ +# Contributing + +This repository uses GitHub pull requests for code review. + +See the [Joyent Engineering +Guidelines](https://github.com/joyent/eng/blob/master/docs/index.md) for general +best practices expected in this repository. + +Contributions should be "make prepush" clean. This target requires separate +tools: + +* https://github.com/davepacheco/jsstyle +* https://github.com/davepacheco/javascriptlint +* https://github.com/joyent/catest + +If you're changing something non-trivial or user-facing, you may want to submit +an issue first. diff --git a/node_modules/extsprintf/LICENSE b/node_modules/extsprintf/LICENSE new file mode 100644 index 0000000..cbc0bb3 --- /dev/null +++ b/node_modules/extsprintf/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012, Joyent, Inc. All rights reserved. + +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 diff --git a/node_modules/extsprintf/Makefile b/node_modules/extsprintf/Makefile new file mode 100644 index 0000000..6d96059 --- /dev/null +++ b/node_modules/extsprintf/Makefile @@ -0,0 +1,30 @@ +# +# Copyright (c) 2017, Joyent, Inc. All rights reserved. +# +# Makefile: top-level Makefile +# +# This Makefile contains only repo-specific logic and uses included makefiles +# to supply common targets (javascriptlint, jsstyle, restdown, etc.), which are +# used by other repos as well. +# + +# +# Files +# +CATEST = deps/catest/catest +JSL = jsl +JSSTYLE = jsstyle +JS_FILES := $(shell find examples lib -name '*.js') +JSL_FILES_NODE = $(JS_FILES) +JSSTYLE_FILES = $(JS_FILES) +JSL_CONF_NODE = jsl.node.conf + +# Default target is "check" +check: + +test: | $(CATEST) + $(CATEST) -a + +CATEST: deps/catest/.git + +include ./Makefile.targ diff --git a/node_modules/extsprintf/Makefile.targ b/node_modules/extsprintf/Makefile.targ new file mode 100644 index 0000000..2a64fe7 --- /dev/null +++ b/node_modules/extsprintf/Makefile.targ @@ -0,0 +1,285 @@ +# -*- mode: makefile -*- +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# +# Makefile.targ: common targets. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# +# This Makefile defines several useful targets and rules. You can use it by +# including it from a Makefile that specifies some of the variables below. +# +# Targets defined in this Makefile: +# +# check Checks JavaScript files for lint and style +# Checks bash scripts for syntax +# Checks SMF manifests for validity against the SMF DTD +# +# clean Removes built files +# +# docs Builds restdown documentation in docs/ +# +# prepush Depends on "check" and "test" +# +# test Does nothing (you should override this) +# +# xref Generates cscope (source cross-reference index) +# +# For details on what these targets are supposed to do, see the Joyent +# Engineering Guide. +# +# To make use of these targets, you'll need to set some of these variables. Any +# variables left unset will simply not be used. +# +# BASH_FILES Bash scripts to check for syntax +# (paths relative to top-level Makefile) +# +# CLEAN_FILES Files to remove as part of the "clean" target. Note +# that files generated by targets in this Makefile are +# automatically included in CLEAN_FILES. These include +# restdown-generated HTML and JSON files. +# +# DOC_FILES Restdown (documentation source) files. These are +# assumed to be contained in "docs/", and must NOT +# contain the "docs/" prefix. +# +# JSL_CONF_NODE Specify JavaScriptLint configuration files +# JSL_CONF_WEB (paths relative to top-level Makefile) +# +# Node.js and Web configuration files are separate +# because you'll usually want different global variable +# configurations. If no file is specified, none is given +# to jsl, which causes it to use a default configuration, +# which probably isn't what you want. +# +# JSL_FILES_NODE JavaScript files to check with Node config file. +# JSL_FILES_WEB JavaScript files to check with Web config file. +# +# You can also override these variables: +# +# BASH Path to bash (default: bash) +# +# CSCOPE_DIRS Directories to search for source files for the cscope +# index. (default: ".") +# +# JSL Path to JavaScriptLint (default: "jsl") +# +# JSL_FLAGS_NODE Additional flags to pass through to JSL +# JSL_FLAGS_WEB +# JSL_FLAGS +# +# JSSTYLE Path to jsstyle (default: jsstyle) +# +# JSSTYLE_FLAGS Additional flags to pass through to jsstyle +# + +# +# Defaults for the various tools we use. +# +BASH ?= bash +BASHSTYLE ?= tools/bashstyle +CP ?= cp +CSCOPE ?= cscope +CSCOPE_DIRS ?= . +JSL ?= jsl +JSSTYLE ?= jsstyle +MKDIR ?= mkdir -p +MV ?= mv +RESTDOWN_FLAGS ?= +RMTREE ?= rm -rf +JSL_FLAGS ?= --nologo --nosummary + +ifeq ($(shell uname -s),SunOS) + TAR ?= gtar +else + TAR ?= tar +endif + + +# +# Defaults for other fixed values. +# +BUILD = build +DISTCLEAN_FILES += $(BUILD) +DOC_BUILD = $(BUILD)/docs/public + +# +# Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}. +# +ifneq ($(origin JSL_CONF_NODE), undefined) + JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE) +endif + +ifneq ($(origin JSL_CONF_WEB), undefined) + JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB) +endif + +# +# Targets. For descriptions on what these are supposed to do, see the +# Joyent Engineering Guide. +# + +# +# Instruct make to keep around temporary files. We have rules below that +# automatically update git submodules as needed, but they employ a deps/*/.git +# temporary file. Without this directive, make tries to remove these .git +# directories after the build has completed. +# +.SECONDARY: $($(wildcard deps/*):%=%/.git) + +# +# This rule enables other rules that use files from a git submodule to have +# those files depend on deps/module/.git and have "make" automatically check +# out the submodule as needed. +# +deps/%/.git: + git submodule update --init deps/$* + +# +# These recipes make heavy use of dynamically-created phony targets. The parent +# Makefile defines a list of input files like BASH_FILES. We then say that each +# of these files depends on a fake target called filename.bashchk, and then we +# define a pattern rule for those targets that runs bash in check-syntax-only +# mode. This mechanism has the nice properties that if you specify zero files, +# the rule becomes a noop (unlike a single rule to check all bash files, which +# would invoke bash with zero files), and you can check individual files from +# the command line with "make filename.bashchk". +# +.PHONY: check-bash +check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) + +%.bashchk: % + $(BASH) -n $^ + +%.bashstyle: % + $(BASHSTYLE) $^ + +.PHONY: check-jsl check-jsl-node check-jsl-web +check-jsl: check-jsl-node check-jsl-web + +check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk) + +check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk) + +%.jslnodechk: % $(JSL_EXEC) + $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $< + +%.jslwebchk: % $(JSL_EXEC) + $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $< + +.PHONY: check-jsstyle +check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk) + +%.jsstylechk: % $(JSSTYLE_EXEC) + $(JSSTYLE) $(JSSTYLE_FLAGS) $< + +.PHONY: check +check: check-jsl check-jsstyle check-bash + @echo check ok + +.PHONY: clean +clean:: + -$(RMTREE) $(CLEAN_FILES) + +.PHONY: distclean +distclean:: clean + -$(RMTREE) $(DISTCLEAN_FILES) + +CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out +CLEAN_FILES += $(CSCOPE_FILES) + +.PHONY: xref +xref: cscope.files + $(CSCOPE) -bqR + +.PHONY: cscope.files +cscope.files: + find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \ + -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@ + +# +# The "docs" target is complicated because we do several things here: +# +# (1) Use restdown to build HTML and JSON files from each of DOC_FILES. +# +# (2) Copy these files into $(DOC_BUILD) (build/docs/public), which +# functions as a complete copy of the documentation that could be +# mirrored or served over HTTP. +# +# (3) Then copy any directories and media from docs/media into +# $(DOC_BUILD)/media. This allows projects to include their own media, +# including files that will override same-named files provided by +# restdown. +# +# Step (3) is the surprisingly complex part: in order to do this, we need to +# identify the subdirectories in docs/media, recreate them in +# $(DOC_BUILD)/media, then do the same with the files. +# +DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$") +DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%) +DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%) + +DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null) +DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%) +DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) + +# +# Like the other targets, "docs" just depends on the final files we want to +# create in $(DOC_BUILD), leveraging other targets and recipes to define how +# to get there. +# +.PHONY: docs +docs: \ + $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ + $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ + $(DOC_MEDIA_FILES_BUILD) + +# +# We keep the intermediate files so that the next build can see whether the +# files in DOC_BUILD are up to date. +# +.PRECIOUS: \ + $(DOC_FILES:%.restdown=docs/%.html) \ + $(DOC_FILES:%.restdown=docs/%json) + +# +# We do clean those intermediate files, as well as all of DOC_BUILD. +# +CLEAN_FILES += \ + $(DOC_BUILD) \ + $(DOC_FILES:%.restdown=docs/%.html) \ + $(DOC_FILES:%.restdown=docs/%.json) + +# +# Before installing the files, we must make sure the directories exist. The | +# syntax tells make that the dependency need only exist, not be up to date. +# Otherwise, it might try to rebuild spuriously because the directory itself +# appears out of date. +# +$(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) + +$(DOC_BUILD)/%: docs/% | $(DOC_BUILD) + $(CP) $< $@ + +docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) + $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< + +$(DOC_BUILD): + $(MKDIR) $@ + +$(DOC_MEDIA_DIRS_BUILD): + $(MKDIR) $@ + +# +# The default "test" target does nothing. This should usually be overridden by +# the parent Makefile. It's included here so we can define "prepush" without +# requiring the repo to define "test". +# +.PHONY: test +test: + +.PHONY: prepush +prepush: check test diff --git a/node_modules/extsprintf/README.md b/node_modules/extsprintf/README.md new file mode 100644 index 0000000..b22998d --- /dev/null +++ b/node_modules/extsprintf/README.md @@ -0,0 +1,46 @@ +# extsprintf: extended POSIX-style sprintf + +Stripped down version of s[n]printf(3c). We make a best effort to throw an +exception when given a format string we don't understand, rather than ignoring +it, so that we won't break existing programs if/when we go implement the rest +of this. + +This implementation currently supports specifying + +* field alignment ('-' flag), +* zero-pad ('0' flag) +* always show numeric sign ('+' flag), +* field width +* conversions for strings, decimal integers, and floats (numbers). +* argument size specifiers. These are all accepted but ignored, since + Javascript has no notion of the physical size of an argument. + +Everything else is currently unsupported, most notably: precision, unsigned +numbers, non-decimal numbers, and characters. + +Besides the usual POSIX conversions, this implementation supports: + +* `%j`: pretty-print a JSON object (using node's "inspect") +* `%r`: pretty-print an Error object + +# Example + +First, install it: + + # npm install extsprintf + +Now, use it: + + var mod_extsprintf = require('extsprintf'); + console.log(mod_extsprintf.sprintf('hello %25s', 'world')); + +outputs: + + hello world + +# Also supported + +**printf**: same args as sprintf, but prints the result to stdout + +**fprintf**: same args as sprintf, preceded by a Node stream. Prints the result +to the given stream. diff --git a/node_modules/extsprintf/jsl.node.conf b/node_modules/extsprintf/jsl.node.conf new file mode 100644 index 0000000..03f787f --- /dev/null +++ b/node_modules/extsprintf/jsl.node.conf @@ -0,0 +1,137 @@ +# +# Configuration File for JavaScript Lint +# +# This configuration file can be used to lint a collection of scripts, or to enable +# or disable warnings for scripts that are linted via the command line. +# + +### Warnings +# Enable or disable warnings based on requirements. +# Use "+WarningName" to display or "-WarningName" to suppress. +# ++ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent ++ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity ++ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement ++anon_no_return_value # anonymous function does not always return value ++assign_to_function_call # assignment to a function call +-block_without_braces # block statement without curly braces ++comma_separated_stmts # multiple statements separated by commas (use semicolons?) ++comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) ++default_not_at_end # the default case is not at the end of the switch statement ++dup_option_explicit # duplicate "option explicit" control comment ++duplicate_case_in_switch # duplicate case in switch statement ++duplicate_formal # duplicate formal argument {name} ++empty_statement # empty statement or extra semicolon ++identifier_hides_another # identifer {name} hides an identifier in a parent scope +-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement ++incorrect_version # Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version. ++invalid_fallthru # unexpected "fallthru" control comment ++invalid_pass # unexpected "pass" control comment ++jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax ++leading_decimal_point # leading decimal point may indicate a number or an object member ++legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax ++meaningless_block # meaningless block; curly braces have no impact ++mismatch_ctrl_comments # mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence ++misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma ++missing_break # missing break statement ++missing_break_for_last_case # missing break statement for last case in switch ++missing_default_case # missing default case in switch statement ++missing_option_explicit # the "option explicit" control comment is missing ++missing_semicolon # missing semicolon ++missing_semicolon_for_lambda # missing semicolon for lambda assignment ++multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs ++nested_comment # nested comment ++no_return_value # function {name} does not always return a value ++octal_number # leading zeros make an octal number ++parseint_missing_radix # parseInt missing radix parameter ++partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag ++redeclared_var # redeclaration of {name} ++trailing_comma_in_array # extra comma is not recommended in array initializers ++trailing_decimal_point # trailing decimal point may indicate a number or an object member ++undeclared_identifier # undeclared identifier: {name} ++unreachable_code # unreachable code +-unreferenced_argument # argument declared but never referenced: {name} +-unreferenced_function # function is declared but never referenced: {name} ++unreferenced_variable # variable is declared but never referenced: {name} ++unsupported_version # JavaScript {version} is not supported ++use_of_label # use of label ++useless_assign # useless assignment ++useless_comparison # useless comparison; comparing identical expressions +-useless_quotes # the quotation marks are unnecessary ++useless_void # use of the void type may be unnecessary (void is always undefined) ++var_hides_arg # variable {name} hides argument ++want_assign_or_call # expected an assignment or function call ++with_statement # with statement hides undeclared variables; use temporary variable instead + + +### Output format +# Customize the format of the error message. +# __FILE__ indicates current file path +# __FILENAME__ indicates current file name +# __LINE__ indicates current line +# __COL__ indicates current column +# __ERROR__ indicates error message (__ERROR_PREFIX__: __ERROR_MSG__) +# __ERROR_NAME__ indicates error name (used in configuration file) +# __ERROR_PREFIX__ indicates error prefix +# __ERROR_MSG__ indicates error message +# +# For machine-friendly output, the output format can be prefixed with +# "encode:". If specified, all items will be encoded with C-slashes. +# +# Visual Studio syntax (default): ++output-format __FILE__(__LINE__): __ERROR__ +# Alternative syntax: +#+output-format __FILE__:__LINE__: __ERROR__ + + +### Context +# Show the in-line position of the error. +# Use "+context" to display or "-context" to suppress. +# ++context + + +### Control Comments +# Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for +# the /*@keyword@*/ control comments and JScript conditional comments. (The latter is +# enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason, +# although legacy control comments are enabled by default for backward compatibility. +# +-legacy_control_comments + + +### Defining identifiers +# By default, "option explicit" is enabled on a per-file basis. +# To enable this for all files, use "+always_use_option_explicit" +-always_use_option_explicit + +# Define certain identifiers of which the lint is not aware. +# (Use this in conjunction with the "undeclared identifier" warning.) +# +# Common uses for webpages might be: ++define __dirname ++define clearInterval ++define clearTimeout ++define console ++define exports ++define global ++define process ++define require ++define setInterval ++define setTimeout ++define Buffer ++define JSON ++define Math + +### JavaScript Version +# To change the default JavaScript version: +#+default-type text/javascript;version=1.5 +#+default-type text/javascript;e4x=1 + +### Files +# Specify which files to lint +# Use "+recurse" to enable recursion (disabled by default). +# To add a set of files, use "+process FileName", "+process Folder\Path\*.js", +# or "+process Folder\Path\*.htm". +# + diff --git a/node_modules/extsprintf/lib/extsprintf.js b/node_modules/extsprintf/lib/extsprintf.js new file mode 100644 index 0000000..d5d8ad9 --- /dev/null +++ b/node_modules/extsprintf/lib/extsprintf.js @@ -0,0 +1,225 @@ +/* + * extsprintf.js: extended POSIX-style sprintf + */ + +var mod_assert = require('assert'); +var mod_util = require('util'); + +/* + * Public interface + */ +exports.sprintf = jsSprintf; +exports.printf = jsPrintf; +exports.fprintf = jsFprintf; + +/* + * Stripped down version of s[n]printf(3c). We make a best effort to throw an + * exception when given a format string we don't understand, rather than + * ignoring it, so that we won't break existing programs if/when we go implement + * the rest of this. + * + * This implementation currently supports specifying + * - field alignment ('-' flag), + * - zero-pad ('0' flag) + * - always show numeric sign ('+' flag), + * - field width + * - conversions for strings, decimal integers, and floats (numbers). + * - argument size specifiers. These are all accepted but ignored, since + * Javascript has no notion of the physical size of an argument. + * + * Everything else is currently unsupported, most notably precision, unsigned + * numbers, non-decimal numbers, and characters. + */ +function jsSprintf(ofmt) +{ + var regex = [ + '([^%]*)', /* normal text */ + '%', /* start of format */ + '([\'\\-+ #0]*?)', /* flags (optional) */ + '([1-9]\\d*)?', /* width (optional) */ + '(\\.([1-9]\\d*))?', /* precision (optional) */ + '[lhjztL]*?', /* length mods (ignored) */ + '([diouxXfFeEgGaAcCsSp%jr])' /* conversion */ + ].join(''); + + var re = new RegExp(regex); + + /* variadic arguments used to fill in conversion specifiers */ + var args = Array.prototype.slice.call(arguments, 1); + /* remaining format string */ + var fmt = ofmt; + + /* components of the current conversion specifier */ + var flags, width, precision, conversion; + var left, pad, sign, arg, match; + + /* return value */ + var ret = ''; + + /* current variadic argument (1-based) */ + var argn = 1; + /* 0-based position in the format string that we've read */ + var posn = 0; + /* 1-based position in the format string of the current conversion */ + var convposn; + /* current conversion specifier */ + var curconv; + + mod_assert.equal('string', typeof (fmt), + 'first argument must be a format string'); + + while ((match = re.exec(fmt)) !== null) { + ret += match[1]; + fmt = fmt.substring(match[0].length); + + /* + * Update flags related to the current conversion specifier's + * position so that we can report clear error messages. + */ + curconv = match[0].substring(match[1].length); + convposn = posn + match[1].length + 1; + posn += match[0].length; + + flags = match[2] || ''; + width = match[3] || 0; + precision = match[4] || ''; + conversion = match[6]; + left = false; + sign = false; + pad = ' '; + + if (conversion == '%') { + ret += '%'; + continue; + } + + if (args.length === 0) { + throw (jsError(ofmt, convposn, curconv, + 'has no matching argument ' + + '(too few arguments passed)')); + } + + arg = args.shift(); + argn++; + + if (flags.match(/[\' #]/)) { + throw (jsError(ofmt, convposn, curconv, + 'uses unsupported flags')); + } + + if (precision.length > 0) { + throw (jsError(ofmt, convposn, curconv, + 'uses non-zero precision (not supported)')); + } + + if (flags.match(/-/)) + left = true; + + if (flags.match(/0/)) + pad = '0'; + + if (flags.match(/\+/)) + sign = true; + + switch (conversion) { + case 's': + if (arg === undefined || arg === null) { + throw (jsError(ofmt, convposn, curconv, + 'attempted to print undefined or null ' + + 'as a string (argument ' + argn + ' to ' + + 'sprintf)')); + } + ret += doPad(pad, width, left, arg.toString()); + break; + + case 'd': + arg = Math.floor(arg); + /*jsl:fallthru*/ + case 'f': + sign = sign && arg > 0 ? '+' : ''; + ret += sign + doPad(pad, width, left, + arg.toString()); + break; + + case 'x': + ret += doPad(pad, width, left, arg.toString(16)); + break; + + case 'j': /* non-standard */ + if (width === 0) + width = 10; + ret += mod_util.inspect(arg, false, width); + break; + + case 'r': /* non-standard */ + ret += dumpException(arg); + break; + + default: + throw (jsError(ofmt, convposn, curconv, + 'is not supported')); + } + } + + ret += fmt; + return (ret); +} + +function jsError(fmtstr, convposn, curconv, reason) { + mod_assert.equal(typeof (fmtstr), 'string'); + mod_assert.equal(typeof (curconv), 'string'); + mod_assert.equal(typeof (convposn), 'number'); + mod_assert.equal(typeof (reason), 'string'); + return (new Error('format string "' + fmtstr + + '": conversion specifier "' + curconv + '" at character ' + + convposn + ' ' + reason)); +} + +function jsPrintf() { + var args = Array.prototype.slice.call(arguments); + args.unshift(process.stdout); + jsFprintf.apply(null, args); +} + +function jsFprintf(stream) { + var args = Array.prototype.slice.call(arguments, 1); + return (stream.write(jsSprintf.apply(this, args))); +} + +function doPad(chr, width, left, str) +{ + var ret = str; + + while (ret.length < width) { + if (left) + ret += chr; + else + ret = chr + ret; + } + + return (ret); +} + +/* + * This function dumps long stack traces for exceptions having a cause() method. + * See node-verror for an example. + */ +function dumpException(ex) +{ + var ret; + + if (!(ex instanceof Error)) + throw (new Error(jsSprintf('invalid type for %%r: %j', ex))); + + /* Note that V8 prepends "ex.stack" with ex.toString(). */ + ret = 'EXCEPTION: ' + ex.constructor.name + ': ' + ex.stack; + + if (ex.cause && typeof (ex.cause) === 'function') { + var cex = ex.cause(); + if (cex) { + ret += '\nCaused by: ' + dumpException(cex); + } + } + + return (ret); +} diff --git a/node_modules/extsprintf/package.json b/node_modules/extsprintf/package.json new file mode 100644 index 0000000..62625b8 --- /dev/null +++ b/node_modules/extsprintf/package.json @@ -0,0 +1,14 @@ +{ + "name": "extsprintf", + "version": "1.4.1", + "description": "extended POSIX-style sprintf", + "main": "./lib/extsprintf.js", + "repository": { + "type": "git", + "url": "https://github.com/davepacheco/node-extsprintf.git" + }, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" +} diff --git a/node_modules/extsprintf/test/tst.basic.js b/node_modules/extsprintf/test/tst.basic.js new file mode 100644 index 0000000..9e56fda --- /dev/null +++ b/node_modules/extsprintf/test/tst.basic.js @@ -0,0 +1,118 @@ +/* + * tst.basic.js: tests various valid invocation + */ + +var mod_assert = require('assert'); +var mod_extsprintf = require('../lib/extsprintf'); +var mod_path = require('path'); +var sprintf = mod_extsprintf.sprintf; + +var testcases = [ { + 'name': 'empty string', + 'args': [ '' ], + 'result': '' +}, { + 'name': '%s: basic', + 'args': [ '%s', 'foo' ], + 'result': 'foo' +}, { + 'name': '%s: not first', + 'args': [ 'hello %s\n', 'world' ], + 'result': 'hello world\n' +}, { + 'name': '%s: right-aligned', + 'args': [ 'hello %10s\n', 'world' ], + 'result': 'hello world\n' +}, { + 'name': '%s: left-aligned', + 'args': [ 'hello %-10sagain\n', 'world' ], + 'result': 'hello world again\n' +}, { + 'name': '%d: basic, positive', + 'args': [ '%d', 17 ], + 'result': '17' +}, { + 'name': '%d: basic, zero', + 'args': [ '%d', 0 ], + 'result': '0' +}, { + 'name': '%d: basic, floating point value', + 'args': [ '%d', 17.3 ], + 'result': '17' +}, { + 'name': '%d: basic, negative', + 'args': [ '%d', -3 ], + 'result': '-3' +}, { + 'name': '%d: right-aligned', + 'args': [ '%4d', 17 ], + 'result': ' 17' +}, { + 'name': '%d: right-aligned, zero-padded', + 'args': [ '%04d', 17 ], + 'result': '0017' +}, { + 'name': '%d: left-aligned', + 'args': [ '%-4d', 17 ], + 'result': '17 ' +}, { + 'name': '%x: basic', + 'args': [ '%x', 18], + 'result': '12' +}, { + 'name': '%x: zero-padded, right-aligned', + 'args': [ '%08x', 0xfeedface ], + 'result': 'feedface' +}, { + 'name': '%d: with plus sign', + 'args': [ '%+d', 17 ], + 'result': '+17' +}, { + 'name': '%f: basic', + 'args': [ '%f', 3.2 ], + 'result': '3.2' +}, { + 'name': '%f: right-aligned', + 'args': [ '%5f', 3.2 ], + 'result': ' 3.2' +}, { + 'name': '%%: basic', + 'args': [ '%%' ], + 'result': '%' +}, { + 'name': 'complex', + 'args': [ 'one %s %8s %-3d bytes past 0x%04x, which was %6f%%%s%5s', + 'program', 'wrote', -2, 0x30, 3.7, ' plus', 'over' ], + 'result': 'one program wrote -2 bytes past 0x0030, which was ' + + '3.7% plus over' +} ]; + +function main(verbose) { + /* + * Create one test case with a very large input string. + */ + var input = '1234'; + while (input.length < 100 * 1024) { + input += input; + } + testcases.push({ + 'name': 'long string argument (' + input.length + ' characters)', + 'args': [ '%s', input ], + 'result': input + }); + + testcases.forEach(function (tc) { + var result; + console.error('test case: %s', tc.name); + result = sprintf.apply(null, tc.args); + if (verbose) { + console.error(' args: %s', JSON.stringify(tc.args)); + console.error(' result: %s', result); + } + mod_assert.equal(tc.result, result); + }); + + console.log('%s tests passed', mod_path.basename(__filename)); +} + +main(process.argv.length > 2 && process.argv[2] == '-v'); diff --git a/node_modules/extsprintf/test/tst.invalid.js b/node_modules/extsprintf/test/tst.invalid.js new file mode 100644 index 0000000..1a7a560 --- /dev/null +++ b/node_modules/extsprintf/test/tst.invalid.js @@ -0,0 +1,78 @@ +/* + * tst.invalid.js: tests invalid invocations + */ + +var mod_assert = require('assert'); +var mod_extsprintf = require('../lib/extsprintf'); +var mod_path = require('path'); +var sprintf = mod_extsprintf.sprintf; + +var testcases = [ { + 'name': 'missing all arguments', + 'args': [], + 'errmsg': /first argument must be a format string$/ +}, { + 'name': 'missing argument for format specifier (first char and specifier)', + 'args': [ '%s' ], + 'errmsg': new RegExp( + 'format string "%s": conversion specifier "%s" at character 1 ' + + 'has no matching argument \\(too few arguments passed\\)') +}, { + 'name': 'missing argument for format specifier (later in string)', + 'args': [ 'hello %s world %13d', 'big' ], + 'errmsg': new RegExp( + 'format string "hello %s world %13d": conversion specifier "%13d" at ' + + 'character 16 has no matching argument \\(too few arguments passed\\)') +}, { + 'name': 'printing null as string', + 'args': [ '%d cookies %3s', 15, null ], + 'errmsg': new RegExp( + 'format string "%d cookies %3s": conversion specifier "%3s" at ' + + 'character 12 attempted to print undefined or null as a string ' + + '\\(argument 3 to sprintf\\)') +}, { + 'name': 'printing undefined as string', + 'args': [ '%d cookies %3s ah %d', 15, undefined, 7 ], + 'errmsg': new RegExp( + 'format string "%d cookies %3s ah %d": conversion specifier "%3s" at ' + + 'character 12 attempted to print undefined or null as a string ' + + '\\(argument 3 to sprintf\\)') +}, { + 'name': 'unsupported format character', + 'args': [ 'do not use %X', 13 ], + 'errmsg': new RegExp( + 'format string "do not use %X": conversion ' + + 'specifier "%X" at character 12 is not supported$') +}, { + 'name': 'unsupported flags', + 'args': [ '%#x', 13 ], + 'errmsg': new RegExp( + 'format string "%#x": conversion ' + + 'specifier "%#x" at character 1 uses unsupported flags$') +} ]; + +function main(verbose) { + testcases.forEach(function (tc) { + var error; + console.error('test case: %s', tc.name); + if (verbose) { + console.error(' args: %s', JSON.stringify(tc.args)); + } + mod_assert.throws(function () { + try { + sprintf.apply(null, tc.args); + } catch (ex) { + error = ex; + throw (ex); + } + }, tc.errmsg); + + if (verbose && error) { + console.error(' error: %s', error.message); + } + }); + + console.log('%s tests passed', mod_path.basename(__filename)); +} + +main(process.argv.length > 2 && process.argv[2] == '-v'); diff --git a/node_modules/follow-redirects/LICENSE b/node_modules/follow-redirects/LICENSE new file mode 100644 index 0000000..742cbad --- /dev/null +++ b/node_modules/follow-redirects/LICENSE @@ -0,0 +1,18 @@ +Copyright 2014–present Olivier Lalonde , James Talmage , Ruben Verborgh + +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. diff --git a/node_modules/follow-redirects/README.md b/node_modules/follow-redirects/README.md new file mode 100644 index 0000000..eb869a6 --- /dev/null +++ b/node_modules/follow-redirects/README.md @@ -0,0 +1,155 @@ +## Follow Redirects + +Drop-in replacement for Node's `http` and `https` modules that automatically follows redirects. + +[![npm version](https://img.shields.io/npm/v/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects) +[![Build Status](https://github.com/follow-redirects/follow-redirects/workflows/CI/badge.svg)](https://github.com/follow-redirects/follow-redirects/actions) +[![Coverage Status](https://coveralls.io/repos/follow-redirects/follow-redirects/badge.svg?branch=master)](https://coveralls.io/r/follow-redirects/follow-redirects?branch=master) +[![npm downloads](https://img.shields.io/npm/dm/follow-redirects.svg)](https://www.npmjs.com/package/follow-redirects) +[![Sponsor on GitHub](https://img.shields.io/static/v1?label=Sponsor&message=%F0%9F%92%96&logo=GitHub)](https://github.com/sponsors/RubenVerborgh) + +`follow-redirects` provides [request](https://nodejs.org/api/http.html#http_http_request_options_callback) and [get](https://nodejs.org/api/http.html#http_http_get_options_callback) + methods that behave identically to those found on the native [http](https://nodejs.org/api/http.html#http_http_request_options_callback) and [https](https://nodejs.org/api/https.html#https_https_request_options_callback) + modules, with the exception that they will seamlessly follow redirects. + +```javascript +const { http, https } = require('follow-redirects'); + +http.get('http://bit.ly/900913', response => { + response.on('data', chunk => { + console.log(chunk); + }); +}).on('error', err => { + console.error(err); +}); +``` + +You can inspect the final redirected URL through the `responseUrl` property on the `response`. +If no redirection happened, `responseUrl` is the original request URL. + +```javascript +const request = https.request({ + host: 'bitly.com', + path: '/UHfDGO', +}, response => { + console.log(response.responseUrl); + // 'http://duckduckgo.com/robots.txt' +}); +request.end(); +``` + +## Options +### Global options +Global options are set directly on the `follow-redirects` module: + +```javascript +const followRedirects = require('follow-redirects'); +followRedirects.maxRedirects = 10; +followRedirects.maxBodyLength = 20 * 1024 * 1024; // 20 MB +``` + +The following global options are supported: + +- `maxRedirects` (default: `21`) – sets the maximum number of allowed redirects; if exceeded, an error will be emitted. + +- `maxBodyLength` (default: 10MB) – sets the maximum size of the request body; if exceeded, an error will be emitted. + +### Per-request options +Per-request options are set by passing an `options` object: + +```javascript +const url = require('url'); +const { http, https } = require('follow-redirects'); + +const options = url.parse('http://bit.ly/900913'); +options.maxRedirects = 10; +options.beforeRedirect = (options, response, request) => { + // Use this to adjust the request options upon redirecting, + // to inspect the latest response headers, + // or to cancel the request by throwing an error + + // response.headers = the redirect response headers + // response.statusCode = the redirect response code (eg. 301, 307, etc.) + + // request.url = the requested URL that resulted in a redirect + // request.headers = the headers in the request that resulted in a redirect + // request.method = the method of the request that resulted in a redirect + if (options.hostname === "example.com") { + options.auth = "user:password"; + } +}; +http.request(options); +``` + +In addition to the [standard HTTP](https://nodejs.org/api/http.html#http_http_request_options_callback) and [HTTPS options](https://nodejs.org/api/https.html#https_https_request_options_callback), +the following per-request options are supported: +- `followRedirects` (default: `true`) – whether redirects should be followed. + +- `maxRedirects` (default: `21`) – sets the maximum number of allowed redirects; if exceeded, an error will be emitted. + +- `maxBodyLength` (default: 10MB) – sets the maximum size of the request body; if exceeded, an error will be emitted. + +- `beforeRedirect` (default: `undefined`) – optionally change the request `options` on redirects, or abort the request by throwing an error. + +- `agents` (default: `undefined`) – sets the `agent` option per protocol, since HTTP and HTTPS use different agents. Example value: `{ http: new http.Agent(), https: new https.Agent() }` + +- `trackRedirects` (default: `false`) – whether to store the redirected response details into the `redirects` array on the response object. + + +### Advanced usage +By default, `follow-redirects` will use the Node.js default implementations +of [`http`](https://nodejs.org/api/http.html) +and [`https`](https://nodejs.org/api/https.html). +To enable features such as caching and/or intermediate request tracking, +you might instead want to wrap `follow-redirects` around custom protocol implementations: + +```javascript +const { http, https } = require('follow-redirects').wrap({ + http: require('your-custom-http'), + https: require('your-custom-https'), +}); +``` + +Such custom protocols only need an implementation of the `request` method. + +## Browser Usage + +Due to the way the browser works, +the `http` and `https` browser equivalents perform redirects by default. + +By requiring `follow-redirects` this way: +```javascript +const http = require('follow-redirects/http'); +const https = require('follow-redirects/https'); +``` +you can easily tell webpack and friends to replace +`follow-redirect` by the built-in versions: + +```json +{ + "follow-redirects/http" : "http", + "follow-redirects/https" : "https" +} +``` + +## Contributing + +Pull Requests are always welcome. Please [file an issue](https://github.com/follow-redirects/follow-redirects/issues) + detailing your proposal before you invest your valuable time. Additional features and bug fixes should be accompanied + by tests. You can run the test suite locally with a simple `npm test` command. + +## Debug Logging + +`follow-redirects` uses the excellent [debug](https://www.npmjs.com/package/debug) for logging. To turn on logging + set the environment variable `DEBUG=follow-redirects` for debug output from just this module. When running the test + suite it is sometimes advantageous to set `DEBUG=*` to see output from the express server as well. + +## Authors + +- [Ruben Verborgh](https://ruben.verborgh.org/) +- [Olivier Lalonde](mailto:olalonde@gmail.com) +- [James Talmage](mailto:james@talmage.io) + +## License + +[MIT License](https://github.com/follow-redirects/follow-redirects/blob/master/LICENSE) diff --git a/node_modules/follow-redirects/debug.js b/node_modules/follow-redirects/debug.js new file mode 100644 index 0000000..decb77d --- /dev/null +++ b/node_modules/follow-redirects/debug.js @@ -0,0 +1,15 @@ +var debug; + +module.exports = function () { + if (!debug) { + try { + /* eslint global-require: off */ + debug = require("debug")("follow-redirects"); + } + catch (error) { /* */ } + if (typeof debug !== "function") { + debug = function () { /* */ }; + } + } + debug.apply(null, arguments); +}; diff --git a/node_modules/follow-redirects/http.js b/node_modules/follow-redirects/http.js new file mode 100644 index 0000000..695e356 --- /dev/null +++ b/node_modules/follow-redirects/http.js @@ -0,0 +1 @@ +module.exports = require("./").http; diff --git a/node_modules/follow-redirects/https.js b/node_modules/follow-redirects/https.js new file mode 100644 index 0000000..d21c921 --- /dev/null +++ b/node_modules/follow-redirects/https.js @@ -0,0 +1 @@ +module.exports = require("./").https; diff --git a/node_modules/follow-redirects/index.js b/node_modules/follow-redirects/index.js new file mode 100644 index 0000000..a30b32c --- /dev/null +++ b/node_modules/follow-redirects/index.js @@ -0,0 +1,686 @@ +var url = require("url"); +var URL = url.URL; +var http = require("http"); +var https = require("https"); +var Writable = require("stream").Writable; +var assert = require("assert"); +var debug = require("./debug"); + +// Preventive platform detection +// istanbul ignore next +(function detectUnsupportedEnvironment() { + var looksLikeNode = typeof process !== "undefined"; + var looksLikeBrowser = typeof window !== "undefined" && typeof document !== "undefined"; + var looksLikeV8 = isFunction(Error.captureStackTrace); + if (!looksLikeNode && (looksLikeBrowser || !looksLikeV8)) { + console.warn("The follow-redirects package should be excluded from browser builds."); + } +}()); + +// Whether to use the native URL object or the legacy url module +var useNativeURL = false; +try { + assert(new URL("")); +} +catch (error) { + useNativeURL = error.code === "ERR_INVALID_URL"; +} + +// URL fields to preserve in copy operations +var preservedUrlFields = [ + "auth", + "host", + "hostname", + "href", + "path", + "pathname", + "port", + "protocol", + "query", + "search", + "hash", +]; + +// Create handlers that pass events from native requests +var events = ["abort", "aborted", "connect", "error", "socket", "timeout"]; +var eventHandlers = Object.create(null); +events.forEach(function (event) { + eventHandlers[event] = function (arg1, arg2, arg3) { + this._redirectable.emit(event, arg1, arg2, arg3); + }; +}); + +// Error types with codes +var InvalidUrlError = createErrorType( + "ERR_INVALID_URL", + "Invalid URL", + TypeError +); +var RedirectionError = createErrorType( + "ERR_FR_REDIRECTION_FAILURE", + "Redirected request failed" +); +var TooManyRedirectsError = createErrorType( + "ERR_FR_TOO_MANY_REDIRECTS", + "Maximum number of redirects exceeded", + RedirectionError +); +var MaxBodyLengthExceededError = createErrorType( + "ERR_FR_MAX_BODY_LENGTH_EXCEEDED", + "Request body larger than maxBodyLength limit" +); +var WriteAfterEndError = createErrorType( + "ERR_STREAM_WRITE_AFTER_END", + "write after end" +); + +// istanbul ignore next +var destroy = Writable.prototype.destroy || noop; + +// An HTTP(S) request that can be redirected +function RedirectableRequest(options, responseCallback) { + // Initialize the request + Writable.call(this); + this._sanitizeOptions(options); + this._options = options; + this._ended = false; + this._ending = false; + this._redirectCount = 0; + this._redirects = []; + this._requestBodyLength = 0; + this._requestBodyBuffers = []; + + // Attach a callback if passed + if (responseCallback) { + this.on("response", responseCallback); + } + + // React to responses of native requests + var self = this; + this._onNativeResponse = function (response) { + try { + self._processResponse(response); + } + catch (cause) { + self.emit("error", cause instanceof RedirectionError ? + cause : new RedirectionError({ cause: cause })); + } + }; + + // Perform the first request + this._performRequest(); +} +RedirectableRequest.prototype = Object.create(Writable.prototype); + +RedirectableRequest.prototype.abort = function () { + destroyRequest(this._currentRequest); + this._currentRequest.abort(); + this.emit("abort"); +}; + +RedirectableRequest.prototype.destroy = function (error) { + destroyRequest(this._currentRequest, error); + destroy.call(this, error); + return this; +}; + +// Writes buffered data to the current native request +RedirectableRequest.prototype.write = function (data, encoding, callback) { + // Writing is not allowed if end has been called + if (this._ending) { + throw new WriteAfterEndError(); + } + + // Validate input and shift parameters if necessary + if (!isString(data) && !isBuffer(data)) { + throw new TypeError("data should be a string, Buffer or Uint8Array"); + } + if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + + // Ignore empty buffers, since writing them doesn't invoke the callback + // https://github.com/nodejs/node/issues/22066 + if (data.length === 0) { + if (callback) { + callback(); + } + return; + } + // Only write when we don't exceed the maximum body length + if (this._requestBodyLength + data.length <= this._options.maxBodyLength) { + this._requestBodyLength += data.length; + this._requestBodyBuffers.push({ data: data, encoding: encoding }); + this._currentRequest.write(data, encoding, callback); + } + // Error when we exceed the maximum body length + else { + this.emit("error", new MaxBodyLengthExceededError()); + this.abort(); + } +}; + +// Ends the current native request +RedirectableRequest.prototype.end = function (data, encoding, callback) { + // Shift parameters if necessary + if (isFunction(data)) { + callback = data; + data = encoding = null; + } + else if (isFunction(encoding)) { + callback = encoding; + encoding = null; + } + + // Write data if needed and end + if (!data) { + this._ended = this._ending = true; + this._currentRequest.end(null, null, callback); + } + else { + var self = this; + var currentRequest = this._currentRequest; + this.write(data, encoding, function () { + self._ended = true; + currentRequest.end(null, null, callback); + }); + this._ending = true; + } +}; + +// Sets a header value on the current native request +RedirectableRequest.prototype.setHeader = function (name, value) { + this._options.headers[name] = value; + this._currentRequest.setHeader(name, value); +}; + +// Clears a header value on the current native request +RedirectableRequest.prototype.removeHeader = function (name) { + delete this._options.headers[name]; + this._currentRequest.removeHeader(name); +}; + +// Global timeout for all underlying requests +RedirectableRequest.prototype.setTimeout = function (msecs, callback) { + var self = this; + + // Destroys the socket on timeout + function destroyOnTimeout(socket) { + socket.setTimeout(msecs); + socket.removeListener("timeout", socket.destroy); + socket.addListener("timeout", socket.destroy); + } + + // Sets up a timer to trigger a timeout event + function startTimer(socket) { + if (self._timeout) { + clearTimeout(self._timeout); + } + self._timeout = setTimeout(function () { + self.emit("timeout"); + clearTimer(); + }, msecs); + destroyOnTimeout(socket); + } + + // Stops a timeout from triggering + function clearTimer() { + // Clear the timeout + if (self._timeout) { + clearTimeout(self._timeout); + self._timeout = null; + } + + // Clean up all attached listeners + self.removeListener("abort", clearTimer); + self.removeListener("error", clearTimer); + self.removeListener("response", clearTimer); + self.removeListener("close", clearTimer); + if (callback) { + self.removeListener("timeout", callback); + } + if (!self.socket) { + self._currentRequest.removeListener("socket", startTimer); + } + } + + // Attach callback if passed + if (callback) { + this.on("timeout", callback); + } + + // Start the timer if or when the socket is opened + if (this.socket) { + startTimer(this.socket); + } + else { + this._currentRequest.once("socket", startTimer); + } + + // Clean up on events + this.on("socket", destroyOnTimeout); + this.on("abort", clearTimer); + this.on("error", clearTimer); + this.on("response", clearTimer); + this.on("close", clearTimer); + + return this; +}; + +// Proxy all other public ClientRequest methods +[ + "flushHeaders", "getHeader", + "setNoDelay", "setSocketKeepAlive", +].forEach(function (method) { + RedirectableRequest.prototype[method] = function (a, b) { + return this._currentRequest[method](a, b); + }; +}); + +// Proxy all public ClientRequest properties +["aborted", "connection", "socket"].forEach(function (property) { + Object.defineProperty(RedirectableRequest.prototype, property, { + get: function () { return this._currentRequest[property]; }, + }); +}); + +RedirectableRequest.prototype._sanitizeOptions = function (options) { + // Ensure headers are always present + if (!options.headers) { + options.headers = {}; + } + + // Since http.request treats host as an alias of hostname, + // but the url module interprets host as hostname plus port, + // eliminate the host property to avoid confusion. + if (options.host) { + // Use hostname if set, because it has precedence + if (!options.hostname) { + options.hostname = options.host; + } + delete options.host; + } + + // Complete the URL object when necessary + if (!options.pathname && options.path) { + var searchPos = options.path.indexOf("?"); + if (searchPos < 0) { + options.pathname = options.path; + } + else { + options.pathname = options.path.substring(0, searchPos); + options.search = options.path.substring(searchPos); + } + } +}; + + +// Executes the next native request (initial or redirect) +RedirectableRequest.prototype._performRequest = function () { + // Load the native protocol + var protocol = this._options.protocol; + var nativeProtocol = this._options.nativeProtocols[protocol]; + if (!nativeProtocol) { + throw new TypeError("Unsupported protocol " + protocol); + } + + // If specified, use the agent corresponding to the protocol + // (HTTP and HTTPS use different types of agents) + if (this._options.agents) { + var scheme = protocol.slice(0, -1); + this._options.agent = this._options.agents[scheme]; + } + + // Create the native request and set up its event handlers + var request = this._currentRequest = + nativeProtocol.request(this._options, this._onNativeResponse); + request._redirectable = this; + for (var event of events) { + request.on(event, eventHandlers[event]); + } + + // RFC7230§5.3.1: When making a request directly to an origin server, […] + // a client MUST send only the absolute path […] as the request-target. + this._currentUrl = /^\//.test(this._options.path) ? + url.format(this._options) : + // When making a request to a proxy, […] + // a client MUST send the target URI in absolute-form […]. + this._options.path; + + // End a redirected request + // (The first request must be ended explicitly with RedirectableRequest#end) + if (this._isRedirect) { + // Write the request entity and end + var i = 0; + var self = this; + var buffers = this._requestBodyBuffers; + (function writeNext(error) { + // Only write if this request has not been redirected yet + // istanbul ignore else + if (request === self._currentRequest) { + // Report any write errors + // istanbul ignore if + if (error) { + self.emit("error", error); + } + // Write the next buffer if there are still left + else if (i < buffers.length) { + var buffer = buffers[i++]; + // istanbul ignore else + if (!request.finished) { + request.write(buffer.data, buffer.encoding, writeNext); + } + } + // End the request if `end` has been called on us + else if (self._ended) { + request.end(); + } + } + }()); + } +}; + +// Processes a response from the current native request +RedirectableRequest.prototype._processResponse = function (response) { + // Store the redirected response + var statusCode = response.statusCode; + if (this._options.trackRedirects) { + this._redirects.push({ + url: this._currentUrl, + headers: response.headers, + statusCode: statusCode, + }); + } + + // RFC7231§6.4: The 3xx (Redirection) class of status code indicates + // that further action needs to be taken by the user agent in order to + // fulfill the request. If a Location header field is provided, + // the user agent MAY automatically redirect its request to the URI + // referenced by the Location field value, + // even if the specific status code is not understood. + + // If the response is not a redirect; return it as-is + var location = response.headers.location; + if (!location || this._options.followRedirects === false || + statusCode < 300 || statusCode >= 400) { + response.responseUrl = this._currentUrl; + response.redirects = this._redirects; + this.emit("response", response); + + // Clean up + this._requestBodyBuffers = []; + return; + } + + // The response is a redirect, so abort the current request + destroyRequest(this._currentRequest); + // Discard the remainder of the response to avoid waiting for data + response.destroy(); + + // RFC7231§6.4: A client SHOULD detect and intervene + // in cyclical redirections (i.e., "infinite" redirection loops). + if (++this._redirectCount > this._options.maxRedirects) { + throw new TooManyRedirectsError(); + } + + // Store the request headers if applicable + var requestHeaders; + var beforeRedirect = this._options.beforeRedirect; + if (beforeRedirect) { + requestHeaders = Object.assign({ + // The Host header was set by nativeProtocol.request + Host: response.req.getHeader("host"), + }, this._options.headers); + } + + // RFC7231§6.4: Automatic redirection needs to done with + // care for methods not known to be safe, […] + // RFC7231§6.4.2–3: For historical reasons, a user agent MAY change + // the request method from POST to GET for the subsequent request. + var method = this._options.method; + if ((statusCode === 301 || statusCode === 302) && this._options.method === "POST" || + // RFC7231§6.4.4: The 303 (See Other) status code indicates that + // the server is redirecting the user agent to a different resource […] + // A user agent can perform a retrieval request targeting that URI + // (a GET or HEAD request if using HTTP) […] + (statusCode === 303) && !/^(?:GET|HEAD)$/.test(this._options.method)) { + this._options.method = "GET"; + // Drop a possible entity and headers related to it + this._requestBodyBuffers = []; + removeMatchingHeaders(/^content-/i, this._options.headers); + } + + // Drop the Host header, as the redirect might lead to a different host + var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers); + + // If the redirect is relative, carry over the host of the last request + var currentUrlParts = parseUrl(this._currentUrl); + var currentHost = currentHostHeader || currentUrlParts.host; + var currentUrl = /^\w+:/.test(location) ? this._currentUrl : + url.format(Object.assign(currentUrlParts, { host: currentHost })); + + // Create the redirected request + var redirectUrl = resolveUrl(location, currentUrl); + debug("redirecting to", redirectUrl.href); + this._isRedirect = true; + spreadUrlObject(redirectUrl, this._options); + + // Drop confidential headers when redirecting to a less secure protocol + // or to a different domain that is not a superdomain + if (redirectUrl.protocol !== currentUrlParts.protocol && + redirectUrl.protocol !== "https:" || + redirectUrl.host !== currentHost && + !isSubdomain(redirectUrl.host, currentHost)) { + removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers); + } + + // Evaluate the beforeRedirect callback + if (isFunction(beforeRedirect)) { + var responseDetails = { + headers: response.headers, + statusCode: statusCode, + }; + var requestDetails = { + url: currentUrl, + method: method, + headers: requestHeaders, + }; + beforeRedirect(this._options, responseDetails, requestDetails); + this._sanitizeOptions(this._options); + } + + // Perform the redirected request + this._performRequest(); +}; + +// Wraps the key/value object of protocols with redirect functionality +function wrap(protocols) { + // Default settings + var exports = { + maxRedirects: 21, + maxBodyLength: 10 * 1024 * 1024, + }; + + // Wrap each protocol + var nativeProtocols = {}; + Object.keys(protocols).forEach(function (scheme) { + var protocol = scheme + ":"; + var nativeProtocol = nativeProtocols[protocol] = protocols[scheme]; + var wrappedProtocol = exports[scheme] = Object.create(nativeProtocol); + + // Executes a request, following redirects + function request(input, options, callback) { + // Parse parameters, ensuring that input is an object + if (isURL(input)) { + input = spreadUrlObject(input); + } + else if (isString(input)) { + input = spreadUrlObject(parseUrl(input)); + } + else { + callback = options; + options = validateUrl(input); + input = { protocol: protocol }; + } + if (isFunction(options)) { + callback = options; + options = null; + } + + // Set defaults + options = Object.assign({ + maxRedirects: exports.maxRedirects, + maxBodyLength: exports.maxBodyLength, + }, input, options); + options.nativeProtocols = nativeProtocols; + if (!isString(options.host) && !isString(options.hostname)) { + options.hostname = "::1"; + } + + assert.equal(options.protocol, protocol, "protocol mismatch"); + debug("options", options); + return new RedirectableRequest(options, callback); + } + + // Executes a GET request, following redirects + function get(input, options, callback) { + var wrappedRequest = wrappedProtocol.request(input, options, callback); + wrappedRequest.end(); + return wrappedRequest; + } + + // Expose the properties on the wrapped protocol + Object.defineProperties(wrappedProtocol, { + request: { value: request, configurable: true, enumerable: true, writable: true }, + get: { value: get, configurable: true, enumerable: true, writable: true }, + }); + }); + return exports; +} + +function noop() { /* empty */ } + +function parseUrl(input) { + var parsed; + // istanbul ignore else + if (useNativeURL) { + parsed = new URL(input); + } + else { + // Ensure the URL is valid and absolute + parsed = validateUrl(url.parse(input)); + if (!isString(parsed.protocol)) { + throw new InvalidUrlError({ input }); + } + } + return parsed; +} + +function resolveUrl(relative, base) { + // istanbul ignore next + return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative)); +} + +function validateUrl(input) { + if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) { + throw new InvalidUrlError({ input: input.href || input }); + } + if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) { + throw new InvalidUrlError({ input: input.href || input }); + } + return input; +} + +function spreadUrlObject(urlObject, target) { + var spread = target || {}; + for (var key of preservedUrlFields) { + spread[key] = urlObject[key]; + } + + // Fix IPv6 hostname + if (spread.hostname.startsWith("[")) { + spread.hostname = spread.hostname.slice(1, -1); + } + // Ensure port is a number + if (spread.port !== "") { + spread.port = Number(spread.port); + } + // Concatenate path + spread.path = spread.search ? spread.pathname + spread.search : spread.pathname; + + return spread; +} + +function removeMatchingHeaders(regex, headers) { + var lastValue; + for (var header in headers) { + if (regex.test(header)) { + lastValue = headers[header]; + delete headers[header]; + } + } + return (lastValue === null || typeof lastValue === "undefined") ? + undefined : String(lastValue).trim(); +} + +function createErrorType(code, message, baseClass) { + // Create constructor + function CustomError(properties) { + // istanbul ignore else + if (isFunction(Error.captureStackTrace)) { + Error.captureStackTrace(this, this.constructor); + } + Object.assign(this, properties || {}); + this.code = code; + this.message = this.cause ? message + ": " + this.cause.message : message; + } + + // Attach constructor and set default properties + CustomError.prototype = new (baseClass || Error)(); + Object.defineProperties(CustomError.prototype, { + constructor: { + value: CustomError, + enumerable: false, + }, + name: { + value: "Error [" + code + "]", + enumerable: false, + }, + }); + return CustomError; +} + +function destroyRequest(request, error) { + for (var event of events) { + request.removeListener(event, eventHandlers[event]); + } + request.on("error", noop); + request.destroy(error); +} + +function isSubdomain(subdomain, domain) { + assert(isString(subdomain) && isString(domain)); + var dot = subdomain.length - domain.length - 1; + return dot > 0 && subdomain[dot] === "." && subdomain.endsWith(domain); +} + +function isString(value) { + return typeof value === "string" || value instanceof String; +} + +function isFunction(value) { + return typeof value === "function"; +} + +function isBuffer(value) { + return typeof value === "object" && ("length" in value); +} + +function isURL(value) { + return URL && value instanceof URL; +} + +// Exports +module.exports = wrap({ http: http, https: https }); +module.exports.wrap = wrap; diff --git a/node_modules/follow-redirects/package.json b/node_modules/follow-redirects/package.json new file mode 100644 index 0000000..a2689fa --- /dev/null +++ b/node_modules/follow-redirects/package.json @@ -0,0 +1,58 @@ +{ + "name": "follow-redirects", + "version": "1.15.11", + "description": "HTTP and HTTPS modules that follow redirects.", + "license": "MIT", + "main": "index.js", + "files": [ + "*.js" + ], + "engines": { + "node": ">=4.0" + }, + "scripts": { + "lint": "eslint *.js test", + "test": "nyc mocha" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/follow-redirects/follow-redirects.git" + }, + "homepage": "https://github.com/follow-redirects/follow-redirects", + "bugs": { + "url": "https://github.com/follow-redirects/follow-redirects/issues" + }, + "keywords": [ + "http", + "https", + "url", + "redirect", + "client", + "location", + "utility" + ], + "author": "Ruben Verborgh (https://ruben.verborgh.org/)", + "contributors": [ + "Olivier Lalonde (http://www.syskall.com)", + "James Talmage " + ], + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "peerDependenciesMeta": { + "debug": { + "optional": true + } + }, + "devDependencies": { + "concat-stream": "^2.0.0", + "eslint": "^5.16.0", + "express": "^4.16.4", + "lolex": "^3.1.0", + "mocha": "^6.0.2", + "nyc": "^14.1.1" + } +} diff --git a/node_modules/form-data/CHANGELOG.md b/node_modules/form-data/CHANGELOG.md new file mode 100644 index 0000000..449dd43 --- /dev/null +++ b/node_modules/form-data/CHANGELOG.md @@ -0,0 +1,601 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v4.0.4](https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4) - 2025-07-16 + +### Commits + +- [meta] add `auto-changelog` [`811f682`](https://github.com/form-data/form-data/commit/811f68282fab0315209d0e2d1c44b6c32ea0d479) +- [Tests] handle predict-v8-randomness failures in node < 17 and node > 23 [`1d11a76`](https://github.com/form-data/form-data/commit/1d11a76434d101f22fdb26b8aef8615f28b98402) +- [Fix] Switch to using `crypto` random for boundary values [`3d17230`](https://github.com/form-data/form-data/commit/3d1723080e6577a66f17f163ecd345a21d8d0fd0) +- [Tests] fix linting errors [`5e34080`](https://github.com/form-data/form-data/commit/5e340800b5f8914213e4e0378c084aae71cfd73a) +- [meta] actually ensure the readme backup isn’t published [`316c82b`](https://github.com/form-data/form-data/commit/316c82ba93fd4985af757b771b9a1f26d3b709ef) +- [Dev Deps] update `@ljharb/eslint-config` [`58c25d7`](https://github.com/form-data/form-data/commit/58c25d76406a5b0dfdf54045cf252563f2bbda8d) +- [meta] fix readme capitalization [`2300ca1`](https://github.com/form-data/form-data/commit/2300ca19595b0ee96431e868fe2a40db79e41c61) + +## [v4.0.3](https://github.com/form-data/form-data/compare/v4.0.2...v4.0.3) - 2025-06-05 + +### Fixed + +- [Fix] `append`: avoid a crash on nullish values [`#577`](https://github.com/form-data/form-data/issues/577) + +### Commits + +- [eslint] use a shared config [`426ba9a`](https://github.com/form-data/form-data/commit/426ba9ac440f95d1998dac9a5cd8d738043b048f) +- [eslint] fix some spacing issues [`2094191`](https://github.com/form-data/form-data/commit/20941917f0e9487e68c564ebc3157e23609e2939) +- [Refactor] use `hasown` [`81ab41b`](https://github.com/form-data/form-data/commit/81ab41b46fdf34f5d89d7ff30b513b0925febfaa) +- [Fix] validate boundary type in `setBoundary()` method [`8d8e469`](https://github.com/form-data/form-data/commit/8d8e4693093519f7f18e3c597d1e8df8c493de9e) +- [Tests] add tests to check the behavior of `getBoundary` with non-strings [`837b8a1`](https://github.com/form-data/form-data/commit/837b8a1f7562bfb8bda74f3fc538adb7a5858995) +- [Dev Deps] remove unused deps [`870e4e6`](https://github.com/form-data/form-data/commit/870e4e665935e701bf983a051244ab928e62d58e) +- [meta] remove local commit hooks [`e6e83cc`](https://github.com/form-data/form-data/commit/e6e83ccb545a5619ed6cd04f31d5c2f655eb633e) +- [Dev Deps] update `eslint` [`4066fd6`](https://github.com/form-data/form-data/commit/4066fd6f65992b62fa324a6474a9292a4f88c916) +- [meta] fix scripts to use prepublishOnly [`c4bbb13`](https://github.com/form-data/form-data/commit/c4bbb13c0ef669916657bc129341301b1d331d75) + +## [v4.0.2](https://github.com/form-data/form-data/compare/v4.0.1...v4.0.2) - 2025-02-14 + +### Merged + +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) + +### Fixed + +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) +- [Fix] set `Symbol.toStringTag` when available [`#396`](https://github.com/form-data/form-data/issues/396) + +### Commits + +- Merge tags v2.5.3 and v3.0.3 [`92613b9`](https://github.com/form-data/form-data/commit/92613b9208556eb4ebc482fdf599fae111626fb6) +- [Tests] migrate from travis to GHA [`806eda7`](https://github.com/form-data/form-data/commit/806eda77740e6e3c67c7815afb216f2e1f187ba5) +- [Tests] migrate from travis to GHA [`8fdb3bc`](https://github.com/form-data/form-data/commit/8fdb3bc6b5d001f8909a9fca391d1d1d97ef1d79) +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`7fecefe`](https://github.com/form-data/form-data/commit/7fecefe4ba8f775634aff86a698776ad95ecffb5) +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`6e682d4`](https://github.com/form-data/form-data/commit/6e682d4bd41de7e80de41e3c4ee10f23fcc3dd00) +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`df3c1e6`](https://github.com/form-data/form-data/commit/df3c1e6f0937f47a782dc4573756a54987f31dde) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`8261fcb`](https://github.com/form-data/form-data/commit/8261fcb8bf5944d30ae3bd04b91b71d6a9932ef4) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`fb66cb7`](https://github.com/form-data/form-data/commit/fb66cb740e29fb170eee947d4be6fdf82d6659af) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `eslint`, `formidable`, `in-publish`, `phantomjs-prebuilt`, `pkgfiles`, `pre-commit`, `request`, `tape`, `typescript` [`819f6b7`](https://github.com/form-data/form-data/commit/819f6b7a543306a891fca37c3a06d0ff4a734422) +- [eslint] clean up ignores [`3217b3d`](https://github.com/form-data/form-data/commit/3217b3ded8e382e51171d5c74c6038a21cc54440) +- [eslint] clean up ignores [`3a9d480`](https://github.com/form-data/form-data/commit/3a9d480232dbcbc07260ad84c3da4975d9a3ae9e) +- [Fix] `Buffer.from` and `Buffer.alloc` require node 4+ [`c499f76`](https://github.com/form-data/form-data/commit/c499f76f1faac1ddbf210c45217038e4c1e02337) +- Only apps should have lockfiles [`b82f590`](https://github.com/form-data/form-data/commit/b82f59093cdbadb4b7ec0922d33ae7ab048b82ff) +- Only apps should have lockfiles [`b170ee2`](https://github.com/form-data/form-data/commit/b170ee2b22b4c695c363b811c0c553d2fb1bbd79) +- [Deps] update `combined-stream`, `mime-types` [`6b1ca1d`](https://github.com/form-data/form-data/commit/6b1ca1dc7362a1b1c3a99a885516cca4b7eb817f) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`e5df7f2`](https://github.com/form-data/form-data/commit/e5df7f24383342264bd73dee3274818a40d04065) +- [Deps] update `mime-types` [`5a5bafe`](https://github.com/form-data/form-data/commit/5a5bafee894fead10da49e1fa2b084e17f2e1034) +- Bumped version 2.5.3 [`9457283`](https://github.com/form-data/form-data/commit/9457283e1dce6122adc908fdd7442cfc54cabe7a) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`9dbe192`](https://github.com/form-data/form-data/commit/9dbe192be3db215eac4d9c0b980470a5c2c030c6) +- Merge tags v2.5.2 and v3.0.2 [`d53265d`](https://github.com/form-data/form-data/commit/d53265d86c5153f535ec68eb107548b1b2883576) +- Bumped version 2.5.2 [`7020dd4`](https://github.com/form-data/form-data/commit/7020dd4c1260370abc40e86e3dfe49c5d576fbda) +- [Dev Deps] downgrade `cross-spawn` [`3fc1a9b`](https://github.com/form-data/form-data/commit/3fc1a9b62ddf1fe77a2bd6bd3476e4c0a9e01a88) +- fix: move util.isArray to Array.isArray (#564) [`edb555a`](https://github.com/form-data/form-data/commit/edb555a811f6f7e4668db4831551cf41c1de1cac) +- fix: move util.isArray to Array.isArray (#564) [`10418d1`](https://github.com/form-data/form-data/commit/10418d1fe4b0d65fe020eafe3911feb5ad5e2bd6) + +## [v4.0.1](https://github.com/form-data/form-data/compare/v4.0.0...v4.0.1) - 2024-10-10 + +### Commits + +- [Tests] migrate from travis to GHA [`757b4e3`](https://github.com/form-data/form-data/commit/757b4e32e95726aec9bdcc771fb5a3b564d88034) +- [eslint] clean up ignores [`e8f0d80`](https://github.com/form-data/form-data/commit/e8f0d80cd7cd424d1488532621ec40a33218b30b) +- fix (npmignore): ignore temporary build files [`335ad19`](https://github.com/form-data/form-data/commit/335ad19c6e17dc2d7298ffe0e9b37ba63600e94b) +- fix: move util.isArray to Array.isArray [`440d3be`](https://github.com/form-data/form-data/commit/440d3bed752ac2f9213b4c2229dbccefe140e5fa) + +## [v4.0.0](https://github.com/form-data/form-data/compare/v3.0.3...v4.0.0) - 2021-02-15 + +### Merged + +- Handle custom stream [`#382`](https://github.com/form-data/form-data/pull/382) + +### Commits + +- Fix typo [`e705c0a`](https://github.com/form-data/form-data/commit/e705c0a1fdaf90d21501f56460b93e43a18bd435) +- Update README for custom stream behavior [`6dd8624`](https://github.com/form-data/form-data/commit/6dd8624b2999e32768d62752c9aae5845a803b0d) + +## [v3.0.3](https://github.com/form-data/form-data/compare/v3.0.2...v3.0.3) - 2025-02-14 + +### Merged + +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) + +### Fixed + +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) + +### Commits + +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`7fecefe`](https://github.com/form-data/form-data/commit/7fecefe4ba8f775634aff86a698776ad95ecffb5) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`8261fcb`](https://github.com/form-data/form-data/commit/8261fcb8bf5944d30ae3bd04b91b71d6a9932ef4) +- Only apps should have lockfiles [`b82f590`](https://github.com/form-data/form-data/commit/b82f59093cdbadb4b7ec0922d33ae7ab048b82ff) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`e5df7f2`](https://github.com/form-data/form-data/commit/e5df7f24383342264bd73dee3274818a40d04065) +- [Deps] update `mime-types` [`5a5bafe`](https://github.com/form-data/form-data/commit/5a5bafee894fead10da49e1fa2b084e17f2e1034) + +## [v3.0.2](https://github.com/form-data/form-data/compare/v3.0.1...v3.0.2) - 2024-10-10 + +### Merged + +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) + +### Commits + +- [Tests] migrate from travis to GHA [`8fdb3bc`](https://github.com/form-data/form-data/commit/8fdb3bc6b5d001f8909a9fca391d1d1d97ef1d79) +- [eslint] clean up ignores [`3217b3d`](https://github.com/form-data/form-data/commit/3217b3ded8e382e51171d5c74c6038a21cc54440) +- fix: move util.isArray to Array.isArray (#564) [`edb555a`](https://github.com/form-data/form-data/commit/edb555a811f6f7e4668db4831551cf41c1de1cac) + +## [v3.0.1](https://github.com/form-data/form-data/compare/v3.0.0...v3.0.1) - 2021-02-15 + +### Merged + +- Fix typo: ads -> adds [`#451`](https://github.com/form-data/form-data/pull/451) + +### Commits + +- feat: add setBoundary method [`55d90ce`](https://github.com/form-data/form-data/commit/55d90ce4a4c22b0ea0647991d85cb946dfb7395b) + +## [v3.0.0](https://github.com/form-data/form-data/compare/v2.5.3...v3.0.0) - 2019-11-05 + +### Merged + +- Update Readme.md [`#449`](https://github.com/form-data/form-data/pull/449) +- Update package.json [`#448`](https://github.com/form-data/form-data/pull/448) +- fix memory leak [`#447`](https://github.com/form-data/form-data/pull/447) +- form-data: Replaced PhantomJS Dependency [`#442`](https://github.com/form-data/form-data/pull/442) +- Fix constructor options in Typescript definitions [`#446`](https://github.com/form-data/form-data/pull/446) +- Fix the getHeaders method signatures [`#434`](https://github.com/form-data/form-data/pull/434) +- Update combined-stream (fixes #422) [`#424`](https://github.com/form-data/form-data/pull/424) + +### Fixed + +- Merge pull request #424 from botgram/update-combined-stream [`#422`](https://github.com/form-data/form-data/issues/422) +- Update combined-stream (fixes #422) [`#422`](https://github.com/form-data/form-data/issues/422) + +### Commits + +- Add readable stream options to constructor type [`80c8f74`](https://github.com/form-data/form-data/commit/80c8f746bcf4c0418ae35fbedde12fb8c01e2748) +- Fixed: getHeaders method signatures [`f4ca7f8`](https://github.com/form-data/form-data/commit/f4ca7f8e31f7e07df22c1aeb8e0a32a7055a64ca) +- Pass options to constructor if not used with new [`4bde68e`](https://github.com/form-data/form-data/commit/4bde68e12de1ba90fefad2e7e643f6375b902763) +- Make userHeaders optional [`2b4e478`](https://github.com/form-data/form-data/commit/2b4e4787031490942f2d1ee55c56b85a250875a7) + +## [v2.5.3](https://github.com/form-data/form-data/compare/v2.5.2...v2.5.3) - 2025-02-14 + +### Merged + +- [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) + +### Fixed + +- [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) + +### Commits + +- [Refactor] use `Object.prototype.hasOwnProperty.call` [`6e682d4`](https://github.com/form-data/form-data/commit/6e682d4bd41de7e80de41e3c4ee10f23fcc3dd00) +- [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `eslint`, `formidable`, `in-publish`, `phantomjs-prebuilt`, `pkgfiles`, `pre-commit`, `request`, `tape`, `typescript` [`819f6b7`](https://github.com/form-data/form-data/commit/819f6b7a543306a891fca37c3a06d0ff4a734422) +- Only apps should have lockfiles [`b170ee2`](https://github.com/form-data/form-data/commit/b170ee2b22b4c695c363b811c0c553d2fb1bbd79) +- [Deps] update `combined-stream`, `mime-types` [`6b1ca1d`](https://github.com/form-data/form-data/commit/6b1ca1dc7362a1b1c3a99a885516cca4b7eb817f) +- Bumped version 2.5.3 [`9457283`](https://github.com/form-data/form-data/commit/9457283e1dce6122adc908fdd7442cfc54cabe7a) +- [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`9dbe192`](https://github.com/form-data/form-data/commit/9dbe192be3db215eac4d9c0b980470a5c2c030c6) + +## [v2.5.2](https://github.com/form-data/form-data/compare/v2.5.1...v2.5.2) - 2024-10-10 + +### Merged + +- fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) + +### Commits + +- [Tests] migrate from travis to GHA [`806eda7`](https://github.com/form-data/form-data/commit/806eda77740e6e3c67c7815afb216f2e1f187ba5) +- [eslint] clean up ignores [`3a9d480`](https://github.com/form-data/form-data/commit/3a9d480232dbcbc07260ad84c3da4975d9a3ae9e) +- [Fix] `Buffer.from` and `Buffer.alloc` require node 4+ [`c499f76`](https://github.com/form-data/form-data/commit/c499f76f1faac1ddbf210c45217038e4c1e02337) +- Bumped version 2.5.2 [`7020dd4`](https://github.com/form-data/form-data/commit/7020dd4c1260370abc40e86e3dfe49c5d576fbda) +- [Dev Deps] downgrade `cross-spawn` [`3fc1a9b`](https://github.com/form-data/form-data/commit/3fc1a9b62ddf1fe77a2bd6bd3476e4c0a9e01a88) +- fix: move util.isArray to Array.isArray (#564) [`10418d1`](https://github.com/form-data/form-data/commit/10418d1fe4b0d65fe020eafe3911feb5ad5e2bd6) + +## [v2.5.1](https://github.com/form-data/form-data/compare/v2.5.0...v2.5.1) - 2019-08-28 + +### Merged + +- Fix error in callback signatures [`#435`](https://github.com/form-data/form-data/pull/435) +- -Fixed: Eerror in the documentations as indicated in #439 [`#440`](https://github.com/form-data/form-data/pull/440) +- Add constructor options to TypeScript defs [`#437`](https://github.com/form-data/form-data/pull/437) + +### Commits + +- Add remaining combined-stream options to typedef [`4d41a32`](https://github.com/form-data/form-data/commit/4d41a32c0b3f85f8bbc9cf17df43befd2d5fc305) +- Bumped version 2.5.1 [`8ce81f5`](https://github.com/form-data/form-data/commit/8ce81f56cccf5466363a5eff135ad394a929f59b) +- Bump rimraf to 2.7.1 [`a6bc2d4`](https://github.com/form-data/form-data/commit/a6bc2d4296dbdee5d84cbab7c69bcd0eea7a12e2) + +## [v2.5.0](https://github.com/form-data/form-data/compare/v2.4.0...v2.5.0) - 2019-07-03 + +### Merged + +- - Added: public methods with information and examples to readme [`#429`](https://github.com/form-data/form-data/pull/429) +- chore: move @types/node to devDep [`#431`](https://github.com/form-data/form-data/pull/431) +- Switched windows tests from AppVeyor to Travis [`#430`](https://github.com/form-data/form-data/pull/430) +- feat(typings): migrate TS typings #427 [`#428`](https://github.com/form-data/form-data/pull/428) +- enhance the method of path.basename, handle undefined case [`#421`](https://github.com/form-data/form-data/pull/421) + +### Commits + +- - Added: public methods with information and examples to the readme file. [`21323f3`](https://github.com/form-data/form-data/commit/21323f3b4043a167046a4a2554c5f2825356c423) +- feat(typings): migrate TS typings [`a3c0142`](https://github.com/form-data/form-data/commit/a3c0142ed91b0c7dcaf89c4f618776708f1f70a9) +- - Fixed: Typos [`37350fa`](https://github.com/form-data/form-data/commit/37350fa250782f156a998ec1fa9671866d40ac49) +- Switched to Travis Windows from Appveyor [`fc61c73`](https://github.com/form-data/form-data/commit/fc61c7381fad12662df16dbc3e7621c91b886f03) +- - Fixed: rendering of subheaders [`e93ed8d`](https://github.com/form-data/form-data/commit/e93ed8df9d7f22078bc3a2c24889e9dfa11e192d) +- Updated deps and readme [`e3d8628`](https://github.com/form-data/form-data/commit/e3d8628728f6e4817ab97deeed92f0c822661b89) +- Updated dependencies [`19add50`](https://github.com/form-data/form-data/commit/19add50afb7de66c70d189f422d16f1b886616e2) +- Bumped version to 2.5.0 [`905f173`](https://github.com/form-data/form-data/commit/905f173a3f785e8d312998e765634ee451ca5f42) +- - Fixed: filesize is not a valid option? knownLength should be used for streams [`d88f912`](https://github.com/form-data/form-data/commit/d88f912b75b666b47f8674467516eade69d2d5be) +- Bump notion of modern node to node8 [`508b626`](https://github.com/form-data/form-data/commit/508b626bf1b460d3733d3420dc1cfd001617f6ac) +- enhance the method of path.basename [`faaa68a`](https://github.com/form-data/form-data/commit/faaa68a297be7d4fca0ac4709d5b93afc1f78b5c) + +## [v2.4.0](https://github.com/form-data/form-data/compare/v2.3.2...v2.4.0) - 2019-06-19 + +### Merged + +- Added "getBuffer" method and updated certificates [`#419`](https://github.com/form-data/form-data/pull/419) +- docs(readme): add axios integration document [`#425`](https://github.com/form-data/form-data/pull/425) +- Allow newer versions of combined-stream [`#402`](https://github.com/form-data/form-data/pull/402) + +### Commits + +- Updated: Certificate [`e90a76a`](https://github.com/form-data/form-data/commit/e90a76ab3dcaa63a6f3045f8255bfbb9c25a3e4e) +- Updated build/test/badges [`8512eef`](https://github.com/form-data/form-data/commit/8512eef436e28372f5bc88de3ca76a9cb46e6847) +- Bumped version 2.4.0 [`0f8da06`](https://github.com/form-data/form-data/commit/0f8da06c0b4c997bd2f6b09d78290d339616a950) +- docs(readme): remove unnecessary bracket [`4e3954d`](https://github.com/form-data/form-data/commit/4e3954dde304d27e3b95371d8c78002f3af5d5b2) +- Bumped version to 2.3.3 [`b16916a`](https://github.com/form-data/form-data/commit/b16916a568a0d06f3f8a16c31f9a8b89b7844094) + +## [v2.3.2](https://github.com/form-data/form-data/compare/v2.3.1...v2.3.2) - 2018-02-13 + +### Merged + +- Pulling in fixed combined-stream [`#379`](https://github.com/form-data/form-data/pull/379) + +### Commits + +- All the dev dependencies are breaking in old versions of node :'( [`c7dba6a`](https://github.com/form-data/form-data/commit/c7dba6a139d872d173454845e25e1850ed6b72b4) +- Updated badges [`19b6c7a`](https://github.com/form-data/form-data/commit/19b6c7a8a5c40f47f91c8a8da3e5e4dc3c449fa3) +- Try tests in node@4 [`872a326`](https://github.com/form-data/form-data/commit/872a326ab13e2740b660ff589b75232c3a85fcc9) +- Pull in final version [`9d44871`](https://github.com/form-data/form-data/commit/9d44871073d647995270b19dbc26f65671ce15c7) + +## [v2.3.1](https://github.com/form-data/form-data/compare/v2.3.0...v2.3.1) - 2017-08-24 + +### Commits + +- Updated readme with custom options example [`8e0a569`](https://github.com/form-data/form-data/commit/8e0a5697026016fe171e93bec43c2205279e23ca) +- Added support (tests) for node 8 [`d1d6f4a`](https://github.com/form-data/form-data/commit/d1d6f4ad4670d8ba84cc85b28e522ca0e93eb362) + +## [v2.3.0](https://github.com/form-data/form-data/compare/v2.2.0...v2.3.0) - 2017-08-24 + +### Merged + +- Added custom `options` support [`#368`](https://github.com/form-data/form-data/pull/368) +- Allow form.submit with url string param to use https [`#249`](https://github.com/form-data/form-data/pull/249) +- Proper header production [`#357`](https://github.com/form-data/form-data/pull/357) +- Fix wrong MIME type in example [`#285`](https://github.com/form-data/form-data/pull/285) + +### Commits + +- allow form.submit with url string param to use https [`c0390dc`](https://github.com/form-data/form-data/commit/c0390dcc623e15215308fa2bb0225aa431d9381e) +- update tests for url parsing [`eec0e80`](https://github.com/form-data/form-data/commit/eec0e807889d46697abd39a89ad9bf39996ba787) +- Uses for in to assign properties instead of Object.assign [`f6854ed`](https://github.com/form-data/form-data/commit/f6854edd85c708191bb9c89615a09fd0a9afe518) +- Adds test to check for option override [`61762f2`](https://github.com/form-data/form-data/commit/61762f2c5262e576d6a7f778b4ebab6546ef8582) +- Removes the 2mb maxDataSize limitation [`dc171c3`](https://github.com/form-data/form-data/commit/dc171c3ba49ac9b8813636fd4159d139b812315b) +- Ignore .DS_Store [`e8a05d3`](https://github.com/form-data/form-data/commit/e8a05d33361f7dca8927fe1d96433d049843de24) + +## [v2.2.0](https://github.com/form-data/form-data/compare/v2.1.4...v2.2.0) - 2017-06-11 + +### Merged + +- Filename can be a nested path [`#355`](https://github.com/form-data/form-data/pull/355) + +### Commits + +- Bumped version number. [`d7398c3`](https://github.com/form-data/form-data/commit/d7398c3e7cd81ed12ecc0b84363721bae467db02) + +## [v2.1.4](https://github.com/form-data/form-data/compare/2.1.3...v2.1.4) - 2017-04-08 + +## [2.1.3](https://github.com/form-data/form-data/compare/v2.1.3...2.1.3) - 2017-04-08 + +## [v2.1.3](https://github.com/form-data/form-data/compare/v2.1.2...v2.1.3) - 2017-04-08 + +### Merged + +- toString should output '[object FormData]' [`#346`](https://github.com/form-data/form-data/pull/346) + +## [v2.1.2](https://github.com/form-data/form-data/compare/v2.1.1...v2.1.2) - 2016-11-07 + +### Merged + +- #271 Added check for self and window objects + tests [`#282`](https://github.com/form-data/form-data/pull/282) + +### Commits + +- Added check for self and window objects + tests [`c99e4ec`](https://github.com/form-data/form-data/commit/c99e4ec32cd14d83776f2bdcc5a4e7384131c1b1) + +## [v2.1.1](https://github.com/form-data/form-data/compare/v2.1.0...v2.1.1) - 2016-10-03 + +### Merged + +- Bumped dependencies. [`#270`](https://github.com/form-data/form-data/pull/270) +- Update browser.js shim to use self instead of window [`#267`](https://github.com/form-data/form-data/pull/267) +- Boilerplate code rediction [`#265`](https://github.com/form-data/form-data/pull/265) +- eslint@3.7.0 [`#266`](https://github.com/form-data/form-data/pull/266) + +### Commits + +- code duplicates removed [`e9239fb`](https://github.com/form-data/form-data/commit/e9239fbe7d3c897b29fe3bde857d772469541c01) +- Changed according to requests [`aa99246`](https://github.com/form-data/form-data/commit/aa9924626bd9168334d73fea568c0ad9d8fbaa96) +- chore(package): update eslint to version 3.7.0 [`090a859`](https://github.com/form-data/form-data/commit/090a859835016cab0de49629140499e418db9c3a) + +## [v2.1.0](https://github.com/form-data/form-data/compare/v2.0.0...v2.1.0) - 2016-09-25 + +### Merged + +- Added `hasKnownLength` public method [`#263`](https://github.com/form-data/form-data/pull/263) + +### Commits + +- Added hasKnownLength public method [`655b959`](https://github.com/form-data/form-data/commit/655b95988ef2ed3399f8796b29b2a8673c1df11c) + +## [v2.0.0](https://github.com/form-data/form-data/compare/v1.0.0...v2.0.0) - 2016-09-16 + +### Merged + +- Replaced async with asynckit [`#258`](https://github.com/form-data/form-data/pull/258) +- Pre-release house cleaning [`#247`](https://github.com/form-data/form-data/pull/247) + +### Commits + +- Replaced async with asynckit. Modernized [`1749b78`](https://github.com/form-data/form-data/commit/1749b78d50580fbd080e65c1eb9702ad4f4fc0c0) +- Ignore .bak files [`c08190a`](https://github.com/form-data/form-data/commit/c08190a87d3e22a528b6e32b622193742a4c2672) +- Trying to be more chatty. :) [`c79eabb`](https://github.com/form-data/form-data/commit/c79eabb24eaf761069255a44abf4f540cfd47d40) + +## [v1.0.0](https://github.com/form-data/form-data/compare/v1.0.0-rc4...v1.0.0) - 2016-08-26 + +### Merged + +- Allow custom header fields to be set as an object. [`#190`](https://github.com/form-data/form-data/pull/190) +- v1.0.0-rc4 [`#182`](https://github.com/form-data/form-data/pull/182) +- Avoid undefined variable reference in older browsers [`#176`](https://github.com/form-data/form-data/pull/176) +- More housecleaning [`#164`](https://github.com/form-data/form-data/pull/164) +- More cleanup [`#159`](https://github.com/form-data/form-data/pull/159) +- Added windows testing. Some cleanup. [`#158`](https://github.com/form-data/form-data/pull/158) +- Housecleaning. Added test coverage. [`#156`](https://github.com/form-data/form-data/pull/156) +- Second iteration of cleanup. [`#145`](https://github.com/form-data/form-data/pull/145) + +### Commits + +- Pre-release house cleaning [`440d72b`](https://github.com/form-data/form-data/commit/440d72b5fd44dd132f42598c3183d46e5f35ce71) +- Updated deps, updated docs [`54b6114`](https://github.com/form-data/form-data/commit/54b61143e9ce66a656dd537a1e7b31319a4991be) +- make docs up-to-date [`5e383d7`](https://github.com/form-data/form-data/commit/5e383d7f1466713f7fcef58a6817e0cb466c8ba7) +- Added missing deps [`fe04862`](https://github.com/form-data/form-data/commit/fe04862000b2762245e2db69d5207696a08c1174) + +## [v1.0.0-rc4](https://github.com/form-data/form-data/compare/v1.0.0-rc3...v1.0.0-rc4) - 2016-03-15 + +### Merged + +- Housecleaning, preparing for the release [`#144`](https://github.com/form-data/form-data/pull/144) +- lib: emit error when failing to get length [`#127`](https://github.com/form-data/form-data/pull/127) +- Cleaning up for Codacity 2. [`#143`](https://github.com/form-data/form-data/pull/143) +- Cleaned up codacity concerns. [`#142`](https://github.com/form-data/form-data/pull/142) +- Should throw type error without new operator. [`#129`](https://github.com/form-data/form-data/pull/129) + +### Commits + +- More cleanup [`94b6565`](https://github.com/form-data/form-data/commit/94b6565bb98a387335c72feff5ed5c10da0a7f6f) +- Shuffling things around [`3c2f172`](https://github.com/form-data/form-data/commit/3c2f172eaddf0979b3eef5c73985d1a6fd3eee4a) +- Second iteration of cleanup. [`347c88e`](https://github.com/form-data/form-data/commit/347c88ef9a99a66b9bcf4278497425db2f0182b2) +- Housecleaning [`c335610`](https://github.com/form-data/form-data/commit/c3356100c054a4695e4dec8ed7072775cd745616) +- More housecleaning [`f573321`](https://github.com/form-data/form-data/commit/f573321824aae37ba2052a92cc889d533d9f8fb8) +- Trying to make far run on windows. + cleanup [`e426dfc`](https://github.com/form-data/form-data/commit/e426dfcefb07ee307d8a15dec04044cce62413e6) +- Playing with appveyor [`c9458a7`](https://github.com/form-data/form-data/commit/c9458a7c328782b19859bc1745e7d6b2005ede86) +- Updated dev dependencies. [`ceebe88`](https://github.com/form-data/form-data/commit/ceebe88872bb22da0a5a98daf384e3cc232928d3) +- Replaced win-spawn with cross-spawn [`405a69e`](https://github.com/form-data/form-data/commit/405a69ee34e235ee6561b5ff0140b561be40d1cc) +- Updated readme badges. [`12f282a`](https://github.com/form-data/form-data/commit/12f282a1310fcc2f70cc5669782283929c32a63d) +- Making paths windows friendly. [`f4bddc5`](https://github.com/form-data/form-data/commit/f4bddc5955e2472f8e23c892c9b4d7a08fcb85a3) +- [WIP] trying things for greater sanity [`8ad1f02`](https://github.com/form-data/form-data/commit/8ad1f02b0b3db4a0b00c5d6145ed69bcb7558213) +- Bending under Codacy [`bfff3bb`](https://github.com/form-data/form-data/commit/bfff3bb36052dc83f429949b4e6f9b146a49d996) +- Another attempt to make windows friendly [`f3eb628`](https://github.com/form-data/form-data/commit/f3eb628974ccb91ba0020f41df490207eeed77f6) +- Updated dependencies. [`f73996e`](https://github.com/form-data/form-data/commit/f73996e0508ee2d4b2b376276adfac1de4188ac2) +- Missed travis changes. [`67ee79f`](https://github.com/form-data/form-data/commit/67ee79f964fdabaf300bd41b0af0c1cfaca07687) +- Restructured badges. [`48444a1`](https://github.com/form-data/form-data/commit/48444a1ff156ba2c2c3cfd11047c2f2fd92d4474) +- Add similar type error as the browser for attempting to use form-data without new. [`5711320`](https://github.com/form-data/form-data/commit/5711320fb7c8cc620cfc79b24c7721526e23e539) +- Took out codeclimate-test-reporter [`a7e0c65`](https://github.com/form-data/form-data/commit/a7e0c6522afe85ca9974b0b4e1fca9c77c3e52b1) +- One more [`8e84cff`](https://github.com/form-data/form-data/commit/8e84cff3370526ecd3e175fd98e966242d81993c) + +## [v1.0.0-rc3](https://github.com/form-data/form-data/compare/v1.0.0-rc2...v1.0.0-rc3) - 2015-07-29 + +### Merged + +- House cleaning. Added `pre-commit`. [`#140`](https://github.com/form-data/form-data/pull/140) +- Allow custom content-type without setting a filename. [`#138`](https://github.com/form-data/form-data/pull/138) +- Add node-fetch to alternative submission methods. [`#132`](https://github.com/form-data/form-data/pull/132) +- Update dependencies [`#130`](https://github.com/form-data/form-data/pull/130) +- Switching to container based TravisCI [`#136`](https://github.com/form-data/form-data/pull/136) +- Default content-type to 'application/octect-stream' [`#128`](https://github.com/form-data/form-data/pull/128) +- Allow filename as third option of .append [`#125`](https://github.com/form-data/form-data/pull/125) + +### Commits + +- Allow custom content-type without setting a filename [`c8a77cc`](https://github.com/form-data/form-data/commit/c8a77cc0cf16d15f1ebf25272beaab639ce89f76) +- Fixed ranged test. [`a5ac58c`](https://github.com/form-data/form-data/commit/a5ac58cbafd0909f32fe8301998f689314fd4859) +- Allow filename as third option of #append [`d081005`](https://github.com/form-data/form-data/commit/d0810058c84764b3c463a18b15ebb37864de9260) +- Allow custom content-type without setting a filename [`8cb9709`](https://github.com/form-data/form-data/commit/8cb9709e5f1809cfde0cd707dbabf277138cd771) + +## [v1.0.0-rc2](https://github.com/form-data/form-data/compare/v1.0.0-rc1...v1.0.0-rc2) - 2015-07-21 + +### Merged + +- #109 Append proper line break [`#123`](https://github.com/form-data/form-data/pull/123) +- Add shim for browser (browserify/webpack). [`#122`](https://github.com/form-data/form-data/pull/122) +- Update license field [`#115`](https://github.com/form-data/form-data/pull/115) + +### Commits + +- Add shim for browser. [`87c33f4`](https://github.com/form-data/form-data/commit/87c33f4269a2211938f80ab3e53835362b1afee8) +- Bump version [`a3f5d88`](https://github.com/form-data/form-data/commit/a3f5d8872c810ce240c7d3838c69c3c9fcecc111) + +## [v1.0.0-rc1](https://github.com/form-data/form-data/compare/0.2...v1.0.0-rc1) - 2015-06-13 + +### Merged + +- v1.0.0-rc1 [`#114`](https://github.com/form-data/form-data/pull/114) +- Updated test targets [`#102`](https://github.com/form-data/form-data/pull/102) +- Remove duplicate plus sign [`#94`](https://github.com/form-data/form-data/pull/94) + +### Commits + +- Made https test local. Updated deps. [`afe1959`](https://github.com/form-data/form-data/commit/afe1959ec711f23e57038ab5cb20fedd86271f29) +- Proper self-signed ssl [`4d5ec50`](https://github.com/form-data/form-data/commit/4d5ec50e81109ad2addf3dbb56dc7c134df5ff87) +- Update HTTPS handling for modern days [`2c11b01`](https://github.com/form-data/form-data/commit/2c11b01ce2c06e205c84d7154fa2f27b66c94f3b) +- Made tests more local [`09633fa`](https://github.com/form-data/form-data/commit/09633fa249e7ce3ac581543aafe16ee9039a823b) +- Auto create tmp folder for Formidable [`28714b7`](https://github.com/form-data/form-data/commit/28714b7f71ad556064cdff88fabe6b92bd407ddd) +- remove duplicate plus sign [`36e09c6`](https://github.com/form-data/form-data/commit/36e09c695b0514d91a23f5cd64e6805404776fc7) + +## [0.2](https://github.com/form-data/form-data/compare/0.1.4...0.2) - 2014-12-06 + +### Merged + +- Bumped version [`#96`](https://github.com/form-data/form-data/pull/96) +- Replace mime library. [`#95`](https://github.com/form-data/form-data/pull/95) +- #71 Respect bytes range in a read stream. [`#73`](https://github.com/form-data/form-data/pull/73) + +## [0.1.4](https://github.com/form-data/form-data/compare/0.1.3...0.1.4) - 2014-06-23 + +### Merged + +- Updated version. [`#76`](https://github.com/form-data/form-data/pull/76) +- #71 Respect bytes range in a read stream. [`#75`](https://github.com/form-data/form-data/pull/75) + +## [0.1.3](https://github.com/form-data/form-data/compare/0.1.2...0.1.3) - 2014-06-17 + +### Merged + +- Updated versions. [`#69`](https://github.com/form-data/form-data/pull/69) +- Added custom headers support [`#60`](https://github.com/form-data/form-data/pull/60) +- Added test for Request. Small fixes. [`#56`](https://github.com/form-data/form-data/pull/56) + +### Commits + +- Added test for the custom header functionality [`bd50685`](https://github.com/form-data/form-data/commit/bd506855af62daf728ef1718cae88ed23bb732f3) +- Documented custom headers option [`77a024a`](https://github.com/form-data/form-data/commit/77a024a9375f93c246c35513d80f37d5e11d35ff) +- Removed 0.6 support. [`aee8dce`](https://github.com/form-data/form-data/commit/aee8dce604c595cfaacfc6efb12453d1691ac0d6) + +## [0.1.2](https://github.com/form-data/form-data/compare/0.1.1...0.1.2) - 2013-10-02 + +### Merged + +- Fixed default https port assignment, added tests. [`#52`](https://github.com/form-data/form-data/pull/52) +- #45 Added tests for multi-submit. Updated readme. [`#49`](https://github.com/form-data/form-data/pull/49) +- #47 return request from .submit() [`#48`](https://github.com/form-data/form-data/pull/48) + +### Commits + +- Bumped version. [`2b761b2`](https://github.com/form-data/form-data/commit/2b761b256ae607fc2121621f12c2e1042be26baf) + +## [0.1.1](https://github.com/form-data/form-data/compare/0.1.0...0.1.1) - 2013-08-21 + +### Merged + +- Added license type and reference to package.json [`#46`](https://github.com/form-data/form-data/pull/46) + +### Commits + +- #47 return request from .submit() [`1d61c2d`](https://github.com/form-data/form-data/commit/1d61c2da518bd5e136550faa3b5235bb540f1e06) +- #47 Updated readme. [`e3dae15`](https://github.com/form-data/form-data/commit/e3dae1526bd3c3b9d7aff6075abdaac12c3cc60f) + +## [0.1.0](https://github.com/form-data/form-data/compare/0.0.10...0.1.0) - 2013-07-08 + +### Merged + +- Update master to 0.1.0 [`#44`](https://github.com/form-data/form-data/pull/44) +- 0.1.0 - Added error handling. Streamlined edge cases behavior. [`#43`](https://github.com/form-data/form-data/pull/43) +- Pointed badges back to mothership. [`#39`](https://github.com/form-data/form-data/pull/39) +- Updated node-fake to support 0.11 tests. [`#37`](https://github.com/form-data/form-data/pull/37) +- Updated tests to play nice with 0.10 [`#36`](https://github.com/form-data/form-data/pull/36) +- #32 Added .npmignore [`#34`](https://github.com/form-data/form-data/pull/34) +- Spring cleaning [`#30`](https://github.com/form-data/form-data/pull/30) + +### Commits + +- Added error handling. Streamlined edge cases behavior. [`4da496e`](https://github.com/form-data/form-data/commit/4da496e577cb9bc0fd6c94cbf9333a0082ce353a) +- Made tests more deterministic. [`7fc009b`](https://github.com/form-data/form-data/commit/7fc009b8a2cc9232514a44b2808b9f89ce68f7d2) +- Fixed styling. [`d373b41`](https://github.com/form-data/form-data/commit/d373b417e779024bc3326073e176383cd08c0b18) +- #40 Updated Readme.md regarding getLengthSync() [`efb373f`](https://github.com/form-data/form-data/commit/efb373fd63814d977960e0299d23c92cd876cfef) +- Updated readme. [`527e3a6`](https://github.com/form-data/form-data/commit/527e3a63b032cb6f576f597ad7ff2ebcf8a0b9b4) + +## [0.0.10](https://github.com/form-data/form-data/compare/0.0.9...0.0.10) - 2013-05-08 + +### Commits + +- Updated tests to play nice with 0.10. [`932b39b`](https://github.com/form-data/form-data/commit/932b39b773e49edcb2c5d2e58fe389ab6c42f47c) +- Added dependency tracking. [`3131d7f`](https://github.com/form-data/form-data/commit/3131d7f6996cd519d50547e4de1587fd80d0fa07) + +## 0.0.9 - 2013-04-29 + +### Merged + +- Custom params for form.submit() should cover most edge cases. [`#22`](https://github.com/form-data/form-data/pull/22) +- Updated Readme and version number. [`#20`](https://github.com/form-data/form-data/pull/20) +- Allow custom headers and pre-known length in parts [`#17`](https://github.com/form-data/form-data/pull/17) +- Bumped version number. [`#12`](https://github.com/form-data/form-data/pull/12) +- Fix for #10 [`#11`](https://github.com/form-data/form-data/pull/11) +- Bumped version number. [`#8`](https://github.com/form-data/form-data/pull/8) +- Added support for https destination, http-response and mikeal's request streams. [`#7`](https://github.com/form-data/form-data/pull/7) +- Updated git url. [`#6`](https://github.com/form-data/form-data/pull/6) +- Version bump. [`#5`](https://github.com/form-data/form-data/pull/5) +- Changes to support custom content-type and getLengthSync. [`#4`](https://github.com/form-data/form-data/pull/4) +- make .submit(url) use host from url, not 'localhost' [`#2`](https://github.com/form-data/form-data/pull/2) +- Make package.json JSON [`#1`](https://github.com/form-data/form-data/pull/1) + +### Fixed + +- Add MIT license [`#14`](https://github.com/form-data/form-data/issues/14) + +### Commits + +- Spring cleaning. [`850ba1b`](https://github.com/form-data/form-data/commit/850ba1b649b6856b0fa87bbcb04bc70ece0137a6) +- Added custom request params to form.submit(). Made tests more stable. [`de3502f`](https://github.com/form-data/form-data/commit/de3502f6c4a509f6ed12a7dd9dc2ce9c2e0a8d23) +- Basic form (no files) working [`6ffdc34`](https://github.com/form-data/form-data/commit/6ffdc343e8594cfc2efe1e27653ea39d8980a14e) +- Got initial test to pass [`9a59d08`](https://github.com/form-data/form-data/commit/9a59d08c024479fd3c9d99ba2f0893a47b3980f0) +- Implement initial getLength [`9060c91`](https://github.com/form-data/form-data/commit/9060c91b861a6573b73beddd11e866db422b5830) +- Make getLength work with file streams [`6f6b1e9`](https://github.com/form-data/form-data/commit/6f6b1e9b65951e6314167db33b446351702f5558) +- Implemented a simplistic submit() function [`41e9cc1`](https://github.com/form-data/form-data/commit/41e9cc124124721e53bc1d1459d45db1410c44e6) +- added test for custom headers and content-length in parts (felixge/node-form-data/17) [`b16d14e`](https://github.com/form-data/form-data/commit/b16d14e693670f5d52babec32cdedd1aa07c1aa4) +- Fixed code styling. [`5847424`](https://github.com/form-data/form-data/commit/5847424c666970fc2060acd619e8a78678888a82) +- #29 Added custom filename and content-type options to support identity-less streams. [`adf8b4a`](https://github.com/form-data/form-data/commit/adf8b4a41530795682cd3e35ffaf26b30288ccda) +- Initial Readme and package.json [`8c744e5`](https://github.com/form-data/form-data/commit/8c744e58be4014bdf432e11b718ed87f03e217af) +- allow append() to completely override header and boundary [`3fb2ad4`](https://github.com/form-data/form-data/commit/3fb2ad491f66e4b4ff16130be25b462820b8c972) +- Syntax highlighting [`ab3a6a5`](https://github.com/form-data/form-data/commit/ab3a6a5ed1ab77a2943ce3befcb2bb3cd9ff0330) +- Updated Readme.md [`de8f441`](https://github.com/form-data/form-data/commit/de8f44122ca754cbfedc0d2748e84add5ff0b669) +- Added examples to Readme file. [`c406ac9`](https://github.com/form-data/form-data/commit/c406ac921d299cbc130464ed19338a9ef97cb650) +- pass options.knownLength to set length at beginning, w/o waiting for async size calculation [`e2ac039`](https://github.com/form-data/form-data/commit/e2ac0397ff7c37c3dca74fa9925b55f832e4fa0b) +- Updated dependencies and added test command. [`09bd7cd`](https://github.com/form-data/form-data/commit/09bd7cd86f1ad7a58df1b135eb6eef0d290894b4) +- Bumped version. Updated readme. [`4581140`](https://github.com/form-data/form-data/commit/4581140f322758c6fc92019d342c7d7d6c94af5c) +- Test runner [`1707ebb`](https://github.com/form-data/form-data/commit/1707ebbd180856e6ed44e80c46b02557e2425762) +- Added .npmignore, bumped version. [`2e033e0`](https://github.com/form-data/form-data/commit/2e033e0e4be7c1457be090cd9b2996f19d8fb665) +- FormData.prototype.append takes and passes along options (for header) [`b519203`](https://github.com/form-data/form-data/commit/b51920387ed4da7b4e106fc07b9459f26b5ae2f0) +- Make package.json JSON [`bf1b58d`](https://github.com/form-data/form-data/commit/bf1b58df794b10fda86ed013eb9237b1e5032085) +- Add dependencies to package.json [`7413d0b`](https://github.com/form-data/form-data/commit/7413d0b4cf5546312d47ea426db8180619083974) +- Add convenient submit() interface [`55855e4`](https://github.com/form-data/form-data/commit/55855e4bea14585d4a3faf9e7318a56696adbc7d) +- Fix content type [`08b6ae3`](https://github.com/form-data/form-data/commit/08b6ae337b23ef1ba457ead72c9b133047df213c) +- Combatting travis rvm calls. [`409adfd`](https://github.com/form-data/form-data/commit/409adfd100a3cf4968a632c05ba58d92d262d144) +- Fixed Issue #2 [`b3a5d66`](https://github.com/form-data/form-data/commit/b3a5d661739dcd6921b444b81d5cb3c32fab655d) +- Fix for #10. [`bab70b9`](https://github.com/form-data/form-data/commit/bab70b9e803e17287632762073d227d6c59989e0) +- Trying workarounds for formidable - 0.6 "love". [`25782a3`](https://github.com/form-data/form-data/commit/25782a3f183d9c30668ec2bca6247ed83f10611c) +- change whitespace to conform with felixge's style guide [`9fa34f4`](https://github.com/form-data/form-data/commit/9fa34f433bece85ef73086a874c6f0164ab7f1f6) +- Add async to deps [`b7d1a6b`](https://github.com/form-data/form-data/commit/b7d1a6b10ee74be831de24ed76843e5a6935f155) +- typo [`7860a9c`](https://github.com/form-data/form-data/commit/7860a9c8a582f0745ce0e4a0549f4bffc29c0b50) +- Bumped version. [`fa36c1b`](https://github.com/form-data/form-data/commit/fa36c1b4229c34b85d7efd41908429b6d1da3bfc) +- Updated .gitignore [`de567bd`](https://github.com/form-data/form-data/commit/de567bde620e53b8e9b0ed3506e79491525ec558) +- Don't rely on resume() being called by pipe [`1deae47`](https://github.com/form-data/form-data/commit/1deae47e042bcd170bd5dbe2b4a4fa5356bb8aa2) +- One more wrong content type [`28f166d`](https://github.com/form-data/form-data/commit/28f166d443e2eb77f2559324014670674b97e46e) +- Another typo [`b959b6a`](https://github.com/form-data/form-data/commit/b959b6a2be061cac17f8d329b89cea109f0f32be) +- Typo [`698fa0a`](https://github.com/form-data/form-data/commit/698fa0aa5dbf4eeb77377415acc202a6fbe3f4a2) +- Being simply dumb. [`b614db8`](https://github.com/form-data/form-data/commit/b614db85702061149fbd98418605106975e72ade) +- Fixed typo in the filename. [`30af6be`](https://github.com/form-data/form-data/commit/30af6be13fb0c9e92b32e935317680b9d7599928) diff --git a/node_modules/form-data/License b/node_modules/form-data/License new file mode 100644 index 0000000..c7ff12a --- /dev/null +++ b/node_modules/form-data/License @@ -0,0 +1,19 @@ +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors + + 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. diff --git a/node_modules/form-data/README.md b/node_modules/form-data/README.md new file mode 100644 index 0000000..55afcad --- /dev/null +++ b/node_modules/form-data/README.md @@ -0,0 +1,355 @@ +# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data) + +A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications. + +The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd]. + +[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface + +[![Linux Build](https://img.shields.io/travis/form-data/form-data/v4.0.4.svg?label=linux:6.x-12.x)](https://travis-ci.org/form-data/form-data) +[![MacOS Build](https://img.shields.io/travis/form-data/form-data/v4.0.4.svg?label=macos:6.x-12.x)](https://travis-ci.org/form-data/form-data) +[![Windows Build](https://img.shields.io/travis/form-data/form-data/v4.0.4.svg?label=windows:6.x-12.x)](https://travis-ci.org/form-data/form-data) + +[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/v4.0.4.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master) +[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data) + +## Install + +``` +npm install --save form-data +``` + +## Usage + +In this example we are constructing a form with 3 fields that contain a string, +a buffer and a file stream. + +``` javascript +var FormData = require('form-data'); +var fs = require('fs'); + +var form = new FormData(); +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_file', fs.createReadStream('/foo/bar.jpg')); +``` + +Also you can use http-response stream: + +``` javascript +var FormData = require('form-data'); +var http = require('http'); + +var form = new FormData(); + +http.request('http://nodejs.org/images/logo.png', function (response) { + form.append('my_field', 'my value'); + form.append('my_buffer', new Buffer(10)); + form.append('my_logo', response); +}); +``` + +Or @mikeal's [request](https://github.com/request/request) stream: + +``` javascript +var FormData = require('form-data'); +var request = require('request'); + +var form = new FormData(); + +form.append('my_field', 'my value'); +form.append('my_buffer', new Buffer(10)); +form.append('my_logo', request('http://nodejs.org/images/logo.png')); +``` + +In order to submit this form to a web application, call ```submit(url, [callback])``` method: + +``` javascript +form.submit('http://example.org/', function (err, res) { + // res – response object (http.IncomingMessage) // + res.resume(); +}); + +``` + +For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods. + +### Custom options + +You can provide custom options, such as `maxDataSize`: + +``` javascript +var FormData = require('form-data'); + +var form = new FormData({ maxDataSize: 20971520 }); +form.append('my_field', 'my value'); +form.append('my_buffer', /* something big */); +``` + +List of available options could be found in [combined-stream](https://github.com/felixge/node-combined-stream/blob/master/lib/combined_stream.js#L7-L15) + +### Alternative submission methods + +You can use node's http client interface: + +``` javascript +var http = require('http'); + +var request = http.request({ + method: 'post', + host: 'example.org', + path: '/upload', + headers: form.getHeaders() +}); + +form.pipe(request); + +request.on('response', function (res) { + console.log(res.statusCode); +}); +``` + +Or if you would prefer the `'Content-Length'` header to be set for you: + +``` javascript +form.submit('example.org/upload', function (err, res) { + console.log(res.statusCode); +}); +``` + +To use custom headers and pre-known length in parts: + +``` javascript +var CRLF = '\r\n'; +var form = new FormData(); + +var options = { + header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, + knownLength: 1 +}; + +form.append('my_buffer', buffer, options); + +form.submit('http://example.com/', function (err, res) { + if (err) throw err; + console.log('Done'); +}); +``` + +Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually: + +``` javascript +someModule.stream(function (err, stdout, stderr) { + if (err) throw err; + + var form = new FormData(); + + form.append('file', stdout, { + filename: 'unicycle.jpg', // ... or: + filepath: 'photos/toys/unicycle.jpg', + contentType: 'image/jpeg', + knownLength: 19806 + }); + + form.submit('http://example.com/', function (err, res) { + if (err) throw err; + console.log('Done'); + }); +}); +``` + +The `filepath` property overrides `filename` and may contain a relative path. This is typically used when uploading [multiple files from a directory](https://wicg.github.io/entries-api/#dom-htmlinputelement-webkitdirectory). + +For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter: + +``` javascript +form.submit({ + host: 'example.com', + path: '/probably.php?extra=params', + auth: 'username:password' +}, function (err, res) { + console.log(res.statusCode); +}); +``` + +In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`: + +``` javascript +form.submit({ + host: 'example.com', + path: '/surelynot.php', + headers: { 'x-test-header': 'test-header-value' } +}, function (err, res) { + console.log(res.statusCode); +}); +``` + +### Methods + +- [_Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] )](https://github.com/form-data/form-data#void-append-string-field-mixed-value--mixed-options-). +- [_Headers_ getHeaders( [**Headers** _userHeaders_] )](https://github.com/form-data/form-data#array-getheaders-array-userheaders-) +- [_String_ getBoundary()](https://github.com/form-data/form-data#string-getboundary) +- [_Void_ setBoundary()](https://github.com/form-data/form-data#void-setboundary) +- [_Buffer_ getBuffer()](https://github.com/form-data/form-data#buffer-getbuffer) +- [_Integer_ getLengthSync()](https://github.com/form-data/form-data#integer-getlengthsync) +- [_Integer_ getLength( **function** _callback_ )](https://github.com/form-data/form-data#integer-getlength-function-callback-) +- [_Boolean_ hasKnownLength()](https://github.com/form-data/form-data#boolean-hasknownlength) +- [_Request_ submit( _params_, **function** _callback_ )](https://github.com/form-data/form-data#request-submit-params-function-callback-) +- [_String_ toString()](https://github.com/form-data/form-data#string-tostring) + +#### _Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] ) +Append data to the form. You can submit about any format (string, integer, boolean, buffer, etc.). However, Arrays are not supported and need to be turned into strings by the user. +```javascript +var form = new FormData(); +form.append('my_string', 'my value'); +form.append('my_integer', 1); +form.append('my_boolean', true); +form.append('my_buffer', new Buffer(10)); +form.append('my_array_as_json', JSON.stringify(['bird', 'cute'])); +``` + +You may provide a string for options, or an object. +```javascript +// Set filename by providing a string for options +form.append('my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg'); + +// provide an object. +form.append('my_file', fs.createReadStream('/foo/bar.jpg'), { filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806 }); +``` + +#### _Headers_ getHeaders( [**Headers** _userHeaders_] ) +This method adds the correct `content-type` header to the provided array of `userHeaders`. + +#### _String_ getBoundary() +Return the boundary of the formData. By default, the boundary consists of 26 `-` followed by 24 numbers +for example: +```javascript +--------------------------515890814546601021194782 +``` + +#### _Void_ setBoundary(String _boundary_) +Set the boundary string, overriding the default behavior described above. + +_Note: The boundary must be unique and may not appear in the data._ + +#### _Buffer_ getBuffer() +Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data. +```javascript +var form = new FormData(); +form.append('my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73])); +form.append('my_file', fs.readFileSync('/foo/bar.jpg')); + +axios.post('https://example.com/path/to/api', form.getBuffer(), form.getHeaders()); +``` +**Note:** Because the output is of type Buffer, you can only append types that are accepted by Buffer: *string, Buffer, ArrayBuffer, Array, or Array-like Object*. A ReadStream for example will result in an error. + +#### _Integer_ getLengthSync() +Same as `getLength` but synchronous. + +_Note: getLengthSync __doesn't__ calculate streams length._ + +#### _Integer_ getLength(**function** _callback_ ) +Returns the `Content-Length` async. The callback is used to handle errors and continue once the length has been calculated +```javascript +this.getLength(function (err, length) { + if (err) { + this._error(err); + return; + } + + // add content length + request.setHeader('Content-Length', length); + + ... +}.bind(this)); +``` + +#### _Boolean_ hasKnownLength() +Checks if the length of added values is known. + +#### _Request_ submit(_params_, **function** _callback_ ) +Submit the form to a web application. +```javascript +var form = new FormData(); +form.append('my_string', 'Hello World'); + +form.submit('http://example.com/', function (err, res) { + // res – response object (http.IncomingMessage) // + res.resume(); +} ); +``` + +#### _String_ toString() +Returns the form data as a string. Don't use this if you are sending files or buffers, use `getBuffer()` instead. + +### Integration with other libraries + +#### Request + +Form submission using [request](https://github.com/request/request): + +```javascript +var formData = { + my_field: 'my_value', + my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), +}; + +request.post({url:'http://service.com/upload', formData: formData}, function (err, httpResponse, body) { + if (err) { + return console.error('upload failed:', err); + } + console.log('Upload successful! Server responded with:', body); +}); +``` + +For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads). + +#### node-fetch + +You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch): + +```javascript +var form = new FormData(); + +form.append('a', 1); + +fetch('http://example.com', { method: 'POST', body: form }) + .then(function (res) { + return res.json(); + }).then(function (json) { + console.log(json); + }); +``` + +#### axios + +In Node.js you can post a file using [axios](https://github.com/axios/axios): +```javascript +const form = new FormData(); +const stream = fs.createReadStream(PATH_TO_FILE); + +form.append('image', stream); + +// In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders` +const formHeaders = form.getHeaders(); + +axios.post('http://example.com', form, { + headers: { + ...formHeaders, + }, +}) + .then(response => response) + .catch(error => error) +``` + +## Notes + +- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround. +- ```getLength(cb)``` will send an error as first parameter of callback if stream length cannot be calculated (e.g. send in custom streams w/o using ```knownLength```). +- ```submit``` will not add `content-length` if form length is unknown or not calculable. +- Starting version `2.x` FormData has dropped support for `node@0.10.x`. +- Starting version `3.x` FormData has dropped support for `node@4.x`. + +## License + +Form-Data is released under the [MIT](License) license. diff --git a/node_modules/form-data/index.d.ts b/node_modules/form-data/index.d.ts new file mode 100644 index 0000000..295e9e9 --- /dev/null +++ b/node_modules/form-data/index.d.ts @@ -0,0 +1,62 @@ +// Definitions by: Carlos Ballesteros Velasco +// Leon Yu +// BendingBender +// Maple Miao + +/// +import * as stream from 'stream'; +import * as http from 'http'; + +export = FormData; + +// Extracted because @types/node doesn't export interfaces. +interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + read?(this: stream.Readable, size: number): void; + destroy?(this: stream.Readable, error: Error | null, callback: (error: Error | null) => void): void; + autoDestroy?: boolean; +} + +interface Options extends ReadableOptions { + writable?: boolean; + readable?: boolean; + dataSize?: number; + maxDataSize?: number; + pauseStreams?: boolean; +} + +declare class FormData extends stream.Readable { + constructor(options?: Options); + append(key: string, value: any, options?: FormData.AppendOptions | string): void; + getHeaders(userHeaders?: FormData.Headers): FormData.Headers; + submit( + params: string | FormData.SubmitOptions, + callback?: (error: Error | null, response: http.IncomingMessage) => void + ): http.ClientRequest; + getBuffer(): Buffer; + setBoundary(boundary: string): void; + getBoundary(): string; + getLength(callback: (err: Error | null, length: number) => void): void; + getLengthSync(): number; + hasKnownLength(): boolean; +} + +declare namespace FormData { + interface Headers { + [key: string]: any; + } + + interface AppendOptions { + header?: string | Headers; + knownLength?: number; + filename?: string; + filepath?: string; + contentType?: string; + } + + interface SubmitOptions extends http.RequestOptions { + protocol?: 'https:' | 'http:'; + } +} diff --git a/node_modules/form-data/lib/browser.js b/node_modules/form-data/lib/browser.js new file mode 100644 index 0000000..8950a91 --- /dev/null +++ b/node_modules/form-data/lib/browser.js @@ -0,0 +1,4 @@ +'use strict'; + +/* eslint-env browser */ +module.exports = typeof self === 'object' ? self.FormData : window.FormData; diff --git a/node_modules/form-data/lib/form_data.js b/node_modules/form-data/lib/form_data.js new file mode 100644 index 0000000..8f5f4b5 --- /dev/null +++ b/node_modules/form-data/lib/form_data.js @@ -0,0 +1,494 @@ +'use strict'; + +var CombinedStream = require('combined-stream'); +var util = require('util'); +var path = require('path'); +var http = require('http'); +var https = require('https'); +var parseUrl = require('url').parse; +var fs = require('fs'); +var Stream = require('stream').Stream; +var crypto = require('crypto'); +var mime = require('mime-types'); +var asynckit = require('asynckit'); +var setToStringTag = require('es-set-tostringtag'); +var hasOwn = require('hasown'); +var populate = require('./populate.js'); + +/** + * Create readable "multipart/form-data" streams. + * Can be used to submit forms + * and file uploads to other web applications. + * + * @constructor + * @param {object} options - Properties to be added/overriden for FormData and CombinedStream + */ +function FormData(options) { + if (!(this instanceof FormData)) { + return new FormData(options); + } + + this._overheadLength = 0; + this._valueLength = 0; + this._valuesToMeasure = []; + + CombinedStream.call(this); + + options = options || {}; // eslint-disable-line no-param-reassign + for (var option in options) { // eslint-disable-line no-restricted-syntax + this[option] = options[option]; + } +} + +// make it a Stream +util.inherits(FormData, CombinedStream); + +FormData.LINE_BREAK = '\r\n'; +FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; + +FormData.prototype.append = function (field, value, options) { + options = options || {}; // eslint-disable-line no-param-reassign + + // allow filename as single option + if (typeof options === 'string') { + options = { filename: options }; // eslint-disable-line no-param-reassign + } + + var append = CombinedStream.prototype.append.bind(this); + + // all that streamy business can't handle numbers + if (typeof value === 'number' || value == null) { + value = String(value); // eslint-disable-line no-param-reassign + } + + // https://github.com/felixge/node-form-data/issues/38 + if (Array.isArray(value)) { + /* + * Please convert your array into string + * the way web server expects it + */ + this._error(new Error('Arrays are not supported.')); + return; + } + + var header = this._multiPartHeader(field, value, options); + var footer = this._multiPartFooter(); + + append(header); + append(value); + append(footer); + + // pass along options.knownLength + this._trackLength(header, value, options); +}; + +FormData.prototype._trackLength = function (header, value, options) { + var valueLength = 0; + + /* + * used w/ getLengthSync(), when length is known. + * e.g. for streaming directly from a remote server, + * w/ a known file a size, and not wanting to wait for + * incoming file to finish to get its size. + */ + if (options.knownLength != null) { + valueLength += Number(options.knownLength); + } else if (Buffer.isBuffer(value)) { + valueLength = value.length; + } else if (typeof value === 'string') { + valueLength = Buffer.byteLength(value); + } + + this._valueLength += valueLength; + + // @check why add CRLF? does this account for custom/multiple CRLFs? + this._overheadLength += Buffer.byteLength(header) + FormData.LINE_BREAK.length; + + // empty or either doesn't have path or not an http response or not a stream + if (!value || (!value.path && !(value.readable && hasOwn(value, 'httpVersion')) && !(value instanceof Stream))) { + return; + } + + // no need to bother with the length + if (!options.knownLength) { + this._valuesToMeasure.push(value); + } +}; + +FormData.prototype._lengthRetriever = function (value, callback) { + if (hasOwn(value, 'fd')) { + // take read range into a account + // `end` = Infinity –> read file till the end + // + // TODO: Looks like there is bug in Node fs.createReadStream + // it doesn't respect `end` options without `start` options + // Fix it when node fixes it. + // https://github.com/joyent/node/issues/7819 + if (value.end != undefined && value.end != Infinity && value.start != undefined) { + // when end specified + // no need to calculate range + // inclusive, starts with 0 + callback(null, value.end + 1 - (value.start ? value.start : 0)); // eslint-disable-line callback-return + + // not that fast snoopy + } else { + // still need to fetch file size from fs + fs.stat(value.path, function (err, stat) { + if (err) { + callback(err); + return; + } + + // update final size based on the range options + var fileSize = stat.size - (value.start ? value.start : 0); + callback(null, fileSize); + }); + } + + // or http response + } else if (hasOwn(value, 'httpVersion')) { + callback(null, Number(value.headers['content-length'])); // eslint-disable-line callback-return + + // or request stream http://github.com/mikeal/request + } else if (hasOwn(value, 'httpModule')) { + // wait till response come back + value.on('response', function (response) { + value.pause(); + callback(null, Number(response.headers['content-length'])); + }); + value.resume(); + + // something else + } else { + callback('Unknown stream'); // eslint-disable-line callback-return + } +}; + +FormData.prototype._multiPartHeader = function (field, value, options) { + /* + * custom header specified (as string)? + * it becomes responsible for boundary + * (e.g. to handle extra CRLFs on .NET servers) + */ + if (typeof options.header === 'string') { + return options.header; + } + + var contentDisposition = this._getContentDisposition(value, options); + var contentType = this._getContentType(value, options); + + var contents = ''; + var headers = { + // add custom disposition as third element or keep it two elements if not + 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), + // if no content type. allow it to be empty array + 'Content-Type': [].concat(contentType || []) + }; + + // allow custom headers. + if (typeof options.header === 'object') { + populate(headers, options.header); + } + + var header; + for (var prop in headers) { // eslint-disable-line no-restricted-syntax + if (hasOwn(headers, prop)) { + header = headers[prop]; + + // skip nullish headers. + if (header == null) { + continue; // eslint-disable-line no-restricted-syntax, no-continue + } + + // convert all headers to arrays. + if (!Array.isArray(header)) { + header = [header]; + } + + // add non-empty headers. + if (header.length) { + contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; + } + } + } + + return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; +}; + +FormData.prototype._getContentDisposition = function (value, options) { // eslint-disable-line consistent-return + var filename; + + if (typeof options.filepath === 'string') { + // custom filepath for relative paths + filename = path.normalize(options.filepath).replace(/\\/g, '/'); + } else if (options.filename || (value && (value.name || value.path))) { + /* + * custom filename take precedence + * formidable and the browser add a name property + * fs- and request- streams have path property + */ + filename = path.basename(options.filename || (value && (value.name || value.path))); + } else if (value && value.readable && hasOwn(value, 'httpVersion')) { + // or try http response + filename = path.basename(value.client._httpMessage.path || ''); + } + + if (filename) { + return 'filename="' + filename + '"'; + } +}; + +FormData.prototype._getContentType = function (value, options) { + // use custom content-type above all + var contentType = options.contentType; + + // or try `name` from formidable, browser + if (!contentType && value && value.name) { + contentType = mime.lookup(value.name); + } + + // or try `path` from fs-, request- streams + if (!contentType && value && value.path) { + contentType = mime.lookup(value.path); + } + + // or if it's http-reponse + if (!contentType && value && value.readable && hasOwn(value, 'httpVersion')) { + contentType = value.headers['content-type']; + } + + // or guess it from the filepath or filename + if (!contentType && (options.filepath || options.filename)) { + contentType = mime.lookup(options.filepath || options.filename); + } + + // fallback to the default content type if `value` is not simple value + if (!contentType && value && typeof value === 'object') { + contentType = FormData.DEFAULT_CONTENT_TYPE; + } + + return contentType; +}; + +FormData.prototype._multiPartFooter = function () { + return function (next) { + var footer = FormData.LINE_BREAK; + + var lastPart = this._streams.length === 0; + if (lastPart) { + footer += this._lastBoundary(); + } + + next(footer); + }.bind(this); +}; + +FormData.prototype._lastBoundary = function () { + return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; +}; + +FormData.prototype.getHeaders = function (userHeaders) { + var header; + var formHeaders = { + 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() + }; + + for (header in userHeaders) { // eslint-disable-line no-restricted-syntax + if (hasOwn(userHeaders, header)) { + formHeaders[header.toLowerCase()] = userHeaders[header]; + } + } + + return formHeaders; +}; + +FormData.prototype.setBoundary = function (boundary) { + if (typeof boundary !== 'string') { + throw new TypeError('FormData boundary must be a string'); + } + this._boundary = boundary; +}; + +FormData.prototype.getBoundary = function () { + if (!this._boundary) { + this._generateBoundary(); + } + + return this._boundary; +}; + +FormData.prototype.getBuffer = function () { + var dataBuffer = new Buffer.alloc(0); // eslint-disable-line new-cap + var boundary = this.getBoundary(); + + // Create the form content. Add Line breaks to the end of data. + for (var i = 0, len = this._streams.length; i < len; i++) { + if (typeof this._streams[i] !== 'function') { + // Add content to the buffer. + if (Buffer.isBuffer(this._streams[i])) { + dataBuffer = Buffer.concat([dataBuffer, this._streams[i]]); + } else { + dataBuffer = Buffer.concat([dataBuffer, Buffer.from(this._streams[i])]); + } + + // Add break after content. + if (typeof this._streams[i] !== 'string' || this._streams[i].substring(2, boundary.length + 2) !== boundary) { + dataBuffer = Buffer.concat([dataBuffer, Buffer.from(FormData.LINE_BREAK)]); + } + } + } + + // Add the footer and return the Buffer object. + return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]); +}; + +FormData.prototype._generateBoundary = function () { + // This generates a 50 character boundary similar to those used by Firefox. + + // They are optimized for boyer-moore parsing. + this._boundary = '--------------------------' + crypto.randomBytes(12).toString('hex'); +}; + +// Note: getLengthSync DOESN'T calculate streams length +// As workaround one can calculate file size manually and add it as knownLength option +FormData.prototype.getLengthSync = function () { + var knownLength = this._overheadLength + this._valueLength; + + // Don't get confused, there are 3 "internal" streams for each keyval pair so it basically checks if there is any value added to the form + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + // https://github.com/form-data/form-data/issues/40 + if (!this.hasKnownLength()) { + /* + * Some async length retrievers are present + * therefore synchronous length calculation is false. + * Please use getLength(callback) to get proper length + */ + this._error(new Error('Cannot calculate proper length in synchronous way.')); + } + + return knownLength; +}; + +// Public API to check if length of added values is known +// https://github.com/form-data/form-data/issues/196 +// https://github.com/form-data/form-data/issues/262 +FormData.prototype.hasKnownLength = function () { + var hasKnownLength = true; + + if (this._valuesToMeasure.length) { + hasKnownLength = false; + } + + return hasKnownLength; +}; + +FormData.prototype.getLength = function (cb) { + var knownLength = this._overheadLength + this._valueLength; + + if (this._streams.length) { + knownLength += this._lastBoundary().length; + } + + if (!this._valuesToMeasure.length) { + process.nextTick(cb.bind(this, null, knownLength)); + return; + } + + asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function (err, values) { + if (err) { + cb(err); + return; + } + + values.forEach(function (length) { + knownLength += length; + }); + + cb(null, knownLength); + }); +}; + +FormData.prototype.submit = function (params, cb) { + var request; + var options; + var defaults = { method: 'post' }; + + // parse provided url if it's string or treat it as options object + if (typeof params === 'string') { + params = parseUrl(params); // eslint-disable-line no-param-reassign + /* eslint sort-keys: 0 */ + options = populate({ + port: params.port, + path: params.pathname, + host: params.hostname, + protocol: params.protocol + }, defaults); + } else { // use custom params + options = populate(params, defaults); + // if no port provided use default one + if (!options.port) { + options.port = options.protocol === 'https:' ? 443 : 80; + } + } + + // put that good code in getHeaders to some use + options.headers = this.getHeaders(params.headers); + + // https if specified, fallback to http in any other case + if (options.protocol === 'https:') { + request = https.request(options); + } else { + request = http.request(options); + } + + // get content length and fire away + this.getLength(function (err, length) { + if (err && err !== 'Unknown stream') { + this._error(err); + return; + } + + // add content length + if (length) { + request.setHeader('Content-Length', length); + } + + this.pipe(request); + if (cb) { + var onResponse; + + var callback = function (error, responce) { + request.removeListener('error', callback); + request.removeListener('response', onResponse); + + return cb.call(this, error, responce); // eslint-disable-line no-invalid-this + }; + + onResponse = callback.bind(this, null); + + request.on('error', callback); + request.on('response', onResponse); + } + }.bind(this)); + + return request; +}; + +FormData.prototype._error = function (err) { + if (!this.error) { + this.error = err; + this.pause(); + this.emit('error', err); + } +}; + +FormData.prototype.toString = function () { + return '[object FormData]'; +}; +setToStringTag(FormData, 'FormData'); + +// Public API +module.exports = FormData; diff --git a/node_modules/form-data/lib/populate.js b/node_modules/form-data/lib/populate.js new file mode 100644 index 0000000..55ac3bb --- /dev/null +++ b/node_modules/form-data/lib/populate.js @@ -0,0 +1,10 @@ +'use strict'; + +// populates missing values +module.exports = function (dst, src) { + Object.keys(src).forEach(function (prop) { + dst[prop] = dst[prop] || src[prop]; // eslint-disable-line no-param-reassign + }); + + return dst; +}; diff --git a/node_modules/form-data/package.json b/node_modules/form-data/package.json new file mode 100644 index 0000000..e8d1e7d --- /dev/null +++ b/node_modules/form-data/package.json @@ -0,0 +1,82 @@ +{ + "author": "Felix Geisendörfer (http://debuggable.com/)", + "name": "form-data", + "description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", + "version": "4.0.4", + "repository": { + "type": "git", + "url": "git://github.com/form-data/form-data.git" + }, + "main": "./lib/form_data", + "browser": "./lib/browser", + "typings": "./index.d.ts", + "scripts": { + "pretest": "npm run lint", + "pretests-only": "rimraf coverage test/tmp", + "tests-only": "istanbul cover test/run.js", + "posttests-only": "istanbul report lcov text", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "lint": "eslint --ext=js,mjs .", + "report": "istanbul report lcov text", + "ci-lint": "is-node-modern 8 && npm run lint || is-node-not-modern 8", + "ci-test": "npm run tests-only && npm run browser && npm run report", + "predebug": "rimraf coverage test/tmp", + "debug": "verbose=1 ./test/run.js", + "browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage", + "check": "istanbul check-coverage coverage/coverage*.json", + "files": "pkgfiles --sort=name", + "get-version": "node -e \"console.log(require('./package.json').version)\"", + "update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md", + "postupdate-readme": "mv README.md.bak READ.ME.md.bak", + "restore-readme": "mv READ.ME.md.bak README.md", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepack": "npm run update-readme", + "postpack": "npm run restore-readme", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "engines": { + "node": ">= 6" + }, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.2.0", + "auto-changelog": "^2.5.0", + "browserify": "^13.3.0", + "browserify-istanbul": "^2.0.0", + "coveralls": "^3.1.1", + "cross-spawn": "^6.0.6", + "eslint": "=8.8.0", + "fake": "^0.2.2", + "far": "^0.0.7", + "formidable": "^1.2.6", + "in-publish": "^2.0.1", + "is-node-modern": "^1.0.0", + "istanbul": "^0.4.5", + "obake": "^0.1.2", + "pkgfiles": "^2.3.2", + "pre-commit": "^1.2.2", + "predict-v8-randomness": "^1.0.35", + "puppeteer": "^1.20.0", + "request": "~2.87.0", + "rimraf": "^2.7.1", + "semver": "^6.3.1", + "tape": "^5.9.0" + }, + "license": "MIT", + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + } +} diff --git a/node_modules/function-bind/.eslintrc b/node_modules/function-bind/.eslintrc new file mode 100644 index 0000000..71a054f --- /dev/null +++ b/node_modules/function-bind/.eslintrc @@ -0,0 +1,21 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "func-name-matching": 0, + "indent": [2, 4], + "no-new-func": [1], + }, + + "overrides": [ + { + "files": "test/**", + "rules": { + "max-lines-per-function": 0, + "strict": [0] + }, + }, + ], +} diff --git a/node_modules/function-bind/.github/FUNDING.yml b/node_modules/function-bind/.github/FUNDING.yml new file mode 100644 index 0000000..7448219 --- /dev/null +++ b/node_modules/function-bind/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/function-bind +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/function-bind/.github/SECURITY.md b/node_modules/function-bind/.github/SECURITY.md new file mode 100644 index 0000000..82e4285 --- /dev/null +++ b/node_modules/function-bind/.github/SECURITY.md @@ -0,0 +1,3 @@ +# Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. diff --git a/node_modules/function-bind/.nycrc b/node_modules/function-bind/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/function-bind/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/function-bind/CHANGELOG.md b/node_modules/function-bind/CHANGELOG.md new file mode 100644 index 0000000..f9e6cc0 --- /dev/null +++ b/node_modules/function-bind/CHANGELOG.md @@ -0,0 +1,136 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.1.2](https://github.com/ljharb/function-bind/compare/v1.1.1...v1.1.2) - 2023-10-12 + +### Merged + +- Point to the correct file [`#16`](https://github.com/ljharb/function-bind/pull/16) + +### Commits + +- [Tests] migrate tests to Github Actions [`4f8b57c`](https://github.com/ljharb/function-bind/commit/4f8b57c02f2011fe9ae353d5e74e8745f0988af8) +- [Tests] remove `jscs` [`90eb2ed`](https://github.com/ljharb/function-bind/commit/90eb2edbeefd5b76cd6c3a482ea3454db169b31f) +- [meta] update `.gitignore` [`53fcdc3`](https://github.com/ljharb/function-bind/commit/53fcdc371cd66634d6e9b71c836a50f437e89fed) +- [Tests] up to `node` `v11.10`, `v10.15`, `v9.11`, `v8.15`, `v6.16`, `v4.9`; use `nvm install-latest-npm`; run audit script in tests [`1fe8f6e`](https://github.com/ljharb/function-bind/commit/1fe8f6e9aed0dfa8d8b3cdbd00c7f5ea0cd2b36e) +- [meta] add `auto-changelog` [`1921fcb`](https://github.com/ljharb/function-bind/commit/1921fcb5b416b63ffc4acad051b6aad5722f777d) +- [Robustness] remove runtime dependency on all builtins except `.apply` [`f743e61`](https://github.com/ljharb/function-bind/commit/f743e61aa6bb2360358c04d4884c9db853d118b7) +- Docs: enable badges; update wording [`503cb12`](https://github.com/ljharb/function-bind/commit/503cb12d998b5f91822776c73332c7adcd6355dd) +- [readme] update badges [`290c5db`](https://github.com/ljharb/function-bind/commit/290c5dbbbda7264efaeb886552a374b869a4bb48) +- [Tests] switch to nyc for coverage [`ea360ba`](https://github.com/ljharb/function-bind/commit/ea360ba907fc2601ed18d01a3827fa2d3533cdf8) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`cae5e9e`](https://github.com/ljharb/function-bind/commit/cae5e9e07a5578dc6df26c03ee22851ce05b943c) +- [meta] add `funding` field; create FUNDING.yml [`c9f4274`](https://github.com/ljharb/function-bind/commit/c9f4274aa80ea3aae9657a3938fdba41a3b04ca6) +- [Tests] fix eslint errors from #15 [`f69aaa2`](https://github.com/ljharb/function-bind/commit/f69aaa2beb2fdab4415bfb885760a699d0b9c964) +- [actions] fix permissions [`99a0cd9`](https://github.com/ljharb/function-bind/commit/99a0cd9f3b5bac223a0d572f081834cd73314be7) +- [meta] use `npmignore` to autogenerate an npmignore file [`f03b524`](https://github.com/ljharb/function-bind/commit/f03b524ca91f75a109a5d062f029122c86ecd1ae) +- [Dev Deps] update `@ljharb/eslint‑config`, `eslint`, `tape` [`7af9300`](https://github.com/ljharb/function-bind/commit/7af930023ae2ce7645489532821e4fbbcd7a2280) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `covert`, `tape` [`64a9127`](https://github.com/ljharb/function-bind/commit/64a9127ab0bd331b93d6572eaf6e9971967fc08c) +- [Tests] use `aud` instead of `npm audit` [`e75069c`](https://github.com/ljharb/function-bind/commit/e75069c50010a8fcce2a9ce2324934c35fdb4386) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`d03555c`](https://github.com/ljharb/function-bind/commit/d03555ca59dea3b71ce710045e4303b9e2619e28) +- [meta] add `safe-publish-latest` [`9c8f809`](https://github.com/ljharb/function-bind/commit/9c8f8092aed027d7e80c94f517aa892385b64f09) +- [Dev Deps] update `@ljharb/eslint-config`, `tape` [`baf6893`](https://github.com/ljharb/function-bind/commit/baf6893e27f5b59abe88bc1995e6f6ed1e527397) +- [meta] create SECURITY.md [`4db1779`](https://github.com/ljharb/function-bind/commit/4db17799f1f28ae294cb95e0081ca2b591c3911b) +- [Tests] add `npm run audit` [`c8b38ec`](https://github.com/ljharb/function-bind/commit/c8b38ec40ed3f85dabdee40ed4148f1748375bc2) +- Revert "Point to the correct file" [`05cdf0f`](https://github.com/ljharb/function-bind/commit/05cdf0fa205c6a3c5ba40bbedd1dfa9874f915c9) + +## [v1.1.1](https://github.com/ljharb/function-bind/compare/v1.1.0...v1.1.1) - 2017-08-28 + +### Commits + +- [Tests] up to `node` `v8`; newer npm breaks on older node; fix scripts [`817f7d2`](https://github.com/ljharb/function-bind/commit/817f7d28470fdbff8ef608d4d565dd4d1430bc5e) +- [Dev Deps] update `eslint`, `jscs`, `tape`, `@ljharb/eslint-config` [`854288b`](https://github.com/ljharb/function-bind/commit/854288b1b6f5c555f89aceb9eff1152510262084) +- [Dev Deps] update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`83e639f`](https://github.com/ljharb/function-bind/commit/83e639ff74e6cd6921285bccec22c1bcf72311bd) +- Only apps should have lockfiles [`5ed97f5`](https://github.com/ljharb/function-bind/commit/5ed97f51235c17774e0832e122abda0f3229c908) +- Use a SPDX-compliant “license” field. [`5feefea`](https://github.com/ljharb/function-bind/commit/5feefea0dc0193993e83e5df01ded424403a5381) + +## [v1.1.0](https://github.com/ljharb/function-bind/compare/v1.0.2...v1.1.0) - 2016-02-14 + +### Commits + +- Update `eslint`, `tape`; use my personal shared `eslint` config [`9c9062a`](https://github.com/ljharb/function-bind/commit/9c9062abbe9dd70b59ea2c3a3c3a81f29b457097) +- Add `npm run eslint` [`dd96c56`](https://github.com/ljharb/function-bind/commit/dd96c56720034a3c1ffee10b8a59a6f7c53e24ad) +- [New] return the native `bind` when available. [`82186e0`](https://github.com/ljharb/function-bind/commit/82186e03d73e580f95ff167e03f3582bed90ed72) +- [Dev Deps] update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`a3dd767`](https://github.com/ljharb/function-bind/commit/a3dd76720c795cb7f4586b0544efabf8aa107b8b) +- Update `eslint` [`3dae2f7`](https://github.com/ljharb/function-bind/commit/3dae2f7423de30a2d20313ddb1edc19660142fe9) +- Update `tape`, `covert`, `jscs` [`a181eee`](https://github.com/ljharb/function-bind/commit/a181eee0cfa24eb229c6e843a971f36e060a2f6a) +- [Tests] up to `node` `v5.6`, `v4.3` [`964929a`](https://github.com/ljharb/function-bind/commit/964929a6a4ddb36fb128de2bcc20af5e4f22e1ed) +- Test up to `io.js` `v2.1` [`2be7310`](https://github.com/ljharb/function-bind/commit/2be7310f2f74886a7124ca925be411117d41d5ea) +- Update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`45f3d68`](https://github.com/ljharb/function-bind/commit/45f3d6865c6ca93726abcef54febe009087af101) +- [Dev Deps] update `tape`, `jscs` [`6e1340d`](https://github.com/ljharb/function-bind/commit/6e1340d94642deaecad3e717825db641af4f8b1f) +- [Tests] up to `io.js` `v3.3`, `node` `v4.1` [`d9bad2b`](https://github.com/ljharb/function-bind/commit/d9bad2b778b1b3a6dd2876087b88b3acf319f8cc) +- Update `eslint` [`935590c`](https://github.com/ljharb/function-bind/commit/935590caa024ab356102e4858e8fc315b2ccc446) +- [Dev Deps] update `jscs`, `eslint`, `@ljharb/eslint-config` [`8c9a1ef`](https://github.com/ljharb/function-bind/commit/8c9a1efd848e5167887aa8501857a0940a480c57) +- Test on `io.js` `v2.2` [`9a3a38c`](https://github.com/ljharb/function-bind/commit/9a3a38c92013aed6e108666e7bd40969b84ac86e) +- Run `travis-ci` tests on `iojs` and `node` v0.12; speed up builds; allow 0.8 failures. [`69afc26`](https://github.com/ljharb/function-bind/commit/69afc2617405b147dd2a8d8ae73ca9e9283f18b4) +- [Dev Deps] Update `tape`, `eslint` [`36c1be0`](https://github.com/ljharb/function-bind/commit/36c1be0ab12b45fe5df6b0fdb01a5d5137fd0115) +- Update `tape`, `jscs` [`98d8303`](https://github.com/ljharb/function-bind/commit/98d8303cd5ca1c6b8f985469f86b0d44d7d45f6e) +- Update `jscs` [`9633a4e`](https://github.com/ljharb/function-bind/commit/9633a4e9fbf82051c240855166e468ba8ba0846f) +- Update `tape`, `jscs` [`c80ef0f`](https://github.com/ljharb/function-bind/commit/c80ef0f46efc9791e76fa50de4414092ac147831) +- Test up to `io.js` `v3.0` [`7e2c853`](https://github.com/ljharb/function-bind/commit/7e2c8537d52ab9cf5a655755561d8917684c0df4) +- Test on `io.js` `v2.4` [`5a199a2`](https://github.com/ljharb/function-bind/commit/5a199a27ba46795ba5eaf0845d07d4b8232895c9) +- Test on `io.js` `v2.3` [`a511b88`](https://github.com/ljharb/function-bind/commit/a511b8896de0bddf3b56862daa416c701f4d0453) +- Fixing a typo from 822b4e1938db02dc9584aa434fd3a45cb20caf43 [`732d6b6`](https://github.com/ljharb/function-bind/commit/732d6b63a9b33b45230e630dbcac7a10855d3266) +- Update `jscs` [`da52a48`](https://github.com/ljharb/function-bind/commit/da52a4886c06d6490f46ae30b15e4163ba08905d) +- Lock covert to v1.0.0. [`d6150fd`](https://github.com/ljharb/function-bind/commit/d6150fda1e6f486718ebdeff823333d9e48e7430) + +## [v1.0.2](https://github.com/ljharb/function-bind/compare/v1.0.1...v1.0.2) - 2014-10-04 + +## [v1.0.1](https://github.com/ljharb/function-bind/compare/v1.0.0...v1.0.1) - 2014-10-03 + +### Merged + +- make CI build faster [`#3`](https://github.com/ljharb/function-bind/pull/3) + +### Commits + +- Using my standard jscs.json [`d8ee94c`](https://github.com/ljharb/function-bind/commit/d8ee94c993eff0a84cf5744fe6a29627f5cffa1a) +- Adding `npm run lint` [`7571ab7`](https://github.com/ljharb/function-bind/commit/7571ab7dfdbd99b25a1dbb2d232622bd6f4f9c10) +- Using consistent indentation [`e91a1b1`](https://github.com/ljharb/function-bind/commit/e91a1b13a61e99ec1e530e299b55508f74218a95) +- Updating jscs [`7e17892`](https://github.com/ljharb/function-bind/commit/7e1789284bc629bc9c1547a61c9b227bbd8c7a65) +- Using consistent quotes [`c50b57f`](https://github.com/ljharb/function-bind/commit/c50b57fcd1c5ec38320979c837006069ebe02b77) +- Adding keywords [`cb94631`](https://github.com/ljharb/function-bind/commit/cb946314eed35f21186a25fb42fc118772f9ee00) +- Directly export a function expression instead of using a declaration, and relying on hoisting. [`5a33c5f`](https://github.com/ljharb/function-bind/commit/5a33c5f45642de180e0d207110bf7d1843ceb87c) +- Naming npm URL and badge in README; use SVG [`2aef8fc`](https://github.com/ljharb/function-bind/commit/2aef8fcb79d54e63a58ae557c4e60949e05d5e16) +- Naming deps URLs in README [`04228d7`](https://github.com/ljharb/function-bind/commit/04228d766670ee45ca24e98345c1f6a7621065b5) +- Naming travis-ci URLs in README; using SVG [`62c810c`](https://github.com/ljharb/function-bind/commit/62c810c2f54ced956cd4d4ab7b793055addfe36e) +- Make sure functions are invoked correctly (also passing coverage tests) [`2b289b4`](https://github.com/ljharb/function-bind/commit/2b289b4dfbf037ffcfa4dc95eb540f6165e9e43a) +- Removing the strict mode pragmas; they make tests fail. [`1aa701d`](https://github.com/ljharb/function-bind/commit/1aa701d199ddc3782476e8f7eef82679be97b845) +- Adding myself as a contributor [`85fd57b`](https://github.com/ljharb/function-bind/commit/85fd57b0860e5a7af42de9a287f3f265fc6d72fc) +- Adding strict mode pragmas [`915b08e`](https://github.com/ljharb/function-bind/commit/915b08e084c86a722eafe7245e21db74aa21ca4c) +- Adding devDeps URLs to README [`4ccc731`](https://github.com/ljharb/function-bind/commit/4ccc73112c1769859e4ca3076caf4086b3cba2cd) +- Fixing the description. [`a7a472c`](https://github.com/ljharb/function-bind/commit/a7a472cf649af515c635cf560fc478fbe48999c8) +- Using a function expression instead of a function declaration. [`b5d3e4e`](https://github.com/ljharb/function-bind/commit/b5d3e4ea6aaffc63888953eeb1fbc7ff45f1fa14) +- Updating tape [`f086be6`](https://github.com/ljharb/function-bind/commit/f086be6029fb56dde61a258c1340600fa174d1e0) +- Updating jscs [`5f9bdb3`](https://github.com/ljharb/function-bind/commit/5f9bdb375ab13ba48f30852aab94029520c54d71) +- Updating jscs [`9b409ba`](https://github.com/ljharb/function-bind/commit/9b409ba6118e23395a4e5d83ef39152aab9d3bfc) +- Run coverage as part of tests. [`8e1b6d4`](https://github.com/ljharb/function-bind/commit/8e1b6d459f047d1bd4fee814e01247c984c80bd0) +- Run linter as part of tests [`c1ca83f`](https://github.com/ljharb/function-bind/commit/c1ca83f832df94587d09e621beba682fabfaa987) +- Updating covert [`701e837`](https://github.com/ljharb/function-bind/commit/701e83774b57b4d3ef631e1948143f43a72f4bb9) + +## [v1.0.0](https://github.com/ljharb/function-bind/compare/v0.2.0...v1.0.0) - 2014-08-09 + +### Commits + +- Make sure old and unstable nodes don't fail Travis [`27adca3`](https://github.com/ljharb/function-bind/commit/27adca34a4ab6ad67b6dfde43942a1b103ce4d75) +- Fixing an issue when the bound function is called as a constructor in ES3. [`e20122d`](https://github.com/ljharb/function-bind/commit/e20122d267d92ce553859b280cbbea5d27c07731) +- Adding `npm run coverage` [`a2e29c4`](https://github.com/ljharb/function-bind/commit/a2e29c4ecaef9e2f6cd1603e868c139073375502) +- Updating tape [`b741168`](https://github.com/ljharb/function-bind/commit/b741168b12b235b1717ff696087645526b69213c) +- Upgrading tape [`63631a0`](https://github.com/ljharb/function-bind/commit/63631a04c7fbe97cc2fa61829cc27246d6986f74) +- Updating tape [`363cb46`](https://github.com/ljharb/function-bind/commit/363cb46dafb23cb3e347729a22f9448051d78464) + +## v0.2.0 - 2014-03-23 + +### Commits + +- Updating test coverage to match es5-shim. [`aa94d44`](https://github.com/ljharb/function-bind/commit/aa94d44b8f9d7f69f10e060db7709aa7a694e5d4) +- initial [`942ee07`](https://github.com/ljharb/function-bind/commit/942ee07e94e542d91798137bc4b80b926137e066) +- Setting the bound function's length properly. [`079f46a`](https://github.com/ljharb/function-bind/commit/079f46a2d3515b7c0b308c2c13fceb641f97ca25) +- Ensuring that some older browsers will throw when given a regex. [`36ac55b`](https://github.com/ljharb/function-bind/commit/36ac55b87f460d4330253c92870aa26fbfe8227f) +- Removing npm scripts that don't have dependencies [`9d2be60`](https://github.com/ljharb/function-bind/commit/9d2be600002cb8bc8606f8f3585ad3e05868c750) +- Updating tape [`297a4ac`](https://github.com/ljharb/function-bind/commit/297a4acc5464db381940aafb194d1c88f4e678f3) +- Skipping length tests for now. [`d9891ea`](https://github.com/ljharb/function-bind/commit/d9891ea4d2aaffa69f408339cdd61ff740f70565) +- don't take my tea [`dccd930`](https://github.com/ljharb/function-bind/commit/dccd930bfd60ea10cb178d28c97550c3bc8c1e07) diff --git a/node_modules/function-bind/LICENSE b/node_modules/function-bind/LICENSE new file mode 100644 index 0000000..62d6d23 --- /dev/null +++ b/node_modules/function-bind/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2013 Raynos. + +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. + diff --git a/node_modules/function-bind/README.md b/node_modules/function-bind/README.md new file mode 100644 index 0000000..814c20b --- /dev/null +++ b/node_modules/function-bind/README.md @@ -0,0 +1,46 @@ +# function-bind [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] + +[![dependency status][deps-svg]][deps-url] +[![dev dependency status][dev-deps-svg]][dev-deps-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Implementation of function.prototype.bind + +Old versions of phantomjs, Internet Explorer < 9, and node < 0.6 don't support `Function.prototype.bind`. + +## Example + +```js +Function.prototype.bind = require("function-bind") +``` + +## Installation + +`npm install function-bind` + +## Contributors + + - Raynos + +## MIT Licenced + +[package-url]: https://npmjs.org/package/function-bind +[npm-version-svg]: https://versionbadg.es/Raynos/function-bind.svg +[deps-svg]: https://david-dm.org/Raynos/function-bind.svg +[deps-url]: https://david-dm.org/Raynos/function-bind +[dev-deps-svg]: https://david-dm.org/Raynos/function-bind/dev-status.svg +[dev-deps-url]: https://david-dm.org/Raynos/function-bind#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/function-bind.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/function-bind.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/function-bind.svg +[downloads-url]: https://npm-stat.com/charts.html?package=function-bind +[codecov-image]: https://codecov.io/gh/Raynos/function-bind/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/Raynos/function-bind/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/Raynos/function-bind +[actions-url]: https://github.com/Raynos/function-bind/actions diff --git a/node_modules/function-bind/implementation.js b/node_modules/function-bind/implementation.js new file mode 100644 index 0000000..fd4384c --- /dev/null +++ b/node_modules/function-bind/implementation.js @@ -0,0 +1,84 @@ +'use strict'; + +/* eslint no-invalid-this: 1 */ + +var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible '; +var toStr = Object.prototype.toString; +var max = Math.max; +var funcType = '[object Function]'; + +var concatty = function concatty(a, b) { + var arr = []; + + for (var i = 0; i < a.length; i += 1) { + arr[i] = a[i]; + } + for (var j = 0; j < b.length; j += 1) { + arr[j + a.length] = b[j]; + } + + return arr; +}; + +var slicy = function slicy(arrLike, offset) { + var arr = []; + for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) { + arr[j] = arrLike[i]; + } + return arr; +}; + +var joiny = function (arr, joiner) { + var str = ''; + for (var i = 0; i < arr.length; i += 1) { + str += arr[i]; + if (i + 1 < arr.length) { + str += joiner; + } + } + return str; +}; + +module.exports = function bind(that) { + var target = this; + if (typeof target !== 'function' || toStr.apply(target) !== funcType) { + throw new TypeError(ERROR_MESSAGE + target); + } + var args = slicy(arguments, 1); + + var bound; + var binder = function () { + if (this instanceof bound) { + var result = target.apply( + this, + concatty(args, arguments) + ); + if (Object(result) === result) { + return result; + } + return this; + } + return target.apply( + that, + concatty(args, arguments) + ); + + }; + + var boundLength = max(0, target.length - args.length); + var boundArgs = []; + for (var i = 0; i < boundLength; i++) { + boundArgs[i] = '$' + i; + } + + bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder); + + if (target.prototype) { + var Empty = function Empty() {}; + Empty.prototype = target.prototype; + bound.prototype = new Empty(); + Empty.prototype = null; + } + + return bound; +}; diff --git a/node_modules/function-bind/index.js b/node_modules/function-bind/index.js new file mode 100644 index 0000000..3bb6b96 --- /dev/null +++ b/node_modules/function-bind/index.js @@ -0,0 +1,5 @@ +'use strict'; + +var implementation = require('./implementation'); + +module.exports = Function.prototype.bind || implementation; diff --git a/node_modules/function-bind/package.json b/node_modules/function-bind/package.json new file mode 100644 index 0000000..6185963 --- /dev/null +++ b/node_modules/function-bind/package.json @@ -0,0 +1,87 @@ +{ + "name": "function-bind", + "version": "1.1.2", + "description": "Implementation of Function.prototype.bind", + "keywords": [ + "function", + "bind", + "shim", + "es5" + ], + "author": "Raynos ", + "repository": { + "type": "git", + "url": "https://github.com/Raynos/function-bind.git" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "main": "index", + "homepage": "https://github.com/Raynos/function-bind", + "contributors": [ + { + "name": "Raynos" + }, + { + "name": "Jordan Harband", + "url": "https://github.com/ljharb" + } + ], + "bugs": { + "url": "https://github.com/Raynos/function-bind/issues", + "email": "raynos2@gmail.com" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.1.0", + "aud": "^2.0.3", + "auto-changelog": "^2.4.0", + "eslint": "=8.8.0", + "in-publish": "^2.0.1", + "npmignore": "^0.3.0", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.7.1" + }, + "license": "MIT", + "scripts": { + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepack": "npmignore --auto --commentLines=autogenerated", + "pretest": "npm run lint", + "test": "npm run tests-only", + "posttest": "aud --production", + "tests-only": "nyc tape 'test/**/*.js'", + "lint": "eslint --ext=js,mjs .", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "testling": { + "files": "test/index.js", + "browsers": [ + "ie/8..latest", + "firefox/16..latest", + "firefox/nightly", + "chrome/22..latest", + "chrome/canary", + "opera/12..latest", + "opera/next", + "safari/5.1..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2..latest" + ] + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + } +} diff --git a/node_modules/function-bind/test/.eslintrc b/node_modules/function-bind/test/.eslintrc new file mode 100644 index 0000000..8a56d5b --- /dev/null +++ b/node_modules/function-bind/test/.eslintrc @@ -0,0 +1,9 @@ +{ + "rules": { + "array-bracket-newline": 0, + "array-element-newline": 0, + "max-statements-per-line": [2, { "max": 2 }], + "no-invalid-this": 0, + "no-magic-numbers": 0, + } +} diff --git a/node_modules/function-bind/test/index.js b/node_modules/function-bind/test/index.js new file mode 100644 index 0000000..2edecce --- /dev/null +++ b/node_modules/function-bind/test/index.js @@ -0,0 +1,252 @@ +// jscs:disable requireUseStrict + +var test = require('tape'); + +var functionBind = require('../implementation'); +var getCurrentContext = function () { return this; }; + +test('functionBind is a function', function (t) { + t.equal(typeof functionBind, 'function'); + t.end(); +}); + +test('non-functions', function (t) { + var nonFunctions = [true, false, [], {}, 42, 'foo', NaN, /a/g]; + t.plan(nonFunctions.length); + for (var i = 0; i < nonFunctions.length; ++i) { + try { functionBind.call(nonFunctions[i]); } catch (ex) { + t.ok(ex instanceof TypeError, 'throws when given ' + String(nonFunctions[i])); + } + } + t.end(); +}); + +test('without a context', function (t) { + t.test('binds properly', function (st) { + var args, context; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + context = this; + }) + }; + namespace.func(1, 2, 3); + st.deepEqual(args, [1, 2, 3]); + st.equal(context, getCurrentContext.call()); + st.end(); + }); + + t.test('binds properly, and still supplies bound arguments', function (st) { + var args, context; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + context = this; + }, undefined, 1, 2, 3) + }; + namespace.func(4, 5, 6); + st.deepEqual(args, [1, 2, 3, 4, 5, 6]); + st.equal(context, getCurrentContext.call()); + st.end(); + }); + + t.test('returns properly', function (st) { + var args; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + return this; + }, null) + }; + var context = namespace.func(1, 2, 3); + st.equal(context, getCurrentContext.call(), 'returned context is namespaced context'); + st.deepEqual(args, [1, 2, 3], 'passed arguments are correct'); + st.end(); + }); + + t.test('returns properly with bound arguments', function (st) { + var args; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + return this; + }, null, 1, 2, 3) + }; + var context = namespace.func(4, 5, 6); + st.equal(context, getCurrentContext.call(), 'returned context is namespaced context'); + st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct'); + st.end(); + }); + + t.test('called as a constructor', function (st) { + var thunkify = function (value) { + return function () { return value; }; + }; + st.test('returns object value', function (sst) { + var expectedReturnValue = [1, 2, 3]; + var Constructor = functionBind.call(thunkify(expectedReturnValue), null); + var result = new Constructor(); + sst.equal(result, expectedReturnValue); + sst.end(); + }); + + st.test('does not return primitive value', function (sst) { + var Constructor = functionBind.call(thunkify(42), null); + var result = new Constructor(); + sst.notEqual(result, 42); + sst.end(); + }); + + st.test('object from bound constructor is instance of original and bound constructor', function (sst) { + var A = function (x) { + this.name = x || 'A'; + }; + var B = functionBind.call(A, null, 'B'); + + var result = new B(); + sst.ok(result instanceof B, 'result is instance of bound constructor'); + sst.ok(result instanceof A, 'result is instance of original constructor'); + sst.end(); + }); + + st.end(); + }); + + t.end(); +}); + +test('with a context', function (t) { + t.test('with no bound arguments', function (st) { + var args, context; + var boundContext = {}; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + context = this; + }, boundContext) + }; + namespace.func(1, 2, 3); + st.equal(context, boundContext, 'binds a context properly'); + st.deepEqual(args, [1, 2, 3], 'supplies passed arguments'); + st.end(); + }); + + t.test('with bound arguments', function (st) { + var args, context; + var boundContext = {}; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + context = this; + }, boundContext, 1, 2, 3) + }; + namespace.func(4, 5, 6); + st.equal(context, boundContext, 'binds a context properly'); + st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'supplies bound and passed arguments'); + st.end(); + }); + + t.test('returns properly', function (st) { + var boundContext = {}; + var args; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + return this; + }, boundContext) + }; + var context = namespace.func(1, 2, 3); + st.equal(context, boundContext, 'returned context is bound context'); + st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context'); + st.deepEqual(args, [1, 2, 3], 'passed arguments are correct'); + st.end(); + }); + + t.test('returns properly with bound arguments', function (st) { + var boundContext = {}; + var args; + var namespace = { + func: functionBind.call(function () { + args = Array.prototype.slice.call(arguments); + return this; + }, boundContext, 1, 2, 3) + }; + var context = namespace.func(4, 5, 6); + st.equal(context, boundContext, 'returned context is bound context'); + st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context'); + st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct'); + st.end(); + }); + + t.test('passes the correct arguments when called as a constructor', function (st) { + var expected = { name: 'Correct' }; + var namespace = { + Func: functionBind.call(function (arg) { + return arg; + }, { name: 'Incorrect' }) + }; + var returned = new namespace.Func(expected); + st.equal(returned, expected, 'returns the right arg when called as a constructor'); + st.end(); + }); + + t.test('has the new instance\'s context when called as a constructor', function (st) { + var actualContext; + var expectedContext = { foo: 'bar' }; + var namespace = { + Func: functionBind.call(function () { + actualContext = this; + }, expectedContext) + }; + var result = new namespace.Func(); + st.equal(result instanceof namespace.Func, true); + st.notEqual(actualContext, expectedContext); + st.end(); + }); + + t.end(); +}); + +test('bound function length', function (t) { + t.test('sets a correct length without thisArg', function (st) { + var subject = functionBind.call(function (a, b, c) { return a + b + c; }); + st.equal(subject.length, 3); + st.equal(subject(1, 2, 3), 6); + st.end(); + }); + + t.test('sets a correct length with thisArg', function (st) { + var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}); + st.equal(subject.length, 3); + st.equal(subject(1, 2, 3), 6); + st.end(); + }); + + t.test('sets a correct length without thisArg and first argument', function (st) { + var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1); + st.equal(subject.length, 2); + st.equal(subject(2, 3), 6); + st.end(); + }); + + t.test('sets a correct length with thisArg and first argument', function (st) { + var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1); + st.equal(subject.length, 2); + st.equal(subject(2, 3), 6); + st.end(); + }); + + t.test('sets a correct length without thisArg and too many arguments', function (st) { + var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1, 2, 3, 4); + st.equal(subject.length, 0); + st.equal(subject(), 6); + st.end(); + }); + + t.test('sets a correct length with thisArg and too many arguments', function (st) { + var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1, 2, 3, 4); + st.equal(subject.length, 0); + st.equal(subject(), 6); + st.end(); + }); +}); diff --git a/node_modules/get-intrinsic/.eslintrc b/node_modules/get-intrinsic/.eslintrc new file mode 100644 index 0000000..235fb79 --- /dev/null +++ b/node_modules/get-intrinsic/.eslintrc @@ -0,0 +1,42 @@ +{ + "root": true, + + "extends": "@ljharb", + + "env": { + "es6": true, + "es2017": true, + "es2020": true, + "es2021": true, + "es2022": true, + }, + + "globals": { + "Float16Array": false, + }, + + "rules": { + "array-bracket-newline": 0, + "complexity": 0, + "eqeqeq": [2, "allow-null"], + "func-name-matching": 0, + "id-length": 0, + "max-lines": 0, + "max-lines-per-function": [2, 90], + "max-params": [2, 4], + "max-statements": 0, + "max-statements-per-line": [2, { "max": 2 }], + "multiline-comment-style": 0, + "no-magic-numbers": 0, + "sort-keys": 0, + }, + + "overrides": [ + { + "files": "test/**", + "rules": { + "new-cap": 0, + }, + }, + ], +} diff --git a/node_modules/get-intrinsic/.github/FUNDING.yml b/node_modules/get-intrinsic/.github/FUNDING.yml new file mode 100644 index 0000000..8e8da0d --- /dev/null +++ b/node_modules/get-intrinsic/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/get-intrinsic +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/get-intrinsic/.nycrc b/node_modules/get-intrinsic/.nycrc new file mode 100644 index 0000000..bdd626c --- /dev/null +++ b/node_modules/get-intrinsic/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/get-intrinsic/CHANGELOG.md b/node_modules/get-intrinsic/CHANGELOG.md new file mode 100644 index 0000000..ce1dd98 --- /dev/null +++ b/node_modules/get-intrinsic/CHANGELOG.md @@ -0,0 +1,186 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.3.0](https://github.com/ljharb/get-intrinsic/compare/v1.2.7...v1.3.0) - 2025-02-22 + +### Commits + +- [Dev Deps] update `es-abstract`, `es-value-fixtures`, `for-each`, `object-inspect` [`9b61553`](https://github.com/ljharb/get-intrinsic/commit/9b61553c587f1c1edbd435597e88c7d387da97dd) +- [Deps] update `call-bind-apply-helpers`, `es-object-atoms`, `get-proto` [`a341fee`](https://github.com/ljharb/get-intrinsic/commit/a341fee0f39a403b0f0069e82c97642d5eb11043) +- [New] add `Float16Array` [`de22116`](https://github.com/ljharb/get-intrinsic/commit/de22116b492fb989a0341bceb6e573abfaed73dc) + +## [v1.2.7](https://github.com/ljharb/get-intrinsic/compare/v1.2.6...v1.2.7) - 2025-01-02 + +### Commits + +- [Refactor] use `get-proto` directly [`00ab955`](https://github.com/ljharb/get-intrinsic/commit/00ab95546a0980c8ad42a84253daaa8d2adcedf9) +- [Deps] update `math-intrinsics` [`c716cdd`](https://github.com/ljharb/get-intrinsic/commit/c716cdd6bbe36b438057025561b8bb5a879ac8a0) +- [Dev Deps] update `call-bound`, `es-abstract` [`dc648a6`](https://github.com/ljharb/get-intrinsic/commit/dc648a67eb359037dff8d8619bfa71d86debccb1) + +## [v1.2.6](https://github.com/ljharb/get-intrinsic/compare/v1.2.5...v1.2.6) - 2024-12-11 + +### Commits + +- [Refactor] use `math-intrinsics` [`841be86`](https://github.com/ljharb/get-intrinsic/commit/841be8641a9254c4c75483b30c8871b5d5065926) +- [Refactor] use `es-object-atoms` [`42057df`](https://github.com/ljharb/get-intrinsic/commit/42057dfa16f66f64787e66482af381cc6f31d2c1) +- [Deps] update `call-bind-apply-helpers` [`45afa24`](https://github.com/ljharb/get-intrinsic/commit/45afa24a9ee4d6d3c172db1f555b16cb27843ef4) +- [Dev Deps] update `call-bound` [`9cba9c6`](https://github.com/ljharb/get-intrinsic/commit/9cba9c6e70212bc163b7a5529cb25df46071646f) + +## [v1.2.5](https://github.com/ljharb/get-intrinsic/compare/v1.2.4...v1.2.5) - 2024-12-06 + +### Commits + +- [actions] split out node 10-20, and 20+ [`6e2b9dd`](https://github.com/ljharb/get-intrinsic/commit/6e2b9dd23902665681ebe453256ccfe21d7966f0) +- [Refactor] use `dunder-proto` and `call-bind-apply-helpers` instead of `has-proto` [`c095d17`](https://github.com/ljharb/get-intrinsic/commit/c095d179ad0f4fbfff20c8a3e0cb4fe668018998) +- [Refactor] use `gopd` [`9841d5b`](https://github.com/ljharb/get-intrinsic/commit/9841d5b35f7ab4fd2d193f0c741a50a077920e90) +- [Dev Deps] update `@ljharb/eslint-config`, `auto-changelog`, `es-abstract`, `es-value-fixtures`, `gopd`, `mock-property`, `object-inspect`, `tape` [`2d07e01`](https://github.com/ljharb/get-intrinsic/commit/2d07e01310cee2cbaedfead6903df128b1f5d425) +- [Deps] update `gopd`, `has-proto`, `has-symbols`, `hasown` [`974d8bf`](https://github.com/ljharb/get-intrinsic/commit/974d8bf5baad7939eef35c25cc1dd88c10a30fa6) +- [Dev Deps] update `call-bind`, `es-abstract`, `tape` [`df9dde1`](https://github.com/ljharb/get-intrinsic/commit/df9dde178186631ab8a3165ede056549918ce4bc) +- [Refactor] cache `es-define-property` as well [`43ef543`](https://github.com/ljharb/get-intrinsic/commit/43ef543cb02194401420e3a914a4ca9168691926) +- [Deps] update `has-proto`, `has-symbols`, `hasown` [`ad4949d`](https://github.com/ljharb/get-intrinsic/commit/ad4949d5467316505aad89bf75f9417ed782f7af) +- [Tests] use `call-bound` directly [`ad5c406`](https://github.com/ljharb/get-intrinsic/commit/ad5c4069774bfe90e520a35eead5fe5ca9d69e80) +- [Deps] update `has-proto`, `hasown` [`45414ca`](https://github.com/ljharb/get-intrinsic/commit/45414caa312333a2798953682c68f85c550627dd) +- [Tests] replace `aud` with `npm audit` [`18d3509`](https://github.com/ljharb/get-intrinsic/commit/18d3509f79460e7924da70409ee81e5053087523) +- [Deps] update `es-define-property` [`aadaa3b`](https://github.com/ljharb/get-intrinsic/commit/aadaa3b2188d77ad9bff394ce5d4249c49eb21f5) +- [Dev Deps] add missing peer dep [`c296a16`](https://github.com/ljharb/get-intrinsic/commit/c296a16246d0c9a5981944f4cc5cf61fbda0cf6a) + +## [v1.2.4](https://github.com/ljharb/get-intrinsic/compare/v1.2.3...v1.2.4) - 2024-02-05 + +### Commits + +- [Refactor] use all 7 <+ ES6 Errors from `es-errors` [`bcac811`](https://github.com/ljharb/get-intrinsic/commit/bcac811abdc1c982e12abf848a410d6aae148d14) + +## [v1.2.3](https://github.com/ljharb/get-intrinsic/compare/v1.2.2...v1.2.3) - 2024-02-03 + +### Commits + +- [Refactor] use `es-errors`, so things that only need those do not need `get-intrinsic` [`f11db9c`](https://github.com/ljharb/get-intrinsic/commit/f11db9c4fb97d87bbd53d3c73ac6b3db3613ad3b) +- [Dev Deps] update `aud`, `es-abstract`, `mock-property`, `npmignore` [`b7ac7d1`](https://github.com/ljharb/get-intrinsic/commit/b7ac7d1616fefb03877b1aed0c8f8d61aad32b6c) +- [meta] simplify `exports` [`faa0cc6`](https://github.com/ljharb/get-intrinsic/commit/faa0cc618e2830ffb51a8202490b0c215d965cbc) +- [meta] add missing `engines.node` [`774dd0b`](https://github.com/ljharb/get-intrinsic/commit/774dd0b3e8f741c3f05a6322d124d6087f146af1) +- [Dev Deps] update `tape` [`5828e8e`](https://github.com/ljharb/get-intrinsic/commit/5828e8e4a04e69312e87a36c0ea39428a7a4c3d8) +- [Robustness] use null objects for lookups [`eb9a11f`](https://github.com/ljharb/get-intrinsic/commit/eb9a11fa9eb3e13b193fcc05a7fb814341b1a7b7) +- [meta] add `sideEffects` flag [`89bcc7a`](https://github.com/ljharb/get-intrinsic/commit/89bcc7a42e19bf07b7c21e3094d5ab177109e6d2) + +## [v1.2.2](https://github.com/ljharb/get-intrinsic/compare/v1.2.1...v1.2.2) - 2023-10-20 + +### Commits + +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `call-bind`, `es-abstract`, `mock-property`, `object-inspect`, `tape` [`f51bcf2`](https://github.com/ljharb/get-intrinsic/commit/f51bcf26412d58d17ce17c91c9afd0ad271f0762) +- [Refactor] use `hasown` instead of `has` [`18d14b7`](https://github.com/ljharb/get-intrinsic/commit/18d14b799bea6b5765e1cec91890830cbcdb0587) +- [Deps] update `function-bind` [`6e109c8`](https://github.com/ljharb/get-intrinsic/commit/6e109c81e03804cc5e7824fb64353cdc3d8ee2c7) + +## [v1.2.1](https://github.com/ljharb/get-intrinsic/compare/v1.2.0...v1.2.1) - 2023-05-13 + +### Commits + +- [Fix] avoid a crash in envs without `__proto__` [`7bad8d0`](https://github.com/ljharb/get-intrinsic/commit/7bad8d061bf8721733b58b73a2565af2b6756b64) +- [Dev Deps] update `es-abstract` [`c60e6b7`](https://github.com/ljharb/get-intrinsic/commit/c60e6b7b4cf9660c7f27ed970970fd55fac48dc5) + +## [v1.2.0](https://github.com/ljharb/get-intrinsic/compare/v1.1.3...v1.2.0) - 2023-01-19 + +### Commits + +- [actions] update checkout action [`ca6b12f`](https://github.com/ljharb/get-intrinsic/commit/ca6b12f31eaacea4ea3b055e744cd61623385ffb) +- [Dev Deps] update `@ljharb/eslint-config`, `es-abstract`, `object-inspect`, `tape` [`41a3727`](https://github.com/ljharb/get-intrinsic/commit/41a3727d0026fa04273ae216a5f8e12eefd72da8) +- [Fix] ensure `Error.prototype` is undeniable [`c511e97`](https://github.com/ljharb/get-intrinsic/commit/c511e97ae99c764c4524b540dee7a70757af8da3) +- [Dev Deps] update `aud`, `es-abstract`, `tape` [`1bef8a8`](https://github.com/ljharb/get-intrinsic/commit/1bef8a8fd439ebb80863199b6189199e0851ac67) +- [Dev Deps] update `aud`, `es-abstract` [`0d41f16`](https://github.com/ljharb/get-intrinsic/commit/0d41f16bcd500bc28b7bfc98043ebf61ea081c26) +- [New] add `BigInt64Array` and `BigUint64Array` [`a6cca25`](https://github.com/ljharb/get-intrinsic/commit/a6cca25f29635889b7e9bd669baf9e04be90e48c) +- [Tests] use `gopd` [`ecf7722`](https://github.com/ljharb/get-intrinsic/commit/ecf7722240d15cfd16edda06acf63359c10fb9bd) + +## [v1.1.3](https://github.com/ljharb/get-intrinsic/compare/v1.1.2...v1.1.3) - 2022-09-12 + +### Commits + +- [Dev Deps] update `es-abstract`, `es-value-fixtures`, `tape` [`07ff291`](https://github.com/ljharb/get-intrinsic/commit/07ff291816406ebe5a12d7f16965bde0942dd688) +- [Fix] properly check for % signs [`50ac176`](https://github.com/ljharb/get-intrinsic/commit/50ac1760fe99c227e64eabde76e9c0e44cd881b5) + +## [v1.1.2](https://github.com/ljharb/get-intrinsic/compare/v1.1.1...v1.1.2) - 2022-06-08 + +### Fixed + +- [Fix] properly validate against extra % signs [`#16`](https://github.com/ljharb/get-intrinsic/issues/16) + +### Commits + +- [actions] reuse common workflows [`0972547`](https://github.com/ljharb/get-intrinsic/commit/0972547efd0abc863fe4c445a6ca7eb4f8c6901d) +- [meta] use `npmignore` to autogenerate an npmignore file [`5ba0b51`](https://github.com/ljharb/get-intrinsic/commit/5ba0b51d8d8d4f1c31d426d74abc0770fd106bad) +- [actions] use `node/install` instead of `node/run`; use `codecov` action [`c364492`](https://github.com/ljharb/get-intrinsic/commit/c364492af4af51333e6f81c0bf21fd3d602c3661) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `es-abstract`, `object-inspect`, `tape` [`dc04dad`](https://github.com/ljharb/get-intrinsic/commit/dc04dad86f6e5608775a2640cb0db5927ae29ed9) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es-abstract`, `object-inspect`, `safe-publish-latest`, `tape` [`1c14059`](https://github.com/ljharb/get-intrinsic/commit/1c1405984e86dd2dc9366c15d8a0294a96a146a5) +- [Tests] use `mock-property` [`b396ef0`](https://github.com/ljharb/get-intrinsic/commit/b396ef05bb73b1d699811abd64b0d9b97997fdda) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `object-inspect`, `tape` [`c2c758d`](https://github.com/ljharb/get-intrinsic/commit/c2c758d3b90af4fef0a76910d8d3c292ec8d1d3e) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `es-abstract`, `es-value-fixtures`, `object-inspect`, `tape` [`29e3c09`](https://github.com/ljharb/get-intrinsic/commit/29e3c091c2bf3e17099969847e8729d0e46896de) +- [actions] update codecov uploader [`8cbc141`](https://github.com/ljharb/get-intrinsic/commit/8cbc1418940d7a8941f3a7985cbc4ac095c5e13d) +- [Dev Deps] update `@ljharb/eslint-config`, `es-abstract`, `es-value-fixtures`, `object-inspect`, `tape` [`10b6f5c`](https://github.com/ljharb/get-intrinsic/commit/10b6f5c02593fb3680c581d696ac124e30652932) +- [readme] add github actions/codecov badges [`4e25400`](https://github.com/ljharb/get-intrinsic/commit/4e25400d9f51ae9eb059cbe22d9144e70ea214e8) +- [Tests] use `for-each` instead of `foreach` [`c05b957`](https://github.com/ljharb/get-intrinsic/commit/c05b957ad9a7bc7721af7cc9e9be1edbfe057496) +- [Dev Deps] update `es-abstract` [`29b05ae`](https://github.com/ljharb/get-intrinsic/commit/29b05aec3e7330e9ad0b8e0f685a9112c20cdd97) +- [meta] use `prepublishOnly` script for npm 7+ [`95c285d`](https://github.com/ljharb/get-intrinsic/commit/95c285da810516057d3bbfa871176031af38f05d) +- [Deps] update `has-symbols` [`593cb4f`](https://github.com/ljharb/get-intrinsic/commit/593cb4fb38e7922e40e42c183f45274b636424cd) +- [readme] fix repo URLs [`1c8305b`](https://github.com/ljharb/get-intrinsic/commit/1c8305b5365827c9b6fc785434aac0e1328ff2f5) +- [Deps] update `has-symbols` [`c7138b6`](https://github.com/ljharb/get-intrinsic/commit/c7138b6c6d73132d859471fb8c13304e1e7c8b20) +- [Dev Deps] remove unused `has-bigints` [`bd63aff`](https://github.com/ljharb/get-intrinsic/commit/bd63aff6ad8f3a986c557fcda2914187bdaab359) + +## [v1.1.1](https://github.com/ljharb/get-intrinsic/compare/v1.1.0...v1.1.1) - 2021-02-03 + +### Fixed + +- [meta] export `./package.json` [`#9`](https://github.com/ljharb/get-intrinsic/issues/9) + +### Commits + +- [readme] flesh out the readme; use `evalmd` [`d12f12c`](https://github.com/ljharb/get-intrinsic/commit/d12f12c15345a0a0772cc65a7c64369529abd614) +- [eslint] set up proper globals config [`5a8c098`](https://github.com/ljharb/get-intrinsic/commit/5a8c0984e3319d1ac0e64b102f8ec18b64e79f36) +- [Dev Deps] update `eslint` [`7b9a5c0`](https://github.com/ljharb/get-intrinsic/commit/7b9a5c0d31a90ca1a1234181c74988fb046701cd) + +## [v1.1.0](https://github.com/ljharb/get-intrinsic/compare/v1.0.2...v1.1.0) - 2021-01-25 + +### Fixed + +- [Refactor] delay `Function` eval until syntax-derived values are requested [`#3`](https://github.com/ljharb/get-intrinsic/issues/3) + +### Commits + +- [Tests] migrate tests to Github Actions [`2ab762b`](https://github.com/ljharb/get-intrinsic/commit/2ab762b48164aea8af37a40ba105bbc8246ab8c4) +- [meta] do not publish github action workflow files [`5e7108e`](https://github.com/ljharb/get-intrinsic/commit/5e7108e4768b244d48d9567ba4f8a6cab9c65b8e) +- [Tests] add some coverage [`01ac7a8`](https://github.com/ljharb/get-intrinsic/commit/01ac7a87ac29738567e8524cd8c9e026b1fa8cb3) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `call-bind`, `es-abstract`, `tape`; add `call-bind` [`911b672`](https://github.com/ljharb/get-intrinsic/commit/911b672fbffae433a96924c6ce013585e425f4b7) +- [Refactor] rearrange evalled constructors a bit [`7e7e4bf`](https://github.com/ljharb/get-intrinsic/commit/7e7e4bf583f3799c8ac1c6c5e10d2cb553957347) +- [meta] add Automatic Rebase and Require Allow Edits workflows [`0199968`](https://github.com/ljharb/get-intrinsic/commit/01999687a263ffce0a3cb011dfbcb761754aedbc) + +## [v1.0.2](https://github.com/ljharb/get-intrinsic/compare/v1.0.1...v1.0.2) - 2020-12-17 + +### Commits + +- [Fix] Throw for non‑existent intrinsics [`68f873b`](https://github.com/ljharb/get-intrinsic/commit/68f873b013c732a05ad6f5fc54f697e55515461b) +- [Fix] Throw for non‑existent segments in the intrinsic path [`8325dee`](https://github.com/ljharb/get-intrinsic/commit/8325deee43128f3654d3399aa9591741ebe17b21) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `has-bigints`, `object-inspect` [`0c227a7`](https://github.com/ljharb/get-intrinsic/commit/0c227a7d8b629166f25715fd242553892e458525) +- [meta] do not lint coverage output [`70d2419`](https://github.com/ljharb/get-intrinsic/commit/70d24199b620043cd9110fc5f426d214ebe21dc9) + +## [v1.0.1](https://github.com/ljharb/get-intrinsic/compare/v1.0.0...v1.0.1) - 2020-10-30 + +### Commits + +- [Tests] gather coverage data on every job [`d1d280d`](https://github.com/ljharb/get-intrinsic/commit/d1d280dec714e3f0519cc877dbcb193057d9cac6) +- [Fix] add missing dependencies [`5031771`](https://github.com/ljharb/get-intrinsic/commit/5031771bb1095b38be88ce7c41d5de88718e432e) +- [Tests] use `es-value-fixtures` [`af48765`](https://github.com/ljharb/get-intrinsic/commit/af48765a23c5323fb0b6b38dbf00eb5099c7bebc) + +## v1.0.0 - 2020-10-29 + +### Commits + +- Implementation [`bbce57c`](https://github.com/ljharb/get-intrinsic/commit/bbce57c6f33d05b2d8d3efa273ceeb3ee01127bb) +- Tests [`17b4f0d`](https://github.com/ljharb/get-intrinsic/commit/17b4f0d56dea6b4059b56fc30ef3ee4d9500ebc2) +- Initial commit [`3153294`](https://github.com/ljharb/get-intrinsic/commit/31532948de363b0a27dd9fd4649e7b7028ec4b44) +- npm init [`fb326c4`](https://github.com/ljharb/get-intrinsic/commit/fb326c4d2817c8419ec31de1295f06bb268a7902) +- [meta] add Automatic Rebase and Require Allow Edits workflows [`48862fb`](https://github.com/ljharb/get-intrinsic/commit/48862fb2508c8f6a57968e6d08b7c883afc9d550) +- [meta] add `auto-changelog` [`5f28ad0`](https://github.com/ljharb/get-intrinsic/commit/5f28ad019e060a353d8028f9f2591a9cc93074a1) +- [meta] add "funding"; create `FUNDING.yml` [`c2bbdde`](https://github.com/ljharb/get-intrinsic/commit/c2bbddeba73a875be61484ee4680b129a6d4e0a1) +- [Tests] add `npm run lint` [`0a84b98`](https://github.com/ljharb/get-intrinsic/commit/0a84b98b22b7cf7a748666f705b0003a493c35fd) +- Only apps should have lockfiles [`9586c75`](https://github.com/ljharb/get-intrinsic/commit/9586c75866c1ee678e4d5d4dbbdef6997e511b05) diff --git a/node_modules/get-intrinsic/LICENSE b/node_modules/get-intrinsic/LICENSE new file mode 100644 index 0000000..48f05d0 --- /dev/null +++ b/node_modules/get-intrinsic/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Jordan Harband + +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. diff --git a/node_modules/get-intrinsic/README.md b/node_modules/get-intrinsic/README.md new file mode 100644 index 0000000..3aa0bba --- /dev/null +++ b/node_modules/get-intrinsic/README.md @@ -0,0 +1,71 @@ +# get-intrinsic [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![dependency status][deps-svg]][deps-url] +[![dev dependency status][dev-deps-svg]][dev-deps-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Get and robustly cache all JS language-level intrinsics at first require time. + +See the syntax described [in the JS spec](https://tc39.es/ecma262/#sec-well-known-intrinsic-objects) for reference. + +## Example + +```js +var GetIntrinsic = require('get-intrinsic'); +var assert = require('assert'); + +// static methods +assert.equal(GetIntrinsic('%Math.pow%'), Math.pow); +assert.equal(Math.pow(2, 3), 8); +assert.equal(GetIntrinsic('%Math.pow%')(2, 3), 8); +delete Math.pow; +assert.equal(GetIntrinsic('%Math.pow%')(2, 3), 8); + +// instance methods +var arr = [1]; +assert.equal(GetIntrinsic('%Array.prototype.push%'), Array.prototype.push); +assert.deepEqual(arr, [1]); + +arr.push(2); +assert.deepEqual(arr, [1, 2]); + +GetIntrinsic('%Array.prototype.push%').call(arr, 3); +assert.deepEqual(arr, [1, 2, 3]); + +delete Array.prototype.push; +GetIntrinsic('%Array.prototype.push%').call(arr, 4); +assert.deepEqual(arr, [1, 2, 3, 4]); + +// missing features +delete JSON.parse; // to simulate a real intrinsic that is missing in the environment +assert.throws(() => GetIntrinsic('%JSON.parse%')); +assert.equal(undefined, GetIntrinsic('%JSON.parse%', true)); +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/get-intrinsic +[npm-version-svg]: https://versionbadg.es/ljharb/get-intrinsic.svg +[deps-svg]: https://david-dm.org/ljharb/get-intrinsic.svg +[deps-url]: https://david-dm.org/ljharb/get-intrinsic +[dev-deps-svg]: https://david-dm.org/ljharb/get-intrinsic/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/get-intrinsic#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/get-intrinsic.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/get-intrinsic.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/get-intrinsic.svg +[downloads-url]: https://npm-stat.com/charts.html?package=get-intrinsic +[codecov-image]: https://codecov.io/gh/ljharb/get-intrinsic/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/get-intrinsic/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/get-intrinsic +[actions-url]: https://github.com/ljharb/get-intrinsic/actions diff --git a/node_modules/get-intrinsic/index.js b/node_modules/get-intrinsic/index.js new file mode 100644 index 0000000..bd1d94b --- /dev/null +++ b/node_modules/get-intrinsic/index.js @@ -0,0 +1,378 @@ +'use strict'; + +var undefined; + +var $Object = require('es-object-atoms'); + +var $Error = require('es-errors'); +var $EvalError = require('es-errors/eval'); +var $RangeError = require('es-errors/range'); +var $ReferenceError = require('es-errors/ref'); +var $SyntaxError = require('es-errors/syntax'); +var $TypeError = require('es-errors/type'); +var $URIError = require('es-errors/uri'); + +var abs = require('math-intrinsics/abs'); +var floor = require('math-intrinsics/floor'); +var max = require('math-intrinsics/max'); +var min = require('math-intrinsics/min'); +var pow = require('math-intrinsics/pow'); +var round = require('math-intrinsics/round'); +var sign = require('math-intrinsics/sign'); + +var $Function = Function; + +// eslint-disable-next-line consistent-return +var getEvalledConstructor = function (expressionSyntax) { + try { + return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')(); + } catch (e) {} +}; + +var $gOPD = require('gopd'); +var $defineProperty = require('es-define-property'); + +var throwTypeError = function () { + throw new $TypeError(); +}; +var ThrowTypeError = $gOPD + ? (function () { + try { + // eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties + arguments.callee; // IE 8 does not throw here + return throwTypeError; + } catch (calleeThrows) { + try { + // IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '') + return $gOPD(arguments, 'callee').get; + } catch (gOPDthrows) { + return throwTypeError; + } + } + }()) + : throwTypeError; + +var hasSymbols = require('has-symbols')(); + +var getProto = require('get-proto'); +var $ObjectGPO = require('get-proto/Object.getPrototypeOf'); +var $ReflectGPO = require('get-proto/Reflect.getPrototypeOf'); + +var $apply = require('call-bind-apply-helpers/functionApply'); +var $call = require('call-bind-apply-helpers/functionCall'); + +var needsEval = {}; + +var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array); + +var INTRINSICS = { + __proto__: null, + '%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError, + '%Array%': Array, + '%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer, + '%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined, + '%AsyncFromSyncIteratorPrototype%': undefined, + '%AsyncFunction%': needsEval, + '%AsyncGenerator%': needsEval, + '%AsyncGeneratorFunction%': needsEval, + '%AsyncIteratorPrototype%': needsEval, + '%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics, + '%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt, + '%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array, + '%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array, + '%Boolean%': Boolean, + '%DataView%': typeof DataView === 'undefined' ? undefined : DataView, + '%Date%': Date, + '%decodeURI%': decodeURI, + '%decodeURIComponent%': decodeURIComponent, + '%encodeURI%': encodeURI, + '%encodeURIComponent%': encodeURIComponent, + '%Error%': $Error, + '%eval%': eval, // eslint-disable-line no-eval + '%EvalError%': $EvalError, + '%Float16Array%': typeof Float16Array === 'undefined' ? undefined : Float16Array, + '%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array, + '%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array, + '%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry, + '%Function%': $Function, + '%GeneratorFunction%': needsEval, + '%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array, + '%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array, + '%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array, + '%isFinite%': isFinite, + '%isNaN%': isNaN, + '%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined, + '%JSON%': typeof JSON === 'object' ? JSON : undefined, + '%Map%': typeof Map === 'undefined' ? undefined : Map, + '%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()), + '%Math%': Math, + '%Number%': Number, + '%Object%': $Object, + '%Object.getOwnPropertyDescriptor%': $gOPD, + '%parseFloat%': parseFloat, + '%parseInt%': parseInt, + '%Promise%': typeof Promise === 'undefined' ? undefined : Promise, + '%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy, + '%RangeError%': $RangeError, + '%ReferenceError%': $ReferenceError, + '%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect, + '%RegExp%': RegExp, + '%Set%': typeof Set === 'undefined' ? undefined : Set, + '%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()), + '%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer, + '%String%': String, + '%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined, + '%Symbol%': hasSymbols ? Symbol : undefined, + '%SyntaxError%': $SyntaxError, + '%ThrowTypeError%': ThrowTypeError, + '%TypedArray%': TypedArray, + '%TypeError%': $TypeError, + '%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array, + '%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray, + '%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array, + '%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array, + '%URIError%': $URIError, + '%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap, + '%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef, + '%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet, + + '%Function.prototype.call%': $call, + '%Function.prototype.apply%': $apply, + '%Object.defineProperty%': $defineProperty, + '%Object.getPrototypeOf%': $ObjectGPO, + '%Math.abs%': abs, + '%Math.floor%': floor, + '%Math.max%': max, + '%Math.min%': min, + '%Math.pow%': pow, + '%Math.round%': round, + '%Math.sign%': sign, + '%Reflect.getPrototypeOf%': $ReflectGPO +}; + +if (getProto) { + try { + null.error; // eslint-disable-line no-unused-expressions + } catch (e) { + // https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229 + var errorProto = getProto(getProto(e)); + INTRINSICS['%Error.prototype%'] = errorProto; + } +} + +var doEval = function doEval(name) { + var value; + if (name === '%AsyncFunction%') { + value = getEvalledConstructor('async function () {}'); + } else if (name === '%GeneratorFunction%') { + value = getEvalledConstructor('function* () {}'); + } else if (name === '%AsyncGeneratorFunction%') { + value = getEvalledConstructor('async function* () {}'); + } else if (name === '%AsyncGenerator%') { + var fn = doEval('%AsyncGeneratorFunction%'); + if (fn) { + value = fn.prototype; + } + } else if (name === '%AsyncIteratorPrototype%') { + var gen = doEval('%AsyncGenerator%'); + if (gen && getProto) { + value = getProto(gen.prototype); + } + } + + INTRINSICS[name] = value; + + return value; +}; + +var LEGACY_ALIASES = { + __proto__: null, + '%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'], + '%ArrayPrototype%': ['Array', 'prototype'], + '%ArrayProto_entries%': ['Array', 'prototype', 'entries'], + '%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'], + '%ArrayProto_keys%': ['Array', 'prototype', 'keys'], + '%ArrayProto_values%': ['Array', 'prototype', 'values'], + '%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'], + '%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'], + '%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'], + '%BooleanPrototype%': ['Boolean', 'prototype'], + '%DataViewPrototype%': ['DataView', 'prototype'], + '%DatePrototype%': ['Date', 'prototype'], + '%ErrorPrototype%': ['Error', 'prototype'], + '%EvalErrorPrototype%': ['EvalError', 'prototype'], + '%Float32ArrayPrototype%': ['Float32Array', 'prototype'], + '%Float64ArrayPrototype%': ['Float64Array', 'prototype'], + '%FunctionPrototype%': ['Function', 'prototype'], + '%Generator%': ['GeneratorFunction', 'prototype'], + '%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'], + '%Int8ArrayPrototype%': ['Int8Array', 'prototype'], + '%Int16ArrayPrototype%': ['Int16Array', 'prototype'], + '%Int32ArrayPrototype%': ['Int32Array', 'prototype'], + '%JSONParse%': ['JSON', 'parse'], + '%JSONStringify%': ['JSON', 'stringify'], + '%MapPrototype%': ['Map', 'prototype'], + '%NumberPrototype%': ['Number', 'prototype'], + '%ObjectPrototype%': ['Object', 'prototype'], + '%ObjProto_toString%': ['Object', 'prototype', 'toString'], + '%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'], + '%PromisePrototype%': ['Promise', 'prototype'], + '%PromiseProto_then%': ['Promise', 'prototype', 'then'], + '%Promise_all%': ['Promise', 'all'], + '%Promise_reject%': ['Promise', 'reject'], + '%Promise_resolve%': ['Promise', 'resolve'], + '%RangeErrorPrototype%': ['RangeError', 'prototype'], + '%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'], + '%RegExpPrototype%': ['RegExp', 'prototype'], + '%SetPrototype%': ['Set', 'prototype'], + '%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'], + '%StringPrototype%': ['String', 'prototype'], + '%SymbolPrototype%': ['Symbol', 'prototype'], + '%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'], + '%TypedArrayPrototype%': ['TypedArray', 'prototype'], + '%TypeErrorPrototype%': ['TypeError', 'prototype'], + '%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'], + '%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'], + '%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'], + '%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'], + '%URIErrorPrototype%': ['URIError', 'prototype'], + '%WeakMapPrototype%': ['WeakMap', 'prototype'], + '%WeakSetPrototype%': ['WeakSet', 'prototype'] +}; + +var bind = require('function-bind'); +var hasOwn = require('hasown'); +var $concat = bind.call($call, Array.prototype.concat); +var $spliceApply = bind.call($apply, Array.prototype.splice); +var $replace = bind.call($call, String.prototype.replace); +var $strSlice = bind.call($call, String.prototype.slice); +var $exec = bind.call($call, RegExp.prototype.exec); + +/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */ +var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g; +var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */ +var stringToPath = function stringToPath(string) { + var first = $strSlice(string, 0, 1); + var last = $strSlice(string, -1); + if (first === '%' && last !== '%') { + throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`'); + } else if (last === '%' && first !== '%') { + throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`'); + } + var result = []; + $replace(string, rePropName, function (match, number, quote, subString) { + result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match; + }); + return result; +}; +/* end adaptation */ + +var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) { + var intrinsicName = name; + var alias; + if (hasOwn(LEGACY_ALIASES, intrinsicName)) { + alias = LEGACY_ALIASES[intrinsicName]; + intrinsicName = '%' + alias[0] + '%'; + } + + if (hasOwn(INTRINSICS, intrinsicName)) { + var value = INTRINSICS[intrinsicName]; + if (value === needsEval) { + value = doEval(intrinsicName); + } + if (typeof value === 'undefined' && !allowMissing) { + throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!'); + } + + return { + alias: alias, + name: intrinsicName, + value: value + }; + } + + throw new $SyntaxError('intrinsic ' + name + ' does not exist!'); +}; + +module.exports = function GetIntrinsic(name, allowMissing) { + if (typeof name !== 'string' || name.length === 0) { + throw new $TypeError('intrinsic name must be a non-empty string'); + } + if (arguments.length > 1 && typeof allowMissing !== 'boolean') { + throw new $TypeError('"allowMissing" argument must be a boolean'); + } + + if ($exec(/^%?[^%]*%?$/, name) === null) { + throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name'); + } + var parts = stringToPath(name); + var intrinsicBaseName = parts.length > 0 ? parts[0] : ''; + + var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing); + var intrinsicRealName = intrinsic.name; + var value = intrinsic.value; + var skipFurtherCaching = false; + + var alias = intrinsic.alias; + if (alias) { + intrinsicBaseName = alias[0]; + $spliceApply(parts, $concat([0, 1], alias)); + } + + for (var i = 1, isOwn = true; i < parts.length; i += 1) { + var part = parts[i]; + var first = $strSlice(part, 0, 1); + var last = $strSlice(part, -1); + if ( + ( + (first === '"' || first === "'" || first === '`') + || (last === '"' || last === "'" || last === '`') + ) + && first !== last + ) { + throw new $SyntaxError('property names with quotes must have matching quotes'); + } + if (part === 'constructor' || !isOwn) { + skipFurtherCaching = true; + } + + intrinsicBaseName += '.' + part; + intrinsicRealName = '%' + intrinsicBaseName + '%'; + + if (hasOwn(INTRINSICS, intrinsicRealName)) { + value = INTRINSICS[intrinsicRealName]; + } else if (value != null) { + if (!(part in value)) { + if (!allowMissing) { + throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.'); + } + return void undefined; + } + if ($gOPD && (i + 1) >= parts.length) { + var desc = $gOPD(value, part); + isOwn = !!desc; + + // By convention, when a data property is converted to an accessor + // property to emulate a data property that does not suffer from + // the override mistake, that accessor's getter is marked with + // an `originalValue` property. Here, when we detect this, we + // uphold the illusion by pretending to see that original data + // property, i.e., returning the value rather than the getter + // itself. + if (isOwn && 'get' in desc && !('originalValue' in desc.get)) { + value = desc.get; + } else { + value = value[part]; + } + } else { + isOwn = hasOwn(value, part); + value = value[part]; + } + + if (isOwn && !skipFurtherCaching) { + INTRINSICS[intrinsicRealName] = value; + } + } + } + return value; +}; diff --git a/node_modules/get-intrinsic/package.json b/node_modules/get-intrinsic/package.json new file mode 100644 index 0000000..2828e73 --- /dev/null +++ b/node_modules/get-intrinsic/package.json @@ -0,0 +1,97 @@ +{ + "name": "get-intrinsic", + "version": "1.3.0", + "description": "Get and robustly cache all JS language-level intrinsics at first require time", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "prelint": "evalmd README.md", + "lint": "eslint --ext=.js,.mjs .", + "pretest": "npm run lint", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>= 10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/get-intrinsic.git" + }, + "keywords": [ + "javascript", + "ecmascript", + "es", + "js", + "intrinsic", + "getintrinsic", + "es-abstract" + ], + "author": "Jordan Harband ", + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/get-intrinsic/issues" + }, + "homepage": "https://github.com/ljharb/get-intrinsic#readme", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "devDependencies": { + "@ljharb/eslint-config": "^21.1.1", + "auto-changelog": "^2.5.0", + "call-bound": "^1.0.3", + "encoding": "^0.1.13", + "es-abstract": "^1.23.9", + "es-value-fixtures": "^1.7.1", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "for-each": "^0.3.5", + "make-async-function": "^1.0.0", + "make-async-generator-function": "^1.0.0", + "make-generator-function": "^2.0.0", + "mock-property": "^1.1.0", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "object-inspect": "^1.13.4", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "testling": { + "files": "test/GetIntrinsic.js" + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/get-intrinsic/test/GetIntrinsic.js b/node_modules/get-intrinsic/test/GetIntrinsic.js new file mode 100644 index 0000000..d9c0f30 --- /dev/null +++ b/node_modules/get-intrinsic/test/GetIntrinsic.js @@ -0,0 +1,274 @@ +'use strict'; + +var GetIntrinsic = require('../'); + +var test = require('tape'); +var forEach = require('for-each'); +var debug = require('object-inspect'); +var generatorFns = require('make-generator-function')(); +var asyncFns = require('make-async-function').list(); +var asyncGenFns = require('make-async-generator-function')(); +var mockProperty = require('mock-property'); + +var callBound = require('call-bound'); +var v = require('es-value-fixtures'); +var $gOPD = require('gopd'); +var DefinePropertyOrThrow = require('es-abstract/2023/DefinePropertyOrThrow'); + +var $isProto = callBound('%Object.prototype.isPrototypeOf%'); + +test('export', function (t) { + t.equal(typeof GetIntrinsic, 'function', 'it is a function'); + t.equal(GetIntrinsic.length, 2, 'function has length of 2'); + + t.end(); +}); + +test('throws', function (t) { + t['throws']( + function () { GetIntrinsic('not an intrinsic'); }, + SyntaxError, + 'nonexistent intrinsic throws a syntax error' + ); + + t['throws']( + function () { GetIntrinsic(''); }, + TypeError, + 'empty string intrinsic throws a type error' + ); + + t['throws']( + function () { GetIntrinsic('.'); }, + SyntaxError, + '"just a dot" intrinsic throws a syntax error' + ); + + t['throws']( + function () { GetIntrinsic('%String'); }, + SyntaxError, + 'Leading % without trailing % throws a syntax error' + ); + + t['throws']( + function () { GetIntrinsic('String%'); }, + SyntaxError, + 'Trailing % without leading % throws a syntax error' + ); + + t['throws']( + function () { GetIntrinsic("String['prototype]"); }, + SyntaxError, + 'Dynamic property access is disallowed for intrinsics (unterminated string)' + ); + + t['throws']( + function () { GetIntrinsic('%Proxy.prototype.undefined%'); }, + TypeError, + "Throws when middle part doesn't exist (%Proxy.prototype.undefined%)" + ); + + t['throws']( + function () { GetIntrinsic('%Array.prototype%garbage%'); }, + SyntaxError, + 'Throws with extra percent signs' + ); + + t['throws']( + function () { GetIntrinsic('%Array.prototype%push%'); }, + SyntaxError, + 'Throws with extra percent signs, even on an existing intrinsic' + ); + + forEach(v.nonStrings, function (nonString) { + t['throws']( + function () { GetIntrinsic(nonString); }, + TypeError, + debug(nonString) + ' is not a String' + ); + }); + + forEach(v.nonBooleans, function (nonBoolean) { + t['throws']( + function () { GetIntrinsic('%', nonBoolean); }, + TypeError, + debug(nonBoolean) + ' is not a Boolean' + ); + }); + + forEach([ + 'toString', + 'propertyIsEnumerable', + 'hasOwnProperty' + ], function (objectProtoMember) { + t['throws']( + function () { GetIntrinsic(objectProtoMember); }, + SyntaxError, + debug(objectProtoMember) + ' is not an intrinsic' + ); + }); + + t.end(); +}); + +test('base intrinsics', function (t) { + t.equal(GetIntrinsic('%Object%'), Object, '%Object% yields Object'); + t.equal(GetIntrinsic('Object'), Object, 'Object yields Object'); + t.equal(GetIntrinsic('%Array%'), Array, '%Array% yields Array'); + t.equal(GetIntrinsic('Array'), Array, 'Array yields Array'); + + t.end(); +}); + +test('dotted paths', function (t) { + t.equal(GetIntrinsic('%Object.prototype.toString%'), Object.prototype.toString, '%Object.prototype.toString% yields Object.prototype.toString'); + t.equal(GetIntrinsic('Object.prototype.toString'), Object.prototype.toString, 'Object.prototype.toString yields Object.prototype.toString'); + t.equal(GetIntrinsic('%Array.prototype.push%'), Array.prototype.push, '%Array.prototype.push% yields Array.prototype.push'); + t.equal(GetIntrinsic('Array.prototype.push'), Array.prototype.push, 'Array.prototype.push yields Array.prototype.push'); + + test('underscore paths are aliases for dotted paths', { skip: !Object.isFrozen || Object.isFrozen(Object.prototype) }, function (st) { + var original = GetIntrinsic('%ObjProto_toString%'); + + forEach([ + '%Object.prototype.toString%', + 'Object.prototype.toString', + '%ObjectPrototype.toString%', + 'ObjectPrototype.toString', + '%ObjProto_toString%', + 'ObjProto_toString' + ], function (name) { + DefinePropertyOrThrow(Object.prototype, 'toString', { + '[[Value]]': function toString() { + return original.apply(this, arguments); + } + }); + st.equal(GetIntrinsic(name), original, name + ' yields original Object.prototype.toString'); + }); + + DefinePropertyOrThrow(Object.prototype, 'toString', { '[[Value]]': original }); + st.end(); + }); + + test('dotted paths cache', { skip: !Object.isFrozen || Object.isFrozen(Object.prototype) }, function (st) { + var original = GetIntrinsic('%Object.prototype.propertyIsEnumerable%'); + + forEach([ + '%Object.prototype.propertyIsEnumerable%', + 'Object.prototype.propertyIsEnumerable', + '%ObjectPrototype.propertyIsEnumerable%', + 'ObjectPrototype.propertyIsEnumerable' + ], function (name) { + var restore = mockProperty(Object.prototype, 'propertyIsEnumerable', { + value: function propertyIsEnumerable() { + return original.apply(this, arguments); + } + }); + st.equal(GetIntrinsic(name), original, name + ' yields cached Object.prototype.propertyIsEnumerable'); + + restore(); + }); + + st.end(); + }); + + test('dotted path reports correct error', function (st) { + st['throws'](function () { + GetIntrinsic('%NonExistentIntrinsic.prototype.property%'); + }, /%NonExistentIntrinsic%/, 'The base intrinsic of %NonExistentIntrinsic.prototype.property% is %NonExistentIntrinsic%'); + + st['throws'](function () { + GetIntrinsic('%NonExistentIntrinsicPrototype.property%'); + }, /%NonExistentIntrinsicPrototype%/, 'The base intrinsic of %NonExistentIntrinsicPrototype.property% is %NonExistentIntrinsicPrototype%'); + + st.end(); + }); + + t.end(); +}); + +test('accessors', { skip: !$gOPD || typeof Map !== 'function' }, function (t) { + var actual = $gOPD(Map.prototype, 'size'); + t.ok(actual, 'Map.prototype.size has a descriptor'); + t.equal(typeof actual.get, 'function', 'Map.prototype.size has a getter function'); + t.equal(GetIntrinsic('%Map.prototype.size%'), actual.get, '%Map.prototype.size% yields the getter for it'); + t.equal(GetIntrinsic('Map.prototype.size'), actual.get, 'Map.prototype.size yields the getter for it'); + + t.end(); +}); + +test('generator functions', { skip: !generatorFns.length }, function (t) { + var $GeneratorFunction = GetIntrinsic('%GeneratorFunction%'); + var $GeneratorFunctionPrototype = GetIntrinsic('%Generator%'); + var $GeneratorPrototype = GetIntrinsic('%GeneratorPrototype%'); + + forEach(generatorFns, function (genFn) { + var fnName = genFn.name; + fnName = fnName ? "'" + fnName + "'" : 'genFn'; + + t.ok(genFn instanceof $GeneratorFunction, fnName + ' instanceof %GeneratorFunction%'); + t.ok($isProto($GeneratorFunctionPrototype, genFn), '%Generator% is prototype of ' + fnName); + t.ok($isProto($GeneratorPrototype, genFn.prototype), '%GeneratorPrototype% is prototype of ' + fnName + '.prototype'); + }); + + t.end(); +}); + +test('async functions', { skip: !asyncFns.length }, function (t) { + var $AsyncFunction = GetIntrinsic('%AsyncFunction%'); + var $AsyncFunctionPrototype = GetIntrinsic('%AsyncFunctionPrototype%'); + + forEach(asyncFns, function (asyncFn) { + var fnName = asyncFn.name; + fnName = fnName ? "'" + fnName + "'" : 'asyncFn'; + + t.ok(asyncFn instanceof $AsyncFunction, fnName + ' instanceof %AsyncFunction%'); + t.ok($isProto($AsyncFunctionPrototype, asyncFn), '%AsyncFunctionPrototype% is prototype of ' + fnName); + }); + + t.end(); +}); + +test('async generator functions', { skip: asyncGenFns.length === 0 }, function (t) { + var $AsyncGeneratorFunction = GetIntrinsic('%AsyncGeneratorFunction%'); + var $AsyncGeneratorFunctionPrototype = GetIntrinsic('%AsyncGenerator%'); + var $AsyncGeneratorPrototype = GetIntrinsic('%AsyncGeneratorPrototype%'); + + forEach(asyncGenFns, function (asyncGenFn) { + var fnName = asyncGenFn.name; + fnName = fnName ? "'" + fnName + "'" : 'asyncGenFn'; + + t.ok(asyncGenFn instanceof $AsyncGeneratorFunction, fnName + ' instanceof %AsyncGeneratorFunction%'); + t.ok($isProto($AsyncGeneratorFunctionPrototype, asyncGenFn), '%AsyncGenerator% is prototype of ' + fnName); + t.ok($isProto($AsyncGeneratorPrototype, asyncGenFn.prototype), '%AsyncGeneratorPrototype% is prototype of ' + fnName + '.prototype'); + }); + + t.end(); +}); + +test('%ThrowTypeError%', function (t) { + var $ThrowTypeError = GetIntrinsic('%ThrowTypeError%'); + + t.equal(typeof $ThrowTypeError, 'function', 'is a function'); + t['throws']( + $ThrowTypeError, + TypeError, + '%ThrowTypeError% throws a TypeError' + ); + + t.end(); +}); + +test('allowMissing', { skip: asyncGenFns.length > 0 }, function (t) { + t['throws']( + function () { GetIntrinsic('%AsyncGeneratorPrototype%'); }, + TypeError, + 'throws when missing' + ); + + t.equal( + GetIntrinsic('%AsyncGeneratorPrototype%', true), + undefined, + 'does not throw when allowMissing' + ); + + t.end(); +}); diff --git a/node_modules/get-proto/.eslintrc b/node_modules/get-proto/.eslintrc new file mode 100644 index 0000000..1d21a8a --- /dev/null +++ b/node_modules/get-proto/.eslintrc @@ -0,0 +1,10 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "id-length": "off", + "sort-keys": "off", + }, +} diff --git a/node_modules/get-proto/.github/FUNDING.yml b/node_modules/get-proto/.github/FUNDING.yml new file mode 100644 index 0000000..93183ef --- /dev/null +++ b/node_modules/get-proto/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/get-proto +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/get-proto/.nycrc b/node_modules/get-proto/.nycrc new file mode 100644 index 0000000..bdd626c --- /dev/null +++ b/node_modules/get-proto/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/get-proto/CHANGELOG.md b/node_modules/get-proto/CHANGELOG.md new file mode 100644 index 0000000..5860229 --- /dev/null +++ b/node_modules/get-proto/CHANGELOG.md @@ -0,0 +1,21 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.1](https://github.com/ljharb/get-proto/compare/v1.0.0...v1.0.1) - 2025-01-02 + +### Commits + +- [Fix] for the `Object.getPrototypeOf` window, throw for non-objects [`7fe6508`](https://github.com/ljharb/get-proto/commit/7fe6508b71419ebe1976bedb86001d1feaeaa49a) + +## v1.0.0 - 2025-01-01 + +### Commits + +- Initial implementation, tests, readme, types [`5c70775`](https://github.com/ljharb/get-proto/commit/5c707751e81c3deeb2cf980d185fc7fd43611415) +- Initial commit [`7c65c2a`](https://github.com/ljharb/get-proto/commit/7c65c2ad4e33d5dae2f219ebe1a046ae2256972c) +- npm init [`0b8cf82`](https://github.com/ljharb/get-proto/commit/0b8cf824c9634e4a34ef7dd2a2cdc5be6ac79518) +- Only apps should have lockfiles [`a6d1bff`](https://github.com/ljharb/get-proto/commit/a6d1bffc364f5828377cea7194558b2dbef7aea2) diff --git a/node_modules/get-proto/LICENSE b/node_modules/get-proto/LICENSE new file mode 100644 index 0000000..eeabd1c --- /dev/null +++ b/node_modules/get-proto/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Jordan Harband + +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. diff --git a/node_modules/get-proto/Object.getPrototypeOf.d.ts b/node_modules/get-proto/Object.getPrototypeOf.d.ts new file mode 100644 index 0000000..028b3ff --- /dev/null +++ b/node_modules/get-proto/Object.getPrototypeOf.d.ts @@ -0,0 +1,5 @@ +declare function getProto(object: O): object | null; + +declare const x: typeof getProto | null; + +export = x; \ No newline at end of file diff --git a/node_modules/get-proto/Object.getPrototypeOf.js b/node_modules/get-proto/Object.getPrototypeOf.js new file mode 100644 index 0000000..c2cbbdf --- /dev/null +++ b/node_modules/get-proto/Object.getPrototypeOf.js @@ -0,0 +1,6 @@ +'use strict'; + +var $Object = require('es-object-atoms'); + +/** @type {import('./Object.getPrototypeOf')} */ +module.exports = $Object.getPrototypeOf || null; diff --git a/node_modules/get-proto/README.md b/node_modules/get-proto/README.md new file mode 100644 index 0000000..f8b4cce --- /dev/null +++ b/node_modules/get-proto/README.md @@ -0,0 +1,50 @@ +# get-proto [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +Robustly get the [[Prototype]] of an object. Uses the best available method. + +## Getting started + +```sh +npm install --save get-proto +``` + +## Usage/Examples + +```js +const assert = require('assert'); +const getProto = require('get-proto'); + +const a = { a: 1, b: 2, [Symbol.toStringTag]: 'foo' }; +const b = { c: 3, __proto__: a }; + +assert.equal(getProto(b), a); +assert.equal(getProto(a), Object.prototype); +assert.equal(getProto({ __proto__: null }), null); +``` + +## Tests + +Clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/get-proto +[npm-version-svg]: https://versionbadg.es/ljharb/get-proto.svg +[deps-svg]: https://david-dm.org/ljharb/get-proto.svg +[deps-url]: https://david-dm.org/ljharb/get-proto +[dev-deps-svg]: https://david-dm.org/ljharb/get-proto/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/get-proto#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/get-proto.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/get-proto.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/get-proto.svg +[downloads-url]: https://npm-stat.com/charts.html?package=get-proto +[codecov-image]: https://codecov.io/gh/ljharb/get-proto/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/get-proto/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/get-proto +[actions-url]: https://github.com/ljharb/get-proto/actions diff --git a/node_modules/get-proto/Reflect.getPrototypeOf.d.ts b/node_modules/get-proto/Reflect.getPrototypeOf.d.ts new file mode 100644 index 0000000..2388fe0 --- /dev/null +++ b/node_modules/get-proto/Reflect.getPrototypeOf.d.ts @@ -0,0 +1,3 @@ +declare const x: typeof Reflect.getPrototypeOf | null; + +export = x; \ No newline at end of file diff --git a/node_modules/get-proto/Reflect.getPrototypeOf.js b/node_modules/get-proto/Reflect.getPrototypeOf.js new file mode 100644 index 0000000..e6c51be --- /dev/null +++ b/node_modules/get-proto/Reflect.getPrototypeOf.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./Reflect.getPrototypeOf')} */ +module.exports = (typeof Reflect !== 'undefined' && Reflect.getPrototypeOf) || null; diff --git a/node_modules/get-proto/index.d.ts b/node_modules/get-proto/index.d.ts new file mode 100644 index 0000000..2c021f3 --- /dev/null +++ b/node_modules/get-proto/index.d.ts @@ -0,0 +1,5 @@ +declare function getProto(object: O): object | null; + +declare const x: typeof getProto | null; + +export = x; diff --git a/node_modules/get-proto/index.js b/node_modules/get-proto/index.js new file mode 100644 index 0000000..7e5747b --- /dev/null +++ b/node_modules/get-proto/index.js @@ -0,0 +1,27 @@ +'use strict'; + +var reflectGetProto = require('./Reflect.getPrototypeOf'); +var originalGetProto = require('./Object.getPrototypeOf'); + +var getDunderProto = require('dunder-proto/get'); + +/** @type {import('.')} */ +module.exports = reflectGetProto + ? function getProto(O) { + // @ts-expect-error TS can't narrow inside a closure, for some reason + return reflectGetProto(O); + } + : originalGetProto + ? function getProto(O) { + if (!O || (typeof O !== 'object' && typeof O !== 'function')) { + throw new TypeError('getProto: not an object'); + } + // @ts-expect-error TS can't narrow inside a closure, for some reason + return originalGetProto(O); + } + : getDunderProto + ? function getProto(O) { + // @ts-expect-error TS can't narrow inside a closure, for some reason + return getDunderProto(O); + } + : null; diff --git a/node_modules/get-proto/package.json b/node_modules/get-proto/package.json new file mode 100644 index 0000000..9c35cec --- /dev/null +++ b/node_modules/get-proto/package.json @@ -0,0 +1,81 @@ +{ + "name": "get-proto", + "version": "1.0.1", + "description": "Robustly get the [[Prototype]] of an object", + "main": "index.js", + "exports": { + ".": "./index.js", + "./Reflect.getPrototypeOf": "./Reflect.getPrototypeOf.js", + "./Object.getPrototypeOf": "./Object.getPrototypeOf.js", + "./package.json": "./package.json" + }, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "pretest": "npm run --silent lint", + "test": "npm run tests-only", + "posttest": "npx npm@\">=10.2\" audit --production", + "tests-only": "nyc tape 'test/**/*.js'", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc && attw -P", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/get-proto.git" + }, + "keywords": [ + "get", + "proto", + "prototype", + "getPrototypeOf", + "[[Prototype]]" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/get-proto/issues" + }, + "homepage": "https://github.com/ljharb/get-proto#readme", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.2", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.3", + "@types/tape": "^5.8.0", + "auto-changelog": "^2.5.0", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "engines": { + "node": ">= 0.4" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "testling": { + "files": "test/index.js" + } +} diff --git a/node_modules/get-proto/test/index.js b/node_modules/get-proto/test/index.js new file mode 100644 index 0000000..5a2ece2 --- /dev/null +++ b/node_modules/get-proto/test/index.js @@ -0,0 +1,68 @@ +'use strict'; + +var test = require('tape'); + +var getProto = require('../'); + +test('getProto', function (t) { + t.equal(typeof getProto, 'function', 'is a function'); + + t.test('can get', { skip: !getProto }, function (st) { + if (getProto) { // TS doesn't understand tape's skip + var proto = { b: 2 }; + st.equal(getProto(proto), Object.prototype, 'proto: returns the [[Prototype]]'); + + st.test('nullish value', function (s2t) { + // @ts-expect-error + s2t['throws'](function () { return getProto(undefined); }, TypeError, 'undefined is not an object'); + // @ts-expect-error + s2t['throws'](function () { return getProto(null); }, TypeError, 'null is not an object'); + s2t.end(); + }); + + // @ts-expect-error + st['throws'](function () { getProto(true); }, 'throws for true'); + // @ts-expect-error + st['throws'](function () { getProto(false); }, 'throws for false'); + // @ts-expect-error + st['throws'](function () { getProto(42); }, 'throws for 42'); + // @ts-expect-error + st['throws'](function () { getProto(NaN); }, 'throws for NaN'); + // @ts-expect-error + st['throws'](function () { getProto(0); }, 'throws for +0'); + // @ts-expect-error + st['throws'](function () { getProto(-0); }, 'throws for -0'); + // @ts-expect-error + st['throws'](function () { getProto(Infinity); }, 'throws for ∞'); + // @ts-expect-error + st['throws'](function () { getProto(-Infinity); }, 'throws for -∞'); + // @ts-expect-error + st['throws'](function () { getProto(''); }, 'throws for empty string'); + // @ts-expect-error + st['throws'](function () { getProto('foo'); }, 'throws for non-empty string'); + st.equal(getProto(/a/g), RegExp.prototype); + st.equal(getProto(new Date()), Date.prototype); + st.equal(getProto(function () {}), Function.prototype); + st.equal(getProto([]), Array.prototype); + st.equal(getProto({}), Object.prototype); + + var nullObject = { __proto__: null }; + if ('toString' in nullObject) { + st.comment('no null objects in this engine'); + st.equal(getProto(nullObject), Object.prototype, '"null" object has Object.prototype as [[Prototype]]'); + } else { + st.equal(getProto(nullObject), null, 'null object has null [[Prototype]]'); + } + } + + st.end(); + }); + + t.test('can not get', { skip: !!getProto }, function (st) { + st.equal(getProto, null); + + st.end(); + }); + + t.end(); +}); diff --git a/node_modules/get-proto/tsconfig.json b/node_modules/get-proto/tsconfig.json new file mode 100644 index 0000000..60fb90e --- /dev/null +++ b/node_modules/get-proto/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + //"target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/gopd/.eslintrc b/node_modules/gopd/.eslintrc new file mode 100644 index 0000000..e2550c0 --- /dev/null +++ b/node_modules/gopd/.eslintrc @@ -0,0 +1,16 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "func-style": [2, "declaration"], + "id-length": 0, + "multiline-comment-style": 0, + "new-cap": [2, { + "capIsNewExceptions": [ + "GetIntrinsic", + ], + }], + }, +} diff --git a/node_modules/gopd/.github/FUNDING.yml b/node_modules/gopd/.github/FUNDING.yml new file mode 100644 index 0000000..94a44a8 --- /dev/null +++ b/node_modules/gopd/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/gopd +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/gopd/CHANGELOG.md b/node_modules/gopd/CHANGELOG.md new file mode 100644 index 0000000..87f5727 --- /dev/null +++ b/node_modules/gopd/CHANGELOG.md @@ -0,0 +1,45 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.2.0](https://github.com/ljharb/gopd/compare/v1.1.0...v1.2.0) - 2024-12-03 + +### Commits + +- [New] add `gOPD` entry point; remove `get-intrinsic` [`5b61232`](https://github.com/ljharb/gopd/commit/5b61232dedea4591a314bcf16101b1961cee024e) + +## [v1.1.0](https://github.com/ljharb/gopd/compare/v1.0.1...v1.1.0) - 2024-11-29 + +### Commits + +- [New] add types [`f585e39`](https://github.com/ljharb/gopd/commit/f585e397886d270e4ba84e53d226e4f9ca2eb0e6) +- [Dev Deps] update `@ljharb/eslint-config`, `auto-changelog`, `tape` [`0b8e4fd`](https://github.com/ljharb/gopd/commit/0b8e4fded64397a7726a9daa144a6cc9a5e2edfa) +- [Dev Deps] update `aud`, `npmignore`, `tape` [`48378b2`](https://github.com/ljharb/gopd/commit/48378b2443f09a4f7efbd0fb6c3ee845a6cabcf3) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`78099ee`](https://github.com/ljharb/gopd/commit/78099eeed41bfdc134c912280483689cc8861c31) +- [Tests] replace `aud` with `npm audit` [`4e0d0ac`](https://github.com/ljharb/gopd/commit/4e0d0ac47619d24a75318a8e1f543ee04b2a2632) +- [meta] add missing `engines.node` [`1443316`](https://github.com/ljharb/gopd/commit/14433165d07835c680155b3dfd62d9217d735eca) +- [Deps] update `get-intrinsic` [`eee5f51`](https://github.com/ljharb/gopd/commit/eee5f51769f3dbaf578b70e2a3199116b01aa670) +- [Deps] update `get-intrinsic` [`550c378`](https://github.com/ljharb/gopd/commit/550c3780e3a9c77b62565712a001b4ed64ea61f5) +- [Dev Deps] add missing peer dep [`8c2ecf8`](https://github.com/ljharb/gopd/commit/8c2ecf848122e4e30abfc5b5086fb48b390dce75) + +## [v1.0.1](https://github.com/ljharb/gopd/compare/v1.0.0...v1.0.1) - 2022-11-01 + +### Commits + +- [Fix] actually export gOPD instead of dP [`4b624bf`](https://github.com/ljharb/gopd/commit/4b624bfbeff788c5e3ff16d9443a83627847234f) + +## v1.0.0 - 2022-11-01 + +### Commits + +- Initial implementation, tests, readme [`0911e01`](https://github.com/ljharb/gopd/commit/0911e012cd642092bd88b732c161c58bf4f20bea) +- Initial commit [`b84e33f`](https://github.com/ljharb/gopd/commit/b84e33f5808a805ac57ff88d4247ad935569acbe) +- [actions] add reusable workflows [`12ae28a`](https://github.com/ljharb/gopd/commit/12ae28ae5f50f86e750215b6e2188901646d0119) +- npm init [`280118b`](https://github.com/ljharb/gopd/commit/280118badb45c80b4483836b5cb5315bddf6e582) +- [meta] add `auto-changelog` [`bb78de5`](https://github.com/ljharb/gopd/commit/bb78de5639a180747fb290c28912beaaf1615709) +- [meta] create FUNDING.yml; add `funding` in package.json [`11c22e6`](https://github.com/ljharb/gopd/commit/11c22e6355bb01f24e7fac4c9bb3055eb5b25002) +- [meta] use `npmignore` to autogenerate an npmignore file [`4f4537a`](https://github.com/ljharb/gopd/commit/4f4537a843b39f698c52f072845092e6fca345bb) +- Only apps should have lockfiles [`c567022`](https://github.com/ljharb/gopd/commit/c567022a18573aa7951cf5399445d9840e23e98b) diff --git a/node_modules/gopd/LICENSE b/node_modules/gopd/LICENSE new file mode 100644 index 0000000..6abfe14 --- /dev/null +++ b/node_modules/gopd/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Jordan Harband + +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. diff --git a/node_modules/gopd/README.md b/node_modules/gopd/README.md new file mode 100644 index 0000000..784e56a --- /dev/null +++ b/node_modules/gopd/README.md @@ -0,0 +1,40 @@ +# gopd [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +`Object.getOwnPropertyDescriptor`, but accounts for IE's broken implementation. + +## Usage + +```javascript +var gOPD = require('gopd'); +var assert = require('assert'); + +if (gOPD) { + assert.equal(typeof gOPD, 'function', 'descriptors supported'); + // use gOPD like Object.getOwnPropertyDescriptor here +} else { + assert.ok(!gOPD, 'descriptors not supported'); +} +``` + +[package-url]: https://npmjs.org/package/gopd +[npm-version-svg]: https://versionbadg.es/ljharb/gopd.svg +[deps-svg]: https://david-dm.org/ljharb/gopd.svg +[deps-url]: https://david-dm.org/ljharb/gopd +[dev-deps-svg]: https://david-dm.org/ljharb/gopd/dev-status.svg +[dev-deps-url]: https://david-dm.org/ljharb/gopd#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/gopd.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/gopd.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/gopd.svg +[downloads-url]: https://npm-stat.com/charts.html?package=gopd +[codecov-image]: https://codecov.io/gh/ljharb/gopd/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/ljharb/gopd/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/gopd +[actions-url]: https://github.com/ljharb/gopd/actions diff --git a/node_modules/gopd/gOPD.d.ts b/node_modules/gopd/gOPD.d.ts new file mode 100644 index 0000000..def48a3 --- /dev/null +++ b/node_modules/gopd/gOPD.d.ts @@ -0,0 +1 @@ +export = Object.getOwnPropertyDescriptor; diff --git a/node_modules/gopd/gOPD.js b/node_modules/gopd/gOPD.js new file mode 100644 index 0000000..cf9616c --- /dev/null +++ b/node_modules/gopd/gOPD.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./gOPD')} */ +module.exports = Object.getOwnPropertyDescriptor; diff --git a/node_modules/gopd/index.d.ts b/node_modules/gopd/index.d.ts new file mode 100644 index 0000000..e228065 --- /dev/null +++ b/node_modules/gopd/index.d.ts @@ -0,0 +1,5 @@ +declare function gOPD(obj: O, prop: K): PropertyDescriptor | undefined; + +declare const fn: typeof gOPD | undefined | null; + +export = fn; \ No newline at end of file diff --git a/node_modules/gopd/index.js b/node_modules/gopd/index.js new file mode 100644 index 0000000..a4081b0 --- /dev/null +++ b/node_modules/gopd/index.js @@ -0,0 +1,15 @@ +'use strict'; + +/** @type {import('.')} */ +var $gOPD = require('./gOPD'); + +if ($gOPD) { + try { + $gOPD([], 'length'); + } catch (e) { + // IE 8 has a broken gOPD + $gOPD = null; + } +} + +module.exports = $gOPD; diff --git a/node_modules/gopd/package.json b/node_modules/gopd/package.json new file mode 100644 index 0000000..01c5ffa --- /dev/null +++ b/node_modules/gopd/package.json @@ -0,0 +1,77 @@ +{ + "name": "gopd", + "version": "1.2.0", + "description": "`Object.getOwnPropertyDescriptor`, but accounts for IE's broken implementation.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./gOPD": "./gOPD.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prelint": "tsc -p . && attw -P", + "lint": "eslint --ext=js,mjs .", + "postlint": "evalmd README.md", + "pretest": "npm run lint", + "tests-only": "tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/ljharb/gopd.git" + }, + "keywords": [ + "ecmascript", + "javascript", + "getownpropertydescriptor", + "property", + "descriptor" + ], + "author": "Jordan Harband ", + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/gopd/issues" + }, + "homepage": "https://github.com/ljharb/gopd#readme", + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.0", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.0", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/gopd/test/index.js b/node_modules/gopd/test/index.js new file mode 100644 index 0000000..6f43453 --- /dev/null +++ b/node_modules/gopd/test/index.js @@ -0,0 +1,36 @@ +'use strict'; + +var test = require('tape'); +var gOPD = require('../'); + +test('gOPD', function (t) { + t.test('supported', { skip: !gOPD }, function (st) { + st.equal(typeof gOPD, 'function', 'is a function'); + + var obj = { x: 1 }; + st.ok('x' in obj, 'property exists'); + + // @ts-expect-error TS can't figure out narrowing from `skip` + var desc = gOPD(obj, 'x'); + st.deepEqual( + desc, + { + configurable: true, + enumerable: true, + value: 1, + writable: true + }, + 'descriptor is as expected' + ); + + st.end(); + }); + + t.test('not supported', { skip: !!gOPD }, function (st) { + st.notOk(gOPD, 'is falsy'); + + st.end(); + }); + + t.end(); +}); diff --git a/node_modules/gopd/tsconfig.json b/node_modules/gopd/tsconfig.json new file mode 100644 index 0000000..d9a6668 --- /dev/null +++ b/node_modules/gopd/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "es2021", + }, + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/has-symbols/.eslintrc b/node_modules/has-symbols/.eslintrc new file mode 100644 index 0000000..2d9a66a --- /dev/null +++ b/node_modules/has-symbols/.eslintrc @@ -0,0 +1,11 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "max-statements-per-line": [2, { "max": 2 }], + "no-magic-numbers": 0, + "multiline-comment-style": 0, + } +} diff --git a/node_modules/has-symbols/.github/FUNDING.yml b/node_modules/has-symbols/.github/FUNDING.yml new file mode 100644 index 0000000..04cf87e --- /dev/null +++ b/node_modules/has-symbols/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/has-symbols +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/has-symbols/.nycrc b/node_modules/has-symbols/.nycrc new file mode 100644 index 0000000..bdd626c --- /dev/null +++ b/node_modules/has-symbols/.nycrc @@ -0,0 +1,9 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/has-symbols/CHANGELOG.md b/node_modules/has-symbols/CHANGELOG.md new file mode 100644 index 0000000..cc3cf83 --- /dev/null +++ b/node_modules/has-symbols/CHANGELOG.md @@ -0,0 +1,91 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.1.0](https://github.com/inspect-js/has-symbols/compare/v1.0.3...v1.1.0) - 2024-12-02 + +### Commits + +- [actions] update workflows [`548c0bf`](https://github.com/inspect-js/has-symbols/commit/548c0bf8c9b1235458df7a1c0490b0064647a282) +- [actions] further shard; update action deps [`bec56bb`](https://github.com/inspect-js/has-symbols/commit/bec56bb0fb44b43a786686b944875a3175cf3ff3) +- [meta] use `npmignore` to autogenerate an npmignore file [`ac81032`](https://github.com/inspect-js/has-symbols/commit/ac81032809157e0a079e5264e9ce9b6f1275777e) +- [New] add types [`6469cbf`](https://github.com/inspect-js/has-symbols/commit/6469cbff1866cfe367b2b3d181d9296ec14b2a3d) +- [actions] update rebase action to use reusable workflow [`9c9d4d0`](https://github.com/inspect-js/has-symbols/commit/9c9d4d0d8938e4b267acdf8e421f4e92d1716d72) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`adb5887`](https://github.com/inspect-js/has-symbols/commit/adb5887ca9444849b08beb5caaa9e1d42320cdfb) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`13ec198`](https://github.com/inspect-js/has-symbols/commit/13ec198ec80f1993a87710af1606a1970b22c7cb) +- [Dev Deps] update `auto-changelog`, `core-js`, `tape` [`941be52`](https://github.com/inspect-js/has-symbols/commit/941be5248387cab1da72509b22acf3fdb223f057) +- [Tests] replace `aud` with `npm audit` [`74f49e9`](https://github.com/inspect-js/has-symbols/commit/74f49e9a9d17a443020784234a1c53ce765b3559) +- [Dev Deps] update `npmignore` [`9c0ac04`](https://github.com/inspect-js/has-symbols/commit/9c0ac0452a834f4c2a4b54044f2d6a89f17e9a70) +- [Dev Deps] add missing peer dep [`52337a5`](https://github.com/inspect-js/has-symbols/commit/52337a5621cced61f846f2afdab7707a8132cc12) + +## [v1.0.3](https://github.com/inspect-js/has-symbols/compare/v1.0.2...v1.0.3) - 2022-03-01 + +### Commits + +- [actions] use `node/install` instead of `node/run`; use `codecov` action [`518b28f`](https://github.com/inspect-js/has-symbols/commit/518b28f6c5a516cbccae30794e40aa9f738b1693) +- [meta] add `bugs` and `homepage` fields; reorder package.json [`c480b13`](https://github.com/inspect-js/has-symbols/commit/c480b13fd6802b557e1cef9749872cb5fdeef744) +- [actions] reuse common workflows [`01d0ee0`](https://github.com/inspect-js/has-symbols/commit/01d0ee0a8d97c0947f5edb73eb722027a77b2b07) +- [actions] update codecov uploader [`6424ebe`](https://github.com/inspect-js/has-symbols/commit/6424ebe86b2c9c7c3d2e9bd4413a4e4f168cb275) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`dfa7e7f`](https://github.com/inspect-js/has-symbols/commit/dfa7e7ff38b594645d8c8222aab895157fa7e282) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `tape` [`0c8d436`](https://github.com/inspect-js/has-symbols/commit/0c8d43685c45189cea9018191d4fd7eca91c9d02) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`9026554`](https://github.com/inspect-js/has-symbols/commit/902655442a1bf88e72b42345494ef0c60f5d36ab) +- [readme] add actions and codecov badges [`eaa9682`](https://github.com/inspect-js/has-symbols/commit/eaa9682f990f481d3acf7a1c7600bec36f7b3adc) +- [Dev Deps] update `eslint`, `tape` [`bc7a3ba`](https://github.com/inspect-js/has-symbols/commit/bc7a3ba46f27b7743f8a2579732d59d1b9ac791e) +- [Dev Deps] update `eslint`, `auto-changelog` [`0ace00a`](https://github.com/inspect-js/has-symbols/commit/0ace00af08a88cdd1e6ce0d60357d941c60c2d9f) +- [meta] use `prepublishOnly` script for npm 7+ [`093f72b`](https://github.com/inspect-js/has-symbols/commit/093f72bc2b0ed00c781f444922a5034257bf561d) +- [Tests] test on all 16 minors [`9b80d3d`](https://github.com/inspect-js/has-symbols/commit/9b80d3d9102529f04c20ec5b1fcc6e38426c6b03) + +## [v1.0.2](https://github.com/inspect-js/has-symbols/compare/v1.0.1...v1.0.2) - 2021-02-27 + +### Fixed + +- [Fix] use a universal way to get the original Symbol [`#11`](https://github.com/inspect-js/has-symbols/issues/11) + +### Commits + +- [Tests] migrate tests to Github Actions [`90ae798`](https://github.com/inspect-js/has-symbols/commit/90ae79820bdfe7bc703d67f5f3c5e205f98556d3) +- [meta] do not publish github action workflow files [`29e60a1`](https://github.com/inspect-js/has-symbols/commit/29e60a1b7c25c7f1acf7acff4a9320d0d10c49b4) +- [Tests] run `nyc` on all tests [`8476b91`](https://github.com/inspect-js/has-symbols/commit/8476b915650d360915abe2522505abf4b0e8f0ae) +- [readme] fix repo URLs, remove defunct badges [`126288e`](https://github.com/inspect-js/has-symbols/commit/126288ecc1797c0a40247a6b78bcb2e0bc5d7036) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `core-js`, `get-own-property-symbols` [`d84bdfa`](https://github.com/inspect-js/has-symbols/commit/d84bdfa48ac5188abbb4904b42614cd6c030940a) +- [Tests] fix linting errors [`0df3070`](https://github.com/inspect-js/has-symbols/commit/0df3070b981b6c9f2ee530c09189a7f5c6def839) +- [actions] add "Allow Edits" workflow [`1e6bc29`](https://github.com/inspect-js/has-symbols/commit/1e6bc29b188f32b9648657b07eda08504be5aa9c) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`36cea2a`](https://github.com/inspect-js/has-symbols/commit/36cea2addd4e6ec435f35a2656b4e9ef82498e9b) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`1278338`](https://github.com/inspect-js/has-symbols/commit/127833801865fbc2cc8979beb9ca869c7bfe8222) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`1493254`](https://github.com/inspect-js/has-symbols/commit/1493254eda13db5fb8fc5e4a3e8324b3d196029d) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `core-js` [`b090bf2`](https://github.com/inspect-js/has-symbols/commit/b090bf214d3679a30edc1e2d729d466ab5183e1d) +- [actions] switch Automatic Rebase workflow to `pull_request_target` event [`4addb7a`](https://github.com/inspect-js/has-symbols/commit/4addb7ab4dc73f927ae99928d68817554fc21dc0) +- [Dev Deps] update `auto-changelog`, `tape` [`81d0baf`](https://github.com/inspect-js/has-symbols/commit/81d0baf3816096a89a8558e8043895f7a7d10d8b) +- [Dev Deps] update `auto-changelog`; add `aud` [`1a4e561`](https://github.com/inspect-js/has-symbols/commit/1a4e5612c25d91c3a03d509721d02630bc4fe3da) +- [readme] remove unused testling URLs [`3000941`](https://github.com/inspect-js/has-symbols/commit/3000941f958046e923ed8152edb1ef4a599e6fcc) +- [Tests] only audit prod deps [`692e974`](https://github.com/inspect-js/has-symbols/commit/692e9743c912410e9440207631a643a34b4741a1) +- [Dev Deps] update `@ljharb/eslint-config` [`51c946c`](https://github.com/inspect-js/has-symbols/commit/51c946c7f6baa793ec5390bb5a45cdce16b4ba76) + +## [v1.0.1](https://github.com/inspect-js/has-symbols/compare/v1.0.0...v1.0.1) - 2019-11-16 + +### Commits + +- [Tests] use shared travis-ci configs [`ce396c9`](https://github.com/inspect-js/has-symbols/commit/ce396c9419ff11c43d0da5d05cdbb79f7fb42229) +- [Tests] up to `node` `v12.4`, `v11.15`, `v10.15`, `v9.11`, `v8.15`, `v7.10`, `v6.17`, `v4.9`; use `nvm install-latest-npm` [`0690732`](https://github.com/inspect-js/has-symbols/commit/0690732801f47ab429f39ba1962f522d5c462d6b) +- [meta] add `auto-changelog` [`2163d0b`](https://github.com/inspect-js/has-symbols/commit/2163d0b7f36343076b8f947cd1667dd1750f26fc) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `core-js`, `safe-publish-latest`, `tape` [`8e0951f`](https://github.com/inspect-js/has-symbols/commit/8e0951f1a7a2e52068222b7bb73511761e6e4d9c) +- [actions] add automatic rebasing / merge commit blocking [`b09cdb7`](https://github.com/inspect-js/has-symbols/commit/b09cdb7cd7ee39e7a769878f56e2d6066f5ccd1d) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `core-js`, `get-own-property-symbols`, `tape` [`1dd42cd`](https://github.com/inspect-js/has-symbols/commit/1dd42cd86183ed0c50f99b1062345c458babca91) +- [meta] create FUNDING.yml [`aa57a17`](https://github.com/inspect-js/has-symbols/commit/aa57a17b19708906d1927f821ea8e73394d84ca4) +- Only apps should have lockfiles [`a2d8bea`](https://github.com/inspect-js/has-symbols/commit/a2d8bea23a97d15c09eaf60f5b107fcf9a4d57aa) +- [Tests] use `npx aud` instead of `nsp` or `npm audit` with hoops [`9e96cb7`](https://github.com/inspect-js/has-symbols/commit/9e96cb783746cbed0c10ef78e599a8eaa7ebe193) +- [meta] add `funding` field [`a0b32cf`](https://github.com/inspect-js/has-symbols/commit/a0b32cf68e803f963c1639b6d47b0a9d6440bab0) +- [Dev Deps] update `safe-publish-latest` [`cb9f0a5`](https://github.com/inspect-js/has-symbols/commit/cb9f0a521a3a1790f1064d437edd33bb6c3d6af0) + +## v1.0.0 - 2016-09-19 + +### Commits + +- Tests. [`ecb6eb9`](https://github.com/inspect-js/has-symbols/commit/ecb6eb934e4883137f3f93b965ba5e0a98df430d) +- package.json [`88a337c`](https://github.com/inspect-js/has-symbols/commit/88a337cee0864a0da35f5d19e69ff0ef0150e46a) +- Initial commit [`42e1e55`](https://github.com/inspect-js/has-symbols/commit/42e1e5502536a2b8ac529c9443984acd14836b1c) +- Initial implementation. [`33f5cc6`](https://github.com/inspect-js/has-symbols/commit/33f5cc6cdff86e2194b081ee842bfdc63caf43fb) +- read me [`01f1170`](https://github.com/inspect-js/has-symbols/commit/01f1170188ff7cb1558aa297f6ba5b516c6d7b0c) diff --git a/node_modules/has-symbols/LICENSE b/node_modules/has-symbols/LICENSE new file mode 100644 index 0000000..df31cbf --- /dev/null +++ b/node_modules/has-symbols/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Jordan Harband + +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. diff --git a/node_modules/has-symbols/README.md b/node_modules/has-symbols/README.md new file mode 100644 index 0000000..33905f0 --- /dev/null +++ b/node_modules/has-symbols/README.md @@ -0,0 +1,46 @@ +# has-symbols [![Version Badge][2]][1] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![dependency status][5]][6] +[![dev dependency status][7]][8] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][11]][1] + +Determine if the JS environment has Symbol support. Supports spec, or shams. + +## Example + +```js +var hasSymbols = require('has-symbols'); + +hasSymbols() === true; // if the environment has native Symbol support. Not polyfillable, not forgeable. + +var hasSymbolsKinda = require('has-symbols/shams'); +hasSymbolsKinda() === true; // if the environment has a Symbol sham that mostly follows the spec. +``` + +## Supported Symbol shams + - get-own-property-symbols [npm](https://www.npmjs.com/package/get-own-property-symbols) | [github](https://github.com/WebReflection/get-own-property-symbols) + - core-js [npm](https://www.npmjs.com/package/core-js) | [github](https://github.com/zloirock/core-js) + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +[1]: https://npmjs.org/package/has-symbols +[2]: https://versionbadg.es/inspect-js/has-symbols.svg +[5]: https://david-dm.org/inspect-js/has-symbols.svg +[6]: https://david-dm.org/inspect-js/has-symbols +[7]: https://david-dm.org/inspect-js/has-symbols/dev-status.svg +[8]: https://david-dm.org/inspect-js/has-symbols#info=devDependencies +[11]: https://nodei.co/npm/has-symbols.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/has-symbols.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/has-symbols.svg +[downloads-url]: https://npm-stat.com/charts.html?package=has-symbols +[codecov-image]: https://codecov.io/gh/inspect-js/has-symbols/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/inspect-js/has-symbols/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/has-symbols +[actions-url]: https://github.com/inspect-js/has-symbols/actions diff --git a/node_modules/has-symbols/index.d.ts b/node_modules/has-symbols/index.d.ts new file mode 100644 index 0000000..9b98595 --- /dev/null +++ b/node_modules/has-symbols/index.d.ts @@ -0,0 +1,3 @@ +declare function hasNativeSymbols(): boolean; + +export = hasNativeSymbols; \ No newline at end of file diff --git a/node_modules/has-symbols/index.js b/node_modules/has-symbols/index.js new file mode 100644 index 0000000..fa65265 --- /dev/null +++ b/node_modules/has-symbols/index.js @@ -0,0 +1,14 @@ +'use strict'; + +var origSymbol = typeof Symbol !== 'undefined' && Symbol; +var hasSymbolSham = require('./shams'); + +/** @type {import('.')} */ +module.exports = function hasNativeSymbols() { + if (typeof origSymbol !== 'function') { return false; } + if (typeof Symbol !== 'function') { return false; } + if (typeof origSymbol('foo') !== 'symbol') { return false; } + if (typeof Symbol('bar') !== 'symbol') { return false; } + + return hasSymbolSham(); +}; diff --git a/node_modules/has-symbols/package.json b/node_modules/has-symbols/package.json new file mode 100644 index 0000000..d835e20 --- /dev/null +++ b/node_modules/has-symbols/package.json @@ -0,0 +1,111 @@ +{ + "name": "has-symbols", + "version": "1.1.0", + "description": "Determine if the JS environment has Symbol support. Supports spec, or shams.", + "main": "index.js", + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run --silent lint", + "test": "npm run tests-only", + "posttest": "npx npm@'>=10.2' audit --production", + "tests-only": "npm run test:stock && npm run test:shams", + "test:stock": "nyc node test", + "test:staging": "nyc node --harmony --es-staging test", + "test:shams": "npm run --silent test:shams:getownpropertysymbols && npm run --silent test:shams:corejs", + "test:shams:corejs": "nyc node test/shams/core-js.js", + "test:shams:getownpropertysymbols": "nyc node test/shams/get-own-property-symbols.js", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc -p . && attw -P", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git://github.com/inspect-js/has-symbols.git" + }, + "keywords": [ + "Symbol", + "symbols", + "typeof", + "sham", + "polyfill", + "native", + "core-js", + "ES6" + ], + "author": { + "name": "Jordan Harband", + "email": "ljharb@gmail.com", + "url": "http://ljharb.codes" + }, + "contributors": [ + { + "name": "Jordan Harband", + "email": "ljharb@gmail.com", + "url": "http://ljharb.codes" + } + ], + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/ljharb/has-symbols/issues" + }, + "homepage": "https://github.com/ljharb/has-symbols#readme", + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.0", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.0", + "@types/core-js": "^2.5.8", + "@types/tape": "^5.6.5", + "auto-changelog": "^2.5.0", + "core-js": "^2.6.12", + "encoding": "^0.1.13", + "eslint": "=8.8.0", + "get-own-property-symbols": "^0.9.5", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "testling": { + "files": "test/index.js", + "browsers": [ + "iexplore/6.0..latest", + "firefox/3.0..6.0", + "firefox/15.0..latest", + "firefox/nightly", + "chrome/4.0..10.0", + "chrome/20.0..latest", + "chrome/canary", + "opera/10.0..latest", + "opera/next", + "safari/4.0..latest", + "ipad/6.0..latest", + "iphone/6.0..latest", + "android-browser/4.2" + ] + }, + "engines": { + "node": ">= 0.4" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows", + "types" + ] + } +} diff --git a/node_modules/has-symbols/shams.d.ts b/node_modules/has-symbols/shams.d.ts new file mode 100644 index 0000000..8d0bf24 --- /dev/null +++ b/node_modules/has-symbols/shams.d.ts @@ -0,0 +1,3 @@ +declare function hasSymbolShams(): boolean; + +export = hasSymbolShams; \ No newline at end of file diff --git a/node_modules/has-symbols/shams.js b/node_modules/has-symbols/shams.js new file mode 100644 index 0000000..f97b474 --- /dev/null +++ b/node_modules/has-symbols/shams.js @@ -0,0 +1,45 @@ +'use strict'; + +/** @type {import('./shams')} */ +/* eslint complexity: [2, 18], max-statements: [2, 33] */ +module.exports = function hasSymbols() { + if (typeof Symbol !== 'function' || typeof Object.getOwnPropertySymbols !== 'function') { return false; } + if (typeof Symbol.iterator === 'symbol') { return true; } + + /** @type {{ [k in symbol]?: unknown }} */ + var obj = {}; + var sym = Symbol('test'); + var symObj = Object(sym); + if (typeof sym === 'string') { return false; } + + if (Object.prototype.toString.call(sym) !== '[object Symbol]') { return false; } + if (Object.prototype.toString.call(symObj) !== '[object Symbol]') { return false; } + + // temp disabled per https://github.com/ljharb/object.assign/issues/17 + // if (sym instanceof Symbol) { return false; } + // temp disabled per https://github.com/WebReflection/get-own-property-symbols/issues/4 + // if (!(symObj instanceof Symbol)) { return false; } + + // if (typeof Symbol.prototype.toString !== 'function') { return false; } + // if (String(sym) !== Symbol.prototype.toString.call(sym)) { return false; } + + var symVal = 42; + obj[sym] = symVal; + for (var _ in obj) { return false; } // eslint-disable-line no-restricted-syntax, no-unreachable-loop + if (typeof Object.keys === 'function' && Object.keys(obj).length !== 0) { return false; } + + if (typeof Object.getOwnPropertyNames === 'function' && Object.getOwnPropertyNames(obj).length !== 0) { return false; } + + var syms = Object.getOwnPropertySymbols(obj); + if (syms.length !== 1 || syms[0] !== sym) { return false; } + + if (!Object.prototype.propertyIsEnumerable.call(obj, sym)) { return false; } + + if (typeof Object.getOwnPropertyDescriptor === 'function') { + // eslint-disable-next-line no-extra-parens + var descriptor = /** @type {PropertyDescriptor} */ (Object.getOwnPropertyDescriptor(obj, sym)); + if (descriptor.value !== symVal || descriptor.enumerable !== true) { return false; } + } + + return true; +}; diff --git a/node_modules/has-symbols/test/index.js b/node_modules/has-symbols/test/index.js new file mode 100644 index 0000000..352129c --- /dev/null +++ b/node_modules/has-symbols/test/index.js @@ -0,0 +1,22 @@ +'use strict'; + +var test = require('tape'); +var hasSymbols = require('../'); +var runSymbolTests = require('./tests'); + +test('interface', function (t) { + t.equal(typeof hasSymbols, 'function', 'is a function'); + t.equal(typeof hasSymbols(), 'boolean', 'returns a boolean'); + t.end(); +}); + +test('Symbols are supported', { skip: !hasSymbols() }, function (t) { + runSymbolTests(t); + t.end(); +}); + +test('Symbols are not supported', { skip: hasSymbols() }, function (t) { + t.equal(typeof Symbol, 'undefined', 'global Symbol is undefined'); + t.equal(typeof Object.getOwnPropertySymbols, 'undefined', 'Object.getOwnPropertySymbols does not exist'); + t.end(); +}); diff --git a/node_modules/has-symbols/test/shams/core-js.js b/node_modules/has-symbols/test/shams/core-js.js new file mode 100644 index 0000000..1a29024 --- /dev/null +++ b/node_modules/has-symbols/test/shams/core-js.js @@ -0,0 +1,29 @@ +'use strict'; + +var test = require('tape'); + +if (typeof Symbol === 'function' && typeof Symbol() === 'symbol') { + test('has native Symbol support', function (t) { + t.equal(typeof Symbol, 'function'); + t.equal(typeof Symbol(), 'symbol'); + t.end(); + }); + // @ts-expect-error TS is stupid and doesn't know about top level return + return; +} + +var hasSymbols = require('../../shams'); + +test('polyfilled Symbols', function (t) { + /* eslint-disable global-require */ + t.equal(hasSymbols(), false, 'hasSymbols is false before polyfilling'); + require('core-js/fn/symbol'); + require('core-js/fn/symbol/to-string-tag'); + + require('../tests')(t); + + var hasSymbolsAfter = hasSymbols(); + t.equal(hasSymbolsAfter, true, 'hasSymbols is true after polyfilling'); + /* eslint-enable global-require */ + t.end(); +}); diff --git a/node_modules/has-symbols/test/shams/get-own-property-symbols.js b/node_modules/has-symbols/test/shams/get-own-property-symbols.js new file mode 100644 index 0000000..e0296f8 --- /dev/null +++ b/node_modules/has-symbols/test/shams/get-own-property-symbols.js @@ -0,0 +1,29 @@ +'use strict'; + +var test = require('tape'); + +if (typeof Symbol === 'function' && typeof Symbol() === 'symbol') { + test('has native Symbol support', function (t) { + t.equal(typeof Symbol, 'function'); + t.equal(typeof Symbol(), 'symbol'); + t.end(); + }); + // @ts-expect-error TS is stupid and doesn't know about top level return + return; +} + +var hasSymbols = require('../../shams'); + +test('polyfilled Symbols', function (t) { + /* eslint-disable global-require */ + t.equal(hasSymbols(), false, 'hasSymbols is false before polyfilling'); + + require('get-own-property-symbols'); + + require('../tests')(t); + + var hasSymbolsAfter = hasSymbols(); + t.equal(hasSymbolsAfter, true, 'hasSymbols is true after polyfilling'); + /* eslint-enable global-require */ + t.end(); +}); diff --git a/node_modules/has-symbols/test/tests.js b/node_modules/has-symbols/test/tests.js new file mode 100644 index 0000000..66a2cb8 --- /dev/null +++ b/node_modules/has-symbols/test/tests.js @@ -0,0 +1,58 @@ +'use strict'; + +/** @type {(t: import('tape').Test) => false | void} */ +// eslint-disable-next-line consistent-return +module.exports = function runSymbolTests(t) { + t.equal(typeof Symbol, 'function', 'global Symbol is a function'); + + if (typeof Symbol !== 'function') { return false; } + + t.notEqual(Symbol(), Symbol(), 'two symbols are not equal'); + + /* + t.equal( + Symbol.prototype.toString.call(Symbol('foo')), + Symbol.prototype.toString.call(Symbol('foo')), + 'two symbols with the same description stringify the same' + ); + */ + + /* + var foo = Symbol('foo'); + + t.notEqual( + String(foo), + String(Symbol('bar')), + 'two symbols with different descriptions do not stringify the same' + ); + */ + + t.equal(typeof Symbol.prototype.toString, 'function', 'Symbol#toString is a function'); + // t.equal(String(foo), Symbol.prototype.toString.call(foo), 'Symbol#toString equals String of the same symbol'); + + t.equal(typeof Object.getOwnPropertySymbols, 'function', 'Object.getOwnPropertySymbols is a function'); + + /** @type {{ [k in symbol]?: unknown }} */ + var obj = {}; + var sym = Symbol('test'); + var symObj = Object(sym); + t.notEqual(typeof sym, 'string', 'Symbol is not a string'); + t.equal(Object.prototype.toString.call(sym), '[object Symbol]', 'symbol primitive Object#toStrings properly'); + t.equal(Object.prototype.toString.call(symObj), '[object Symbol]', 'symbol primitive Object#toStrings properly'); + + var symVal = 42; + obj[sym] = symVal; + // eslint-disable-next-line no-restricted-syntax, no-unused-vars + for (var _ in obj) { t.fail('symbol property key was found in for..in of object'); } + + t.deepEqual(Object.keys(obj), [], 'no enumerable own keys on symbol-valued object'); + t.deepEqual(Object.getOwnPropertyNames(obj), [], 'no own names on symbol-valued object'); + t.deepEqual(Object.getOwnPropertySymbols(obj), [sym], 'one own symbol on symbol-valued object'); + t.equal(Object.prototype.propertyIsEnumerable.call(obj, sym), true, 'symbol is enumerable'); + t.deepEqual(Object.getOwnPropertyDescriptor(obj, sym), { + configurable: true, + enumerable: true, + value: 42, + writable: true + }, 'property descriptor is correct'); +}; diff --git a/node_modules/has-symbols/tsconfig.json b/node_modules/has-symbols/tsconfig.json new file mode 100644 index 0000000..ba99af4 --- /dev/null +++ b/node_modules/has-symbols/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@ljharb/tsconfig", + "compilerOptions": { + "target": "ES2021", + "maxNodeModuleJsDepth": 0, + }, + "exclude": [ + "coverage" + ] +} diff --git a/node_modules/has-tostringtag/.eslintrc b/node_modules/has-tostringtag/.eslintrc new file mode 100644 index 0000000..3b5d9e9 --- /dev/null +++ b/node_modules/has-tostringtag/.eslintrc @@ -0,0 +1,5 @@ +{ + "root": true, + + "extends": "@ljharb", +} diff --git a/node_modules/has-tostringtag/.github/FUNDING.yml b/node_modules/has-tostringtag/.github/FUNDING.yml new file mode 100644 index 0000000..7a450e7 --- /dev/null +++ b/node_modules/has-tostringtag/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/has-tostringtag +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/node_modules/has-tostringtag/.nycrc b/node_modules/has-tostringtag/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/has-tostringtag/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/has-tostringtag/CHANGELOG.md b/node_modules/has-tostringtag/CHANGELOG.md new file mode 100644 index 0000000..eb186ec --- /dev/null +++ b/node_modules/has-tostringtag/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.0.2](https://github.com/inspect-js/has-tostringtag/compare/v1.0.1...v1.0.2) - 2024-02-01 + +### Fixed + +- [Fix] move `has-symbols` back to prod deps [`#3`](https://github.com/inspect-js/has-tostringtag/issues/3) + +## [v1.0.1](https://github.com/inspect-js/has-tostringtag/compare/v1.0.0...v1.0.1) - 2024-02-01 + +### Commits + +- [patch] add types [`9276414`](https://github.com/inspect-js/has-tostringtag/commit/9276414b22fab3eeb234688841722c4be113201f) +- [meta] use `npmignore` to autogenerate an npmignore file [`5c0dcd1`](https://github.com/inspect-js/has-tostringtag/commit/5c0dcd1ff66419562a30d1fd88b966cc36bce5fc) +- [actions] reuse common workflows [`dee9509`](https://github.com/inspect-js/has-tostringtag/commit/dee950904ab5719b62cf8d73d2ac950b09093266) +- [actions] update codecov uploader [`b8cb3a0`](https://github.com/inspect-js/has-tostringtag/commit/b8cb3a0b8ffbb1593012c4c2daa45fb25642825d) +- [Tests] generate coverage [`be5b288`](https://github.com/inspect-js/has-tostringtag/commit/be5b28889e2735cdbcef387f84c2829995f2f05e) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `tape` [`69a0827`](https://github.com/inspect-js/has-tostringtag/commit/69a0827974e9b877b2c75b70b057555da8f25a65) +- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`4c9e210`](https://github.com/inspect-js/has-tostringtag/commit/4c9e210a5682f0557a3235d36b68ce809d7fb825) +- [actions] update rebase action to use reusable workflow [`ca8dcd3`](https://github.com/inspect-js/has-tostringtag/commit/ca8dcd3a6f3f5805d7e3fd461b654aedba0946e7) +- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `npmignore`, `tape` [`07f3eaf`](https://github.com/inspect-js/has-tostringtag/commit/07f3eafa45dd98208c94479737da77f9a69b94c4) +- [Deps] update `has-symbols` [`999e009`](https://github.com/inspect-js/has-tostringtag/commit/999e0095a7d1749a58f55472ec8bf8108cdfdcf3) +- [Tests] remove staging tests since they fail on modern node [`9d9526b`](https://github.com/inspect-js/has-tostringtag/commit/9d9526b1dc1ca7f2292b52efda4c3d857b0e39bd) + +## v1.0.0 - 2021-08-05 + +### Commits + +- Tests [`6b6f573`](https://github.com/inspect-js/has-tostringtag/commit/6b6f5734dc2058badb300ff0783efdad95fe1a65) +- Initial commit [`2f8190e`](https://github.com/inspect-js/has-tostringtag/commit/2f8190e799fac32ba9b95a076c0255e01d7ce475) +- [meta] do not publish github action workflow files [`6e08cc4`](https://github.com/inspect-js/has-tostringtag/commit/6e08cc4e0fea7ec71ef66e70734b2af2c4a8b71b) +- readme [`94bed6c`](https://github.com/inspect-js/has-tostringtag/commit/94bed6c9560cbbfda034f8d6c260bb7b0db33c1a) +- npm init [`be67840`](https://github.com/inspect-js/has-tostringtag/commit/be67840ab92ee7adb98bcc65261975543f815fa5) +- Implementation [`c4914ec`](https://github.com/inspect-js/has-tostringtag/commit/c4914ecc51ddee692c85b471ae0a5d8123030fbf) +- [meta] use `auto-changelog` [`4aaf768`](https://github.com/inspect-js/has-tostringtag/commit/4aaf76895ae01d7b739f2b19f967ef2372506cd7) +- Only apps should have lockfiles [`bc4d99e`](https://github.com/inspect-js/has-tostringtag/commit/bc4d99e4bf494afbaa235c5f098df6e642edf724) +- [meta] add `safe-publish-latest` [`6523c05`](https://github.com/inspect-js/has-tostringtag/commit/6523c05c9b87140f3ae74c9daf91633dd9ff4e1f) diff --git a/node_modules/has-tostringtag/LICENSE b/node_modules/has-tostringtag/LICENSE new file mode 100644 index 0000000..7948bc0 --- /dev/null +++ b/node_modules/has-tostringtag/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Inspect JS + +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. diff --git a/node_modules/has-tostringtag/README.md b/node_modules/has-tostringtag/README.md new file mode 100644 index 0000000..67a5e92 --- /dev/null +++ b/node_modules/has-tostringtag/README.md @@ -0,0 +1,46 @@ +# has-tostringtag [![Version Badge][2]][1] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![dependency status][5]][6] +[![dev dependency status][7]][8] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][11]][1] + +Determine if the JS environment has `Symbol.toStringTag` support. Supports spec, or shams. + +## Example + +```js +var hasSymbolToStringTag = require('has-tostringtag'); + +hasSymbolToStringTag() === true; // if the environment has native Symbol.toStringTag support. Not polyfillable, not forgeable. + +var hasSymbolToStringTagKinda = require('has-tostringtag/shams'); +hasSymbolToStringTagKinda() === true; // if the environment has a Symbol.toStringTag sham that mostly follows the spec. +``` + +## Supported Symbol shams + - get-own-property-symbols [npm](https://www.npmjs.com/package/get-own-property-symbols) | [github](https://github.com/WebReflection/get-own-property-symbols) + - core-js [npm](https://www.npmjs.com/package/core-js) | [github](https://github.com/zloirock/core-js) + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +[1]: https://npmjs.org/package/has-tostringtag +[2]: https://versionbadg.es/inspect-js/has-tostringtag.svg +[5]: https://david-dm.org/inspect-js/has-tostringtag.svg +[6]: https://david-dm.org/inspect-js/has-tostringtag +[7]: https://david-dm.org/inspect-js/has-tostringtag/dev-status.svg +[8]: https://david-dm.org/inspect-js/has-tostringtag#info=devDependencies +[11]: https://nodei.co/npm/has-tostringtag.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/has-tostringtag.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/has-tostringtag.svg +[downloads-url]: https://npm-stat.com/charts.html?package=has-tostringtag +[codecov-image]: https://codecov.io/gh/inspect-js/has-tostringtag/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/inspect-js/has-tostringtag/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/has-tostringtag +[actions-url]: https://github.com/inspect-js/has-tostringtag/actions diff --git a/node_modules/has-tostringtag/index.d.ts b/node_modules/has-tostringtag/index.d.ts new file mode 100644 index 0000000..a61bc60 --- /dev/null +++ b/node_modules/has-tostringtag/index.d.ts @@ -0,0 +1,3 @@ +declare function hasToStringTag(): boolean; + +export = hasToStringTag; diff --git a/node_modules/has-tostringtag/index.js b/node_modules/has-tostringtag/index.js new file mode 100644 index 0000000..77bfa00 --- /dev/null +++ b/node_modules/has-tostringtag/index.js @@ -0,0 +1,8 @@ +'use strict'; + +var hasSymbols = require('has-symbols'); + +/** @type {import('.')} */ +module.exports = function hasToStringTag() { + return hasSymbols() && typeof Symbol.toStringTag === 'symbol'; +}; diff --git a/node_modules/has-tostringtag/package.json b/node_modules/has-tostringtag/package.json new file mode 100644 index 0000000..e5b0300 --- /dev/null +++ b/node_modules/has-tostringtag/package.json @@ -0,0 +1,108 @@ +{ + "name": "has-tostringtag", + "version": "1.0.2", + "author": { + "name": "Jordan Harband", + "email": "ljharb@gmail.com", + "url": "http://ljharb.codes" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + }, + "contributors": [ + { + "name": "Jordan Harband", + "email": "ljharb@gmail.com", + "url": "http://ljharb.codes" + } + ], + "description": "Determine if the JS environment has `Symbol.toStringTag` support. Supports spec, or shams.", + "license": "MIT", + "main": "index.js", + "types": "./index.d.ts", + "exports": { + ".": [ + { + "types": "./index.d.ts", + "default": "./index.js" + }, + "./index.js" + ], + "./shams": [ + { + "types": "./shams.d.ts", + "default": "./shams.js" + }, + "./shams.js" + ], + "./package.json": "./package.json" + }, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run --silent lint", + "test": "npm run tests-only", + "posttest": "aud --production", + "tests-only": "npm run test:stock && npm run test:shams", + "test:stock": "nyc node test", + "test:staging": "nyc node --harmony --es-staging test", + "test:shams": "npm run --silent test:shams:getownpropertysymbols && npm run --silent test:shams:corejs", + "test:shams:corejs": "nyc node test/shams/core-js.js", + "test:shams:getownpropertysymbols": "nyc node test/shams/get-own-property-symbols.js", + "lint": "eslint --ext=js,mjs .", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/inspect-js/has-tostringtag.git" + }, + "bugs": { + "url": "https://github.com/inspect-js/has-tostringtag/issues" + }, + "homepage": "https://github.com/inspect-js/has-tostringtag#readme", + "keywords": [ + "javascript", + "ecmascript", + "symbol", + "symbols", + "tostringtag", + "Symbol.toStringTag" + ], + "devDependencies": { + "@ljharb/eslint-config": "^21.1.0", + "@types/has-symbols": "^1.0.2", + "@types/tape": "^5.6.4", + "aud": "^2.0.4", + "auto-changelog": "^2.4.0", + "core-js": "^2.6.12", + "eslint": "=8.8.0", + "get-own-property-symbols": "^0.9.5", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.7.4", + "typescript": "next" + }, + "engines": { + "node": ">= 0.4" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "dependencies": { + "has-symbols": "^1.0.3" + } +} diff --git a/node_modules/has-tostringtag/shams.d.ts b/node_modules/has-tostringtag/shams.d.ts new file mode 100644 index 0000000..ea4aeec --- /dev/null +++ b/node_modules/has-tostringtag/shams.d.ts @@ -0,0 +1,3 @@ +declare function hasToStringTagShams(): boolean; + +export = hasToStringTagShams; diff --git a/node_modules/has-tostringtag/shams.js b/node_modules/has-tostringtag/shams.js new file mode 100644 index 0000000..809580d --- /dev/null +++ b/node_modules/has-tostringtag/shams.js @@ -0,0 +1,8 @@ +'use strict'; + +var hasSymbols = require('has-symbols/shams'); + +/** @type {import('.')} */ +module.exports = function hasToStringTagShams() { + return hasSymbols() && !!Symbol.toStringTag; +}; diff --git a/node_modules/has-tostringtag/test/index.js b/node_modules/has-tostringtag/test/index.js new file mode 100644 index 0000000..0679afd --- /dev/null +++ b/node_modules/has-tostringtag/test/index.js @@ -0,0 +1,21 @@ +'use strict'; + +var test = require('tape'); +var hasSymbolToStringTag = require('../'); +var runSymbolTests = require('./tests'); + +test('interface', function (t) { + t.equal(typeof hasSymbolToStringTag, 'function', 'is a function'); + t.equal(typeof hasSymbolToStringTag(), 'boolean', 'returns a boolean'); + t.end(); +}); + +test('Symbol.toStringTag exists', { skip: !hasSymbolToStringTag() }, function (t) { + runSymbolTests(t); + t.end(); +}); + +test('Symbol.toStringTag does not exist', { skip: hasSymbolToStringTag() }, function (t) { + t.equal(typeof Symbol === 'undefined' ? 'undefined' : typeof Symbol.toStringTag, 'undefined', 'global Symbol.toStringTag is undefined'); + t.end(); +}); diff --git a/node_modules/has-tostringtag/test/shams/core-js.js b/node_modules/has-tostringtag/test/shams/core-js.js new file mode 100644 index 0000000..7ab214d --- /dev/null +++ b/node_modules/has-tostringtag/test/shams/core-js.js @@ -0,0 +1,31 @@ +'use strict'; + +var test = require('tape'); + +if (typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol') { + test('has native Symbol.toStringTag support', function (t) { + t.equal(typeof Symbol, 'function'); + t.equal(typeof Symbol.toStringTag, 'symbol'); + t.end(); + }); + // @ts-expect-error CJS has top-level return + return; +} + +var hasSymbolToStringTag = require('../../shams'); + +test('polyfilled Symbols', function (t) { + /* eslint-disable global-require */ + t.equal(hasSymbolToStringTag(), false, 'hasSymbolToStringTag is false before polyfilling'); + // @ts-expect-error no types defined + require('core-js/fn/symbol'); + // @ts-expect-error no types defined + require('core-js/fn/symbol/to-string-tag'); + + require('../tests')(t); + + var hasToStringTagAfter = hasSymbolToStringTag(); + t.equal(hasToStringTagAfter, true, 'hasSymbolToStringTag is true after polyfilling'); + /* eslint-enable global-require */ + t.end(); +}); diff --git a/node_modules/has-tostringtag/test/shams/get-own-property-symbols.js b/node_modules/has-tostringtag/test/shams/get-own-property-symbols.js new file mode 100644 index 0000000..c8af44c --- /dev/null +++ b/node_modules/has-tostringtag/test/shams/get-own-property-symbols.js @@ -0,0 +1,30 @@ +'use strict'; + +var test = require('tape'); + +if (typeof Symbol === 'function' && typeof Symbol() === 'symbol') { + test('has native Symbol support', function (t) { + t.equal(typeof Symbol, 'function'); + t.equal(typeof Symbol(), 'symbol'); + t.end(); + }); + // @ts-expect-error CJS has top-level return + return; +} + +var hasSymbolToStringTag = require('../../shams'); + +test('polyfilled Symbols', function (t) { + /* eslint-disable global-require */ + t.equal(hasSymbolToStringTag(), false, 'hasSymbolToStringTag is false before polyfilling'); + + // @ts-expect-error no types defined + require('get-own-property-symbols'); + + require('../tests')(t); + + var hasToStringTagAfter = hasSymbolToStringTag(); + t.equal(hasToStringTagAfter, true, 'hasSymbolToStringTag is true after polyfilling'); + /* eslint-enable global-require */ + t.end(); +}); diff --git a/node_modules/has-tostringtag/test/tests.js b/node_modules/has-tostringtag/test/tests.js new file mode 100644 index 0000000..2aa0d48 --- /dev/null +++ b/node_modules/has-tostringtag/test/tests.js @@ -0,0 +1,15 @@ +'use strict'; + +// eslint-disable-next-line consistent-return +module.exports = /** @type {(t: import('tape').Test) => void | false} */ function runSymbolTests(t) { + t.equal(typeof Symbol, 'function', 'global Symbol is a function'); + t.ok(Symbol.toStringTag, 'Symbol.toStringTag exists'); + + if (typeof Symbol !== 'function' || !Symbol.toStringTag) { return false; } + + /** @type {{ [Symbol.toStringTag]?: 'test'}} */ + var obj = {}; + obj[Symbol.toStringTag] = 'test'; + + t.equal(Object.prototype.toString.call(obj), '[object test]'); +}; diff --git a/node_modules/has-tostringtag/tsconfig.json b/node_modules/has-tostringtag/tsconfig.json new file mode 100644 index 0000000..2002ce5 --- /dev/null +++ b/node_modules/has-tostringtag/tsconfig.json @@ -0,0 +1,49 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + + /* Language and Environment */ + "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + "typeRoots": ["types"], /* Specify multiple folders that act like './node_modules/@types'. */ + "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + + /* JavaScript Support */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + "maxNodeModuleJsDepth": 0, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ + "noEmit": true, /* Disable emitting files from a compilation. */ + + /* Interop Constraints */ + "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + + /* Completeness */ + //"skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "exclude": [ + "coverage" + ] +} diff --git a/node_modules/hasown/.eslintrc b/node_modules/hasown/.eslintrc new file mode 100644 index 0000000..3b5d9e9 --- /dev/null +++ b/node_modules/hasown/.eslintrc @@ -0,0 +1,5 @@ +{ + "root": true, + + "extends": "@ljharb", +} diff --git a/node_modules/hasown/.github/FUNDING.yml b/node_modules/hasown/.github/FUNDING.yml new file mode 100644 index 0000000..d68c8b7 --- /dev/null +++ b/node_modules/hasown/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/hasown +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with a single custom sponsorship URL diff --git a/node_modules/hasown/.nycrc b/node_modules/hasown/.nycrc new file mode 100644 index 0000000..1826526 --- /dev/null +++ b/node_modules/hasown/.nycrc @@ -0,0 +1,13 @@ +{ + "all": true, + "check-coverage": false, + "reporter": ["text-summary", "text", "html", "json"], + "lines": 86, + "statements": 85.93, + "functions": 82.43, + "branches": 76.06, + "exclude": [ + "coverage", + "test" + ] +} diff --git a/node_modules/hasown/CHANGELOG.md b/node_modules/hasown/CHANGELOG.md new file mode 100644 index 0000000..2b0a980 --- /dev/null +++ b/node_modules/hasown/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v2.0.2](https://github.com/inspect-js/hasOwn/compare/v2.0.1...v2.0.2) - 2024-03-10 + +### Commits + +- [types] use shared config [`68e9d4d`](https://github.com/inspect-js/hasOwn/commit/68e9d4dab6facb4f05f02c6baea94a3f2a4e44b2) +- [actions] remove redundant finisher; use reusable workflow [`241a68e`](https://github.com/inspect-js/hasOwn/commit/241a68e13ea1fe52bec5ba7f74144befc31fae7b) +- [Tests] increase coverage [`4125c0d`](https://github.com/inspect-js/hasOwn/commit/4125c0d6121db56ae30e38346dfb0c000b04f0a7) +- [Tests] skip `npm ls` in old node due to TS [`01b9282`](https://github.com/inspect-js/hasOwn/commit/01b92822f9971dea031eafdd14767df41d61c202) +- [types] improve predicate type [`d340f85`](https://github.com/inspect-js/hasOwn/commit/d340f85ce02e286ef61096cbbb6697081d40a12b) +- [Dev Deps] update `tape` [`70089fc`](https://github.com/inspect-js/hasOwn/commit/70089fcf544e64acc024cbe60f5a9b00acad86de) +- [Tests] use `@arethetypeswrong/cli` [`50b272c`](https://github.com/inspect-js/hasOwn/commit/50b272c829f40d053a3dd91c9796e0ac0b2af084) + +## [v2.0.1](https://github.com/inspect-js/hasOwn/compare/v2.0.0...v2.0.1) - 2024-02-10 + +### Commits + +- [types] use a handwritten d.ts file; fix exported type [`012b989`](https://github.com/inspect-js/hasOwn/commit/012b9898ccf91dc441e2ebf594ff70270a5fda58) +- [Dev Deps] update `@types/function-bind`, `@types/mock-property`, `@types/tape`, `aud`, `mock-property`, `npmignore`, `tape`, `typescript` [`977a56f`](https://github.com/inspect-js/hasOwn/commit/977a56f51a1f8b20566f3c471612137894644025) +- [meta] add `sideEffects` flag [`3a60b7b`](https://github.com/inspect-js/hasOwn/commit/3a60b7bf42fccd8c605e5f145a6fcc83b13cb46f) + +## [v2.0.0](https://github.com/inspect-js/hasOwn/compare/v1.0.1...v2.0.0) - 2023-10-19 + +### Commits + +- revamped implementation, tests, readme [`72bf8b3`](https://github.com/inspect-js/hasOwn/commit/72bf8b338e77a638f0a290c63ffaed18339c36b4) +- [meta] revamp package.json [`079775f`](https://github.com/inspect-js/hasOwn/commit/079775fb1ec72c1c6334069593617a0be3847458) +- Only apps should have lockfiles [`6640e23`](https://github.com/inspect-js/hasOwn/commit/6640e233d1bb8b65260880f90787637db157d215) + +## v1.0.1 - 2023-10-10 + +### Commits + +- Initial commit [`8dbfde6`](https://github.com/inspect-js/hasOwn/commit/8dbfde6e8fb0ebb076fab38d138f2984eb340a62) diff --git a/node_modules/hasown/LICENSE b/node_modules/hasown/LICENSE new file mode 100644 index 0000000..0314929 --- /dev/null +++ b/node_modules/hasown/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Jordan Harband and contributors + +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. diff --git a/node_modules/hasown/README.md b/node_modules/hasown/README.md new file mode 100644 index 0000000..f759b8a --- /dev/null +++ b/node_modules/hasown/README.md @@ -0,0 +1,40 @@ +# hasown [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +A robust, ES3 compatible, "has own property" predicate. + +## Example + +```js +const assert = require('assert'); +const hasOwn = require('hasown'); + +assert.equal(hasOwn({}, 'toString'), false); +assert.equal(hasOwn([], 'length'), true); +assert.equal(hasOwn({ a: 42 }, 'a'), true); +``` + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +[package-url]: https://npmjs.org/package/hasown +[npm-version-svg]: https://versionbadg.es/inspect-js/hasown.svg +[deps-svg]: https://david-dm.org/inspect-js/hasOwn.svg +[deps-url]: https://david-dm.org/inspect-js/hasOwn +[dev-deps-svg]: https://david-dm.org/inspect-js/hasOwn/dev-status.svg +[dev-deps-url]: https://david-dm.org/inspect-js/hasOwn#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/hasown.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/hasown.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/hasown.svg +[downloads-url]: https://npm-stat.com/charts.html?package=hasown +[codecov-image]: https://codecov.io/gh/inspect-js/hasOwn/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/inspect-js/hasOwn/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/hasOwn +[actions-url]: https://github.com/inspect-js/hasOwn/actions diff --git a/node_modules/hasown/index.d.ts b/node_modules/hasown/index.d.ts new file mode 100644 index 0000000..aafdf3b --- /dev/null +++ b/node_modules/hasown/index.d.ts @@ -0,0 +1,3 @@ +declare function hasOwn(o: O, p: K): o is O & Record; + +export = hasOwn; diff --git a/node_modules/hasown/index.js b/node_modules/hasown/index.js new file mode 100644 index 0000000..34e6059 --- /dev/null +++ b/node_modules/hasown/index.js @@ -0,0 +1,8 @@ +'use strict'; + +var call = Function.prototype.call; +var $hasOwn = Object.prototype.hasOwnProperty; +var bind = require('function-bind'); + +/** @type {import('.')} */ +module.exports = bind.call(call, $hasOwn); diff --git a/node_modules/hasown/package.json b/node_modules/hasown/package.json new file mode 100644 index 0000000..8502e13 --- /dev/null +++ b/node_modules/hasown/package.json @@ -0,0 +1,92 @@ +{ + "name": "hasown", + "version": "2.0.2", + "description": "A robust, ES3 compatible, \"has own property\" predicate.", + "main": "index.js", + "exports": { + ".": "./index.js", + "./package.json": "./package.json" + }, + "types": "index.d.ts", + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublish": "not-in-publish || npm run prepublishOnly", + "prepublishOnly": "safe-publish-latest", + "prelint": "evalmd README.md", + "lint": "eslint --ext=js,mjs .", + "postlint": "npm run tsc", + "pretest": "npm run lint", + "tsc": "tsc -p .", + "posttsc": "attw -P", + "tests-only": "nyc tape 'test/**/*.js'", + "test": "npm run tests-only", + "posttest": "aud --production", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/inspect-js/hasOwn.git" + }, + "keywords": [ + "has", + "hasOwnProperty", + "hasOwn", + "has-own", + "own", + "has", + "property", + "in", + "javascript", + "ecmascript" + ], + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/inspect-js/hasOwn/issues" + }, + "homepage": "https://github.com/inspect-js/hasOwn#readme", + "dependencies": { + "function-bind": "^1.1.2" + }, + "devDependencies": { + "@arethetypeswrong/cli": "^0.15.1", + "@ljharb/eslint-config": "^21.1.0", + "@ljharb/tsconfig": "^0.2.0", + "@types/function-bind": "^1.1.10", + "@types/mock-property": "^1.0.2", + "@types/tape": "^5.6.4", + "aud": "^2.0.4", + "auto-changelog": "^2.4.0", + "eslint": "=8.8.0", + "evalmd": "^0.0.19", + "in-publish": "^2.0.1", + "mock-property": "^1.0.3", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "safe-publish-latest": "^2.0.0", + "tape": "^5.7.5", + "typescript": "next" + }, + "engines": { + "node": ">= 0.4" + }, + "testling": { + "files": "test/index.js" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows", + "test" + ] + } +} diff --git a/node_modules/hasown/tsconfig.json b/node_modules/hasown/tsconfig.json new file mode 100644 index 0000000..0930c56 --- /dev/null +++ b/node_modules/hasown/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "@ljharb/tsconfig", + "exclude": [ + "coverage", + ], +} diff --git a/node_modules/ldapjs/.eslintignore b/node_modules/ldapjs/.eslintignore new file mode 100644 index 0000000..5538d2f --- /dev/null +++ b/node_modules/ldapjs/.eslintignore @@ -0,0 +1,4 @@ +node_modules/ +coverage/ +.nyc_output/ +docs/ diff --git a/node_modules/ldapjs/.eslintrc.js b/node_modules/ldapjs/.eslintrc.js new file mode 100644 index 0000000..e657d1c --- /dev/null +++ b/node_modules/ldapjs/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + env: { + commonjs: true, + es2021: true, + node: true + }, + parserOptions: { + ecmaVersion: 'latest' + }, + extends: [ + 'standard' + ], + rules: { + 'no-shadow': 'error', + 'no-unused-vars': ['error', { + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_' + }] + } +} diff --git a/node_modules/ldapjs/.github/dependabot.yml b/node_modules/ldapjs/.github/dependabot.yml new file mode 100644 index 0000000..9a4ac3c --- /dev/null +++ b/node_modules/ldapjs/.github/dependabot.yml @@ -0,0 +1,18 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + # versioning-strategy: increase-if-necessary + directory: "/" + schedule: + interval: "weekly" + day: "saturday" + time: "03:00" + timezone: "America/New_York" + - package-ecosystem: "npm" + versioning-strategy: increase-if-necessary + directory: "/" + schedule: + interval: "weekly" + day: "saturday" + time: "03:00" + timezone: "America/New_York" diff --git a/node_modules/ldapjs/.github/workflows/docs.yml b/node_modules/ldapjs/.github/workflows/docs.yml new file mode 100644 index 0000000..bf19d23 --- /dev/null +++ b/node_modules/ldapjs/.github/workflows/docs.yml @@ -0,0 +1,30 @@ +name: 'Update Docs' + +on: + push: + branches: + - master + +jobs: + docs: + name: Update Docs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: '18' + - name: Install Packages + run: npm install + - name: Build Docs + run: npm run docs + - name: Deploy 🚢 + uses: cpina/github-action-push-to-another-repository@master + env: + API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }} + with: + source-directory: 'public' + destination-github-username: 'ldapjs' + destination-repository-name: 'ldapjs.github.io' + user-email: 'bot@ldapjs.org' + target-branch: 'gh-pages' diff --git a/node_modules/ldapjs/.github/workflows/integration.yml b/node_modules/ldapjs/.github/workflows/integration.yml new file mode 100644 index 0000000..71e1bf5 --- /dev/null +++ b/node_modules/ldapjs/.github/workflows/integration.yml @@ -0,0 +1,39 @@ +name: 'Integration Tests' + +# Notes: +# https://github.community/t5/GitHub-Actions/Github-Actions-services-not-reachable/m-p/30739/highlight/true#M538 + +on: + push: + branches: + - master + - next + pull_request: + branches: + - master + - next + +jobs: + baseline: + name: Baseline Tests + runs-on: ubuntu-latest + + services: + openldap: + image: ghcr.io/ldapjs/docker-test-openldap/openldap:2023-10-30 + ports: + - 389:389 + - 636:636 + options: > + --health-cmd "ldapsearch -Y EXTERNAL -Q -H ldapi:// -b ou=people,dc=planetexpress,dc=com -LLL '(cn=Turanga Leela)' cn" + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 'lts/*' + + - name: Install Packages + run: npm install + - name: Run Tests + run: npm run test:integration diff --git a/node_modules/ldapjs/.github/workflows/main.yml b/node_modules/ldapjs/.github/workflows/main.yml new file mode 100644 index 0000000..bdef7f3 --- /dev/null +++ b/node_modules/ldapjs/.github/workflows/main.yml @@ -0,0 +1,47 @@ +name: 'Lint And Test' + +on: + push: + branches: + - master + - next + pull_request: + branches: + - master + - next + +jobs: + lint: + name: Lint Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 'lts/*' + - name: Install Packages + run: npm install + - name: Lint Code + run: npm run lint:ci + + run_tests: + name: Unit Tests + strategy: + matrix: + os: + - ubuntu-latest + - windows-latest + node: + - 16 + - 18 + - 20 + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node }} + - name: Install Packages + run: npm install + - name: Run Tests + run: npm run test:ci diff --git a/node_modules/ldapjs/.taprc.yml b/node_modules/ldapjs/.taprc.yml new file mode 100644 index 0000000..a7ae12e --- /dev/null +++ b/node_modules/ldapjs/.taprc.yml @@ -0,0 +1,10 @@ +# With PR #834 the code in this code base has been reduced significantly. +# As a result, the coverage percentages changed, and are much lower than +# previously. So we are reducing the requirements accordingly +branches: 50 +functions: 50 +lines: 50 +statements: 50 + +files: + - 'test/**/*.test.js' diff --git a/node_modules/ldapjs/CHANGES.md b/node_modules/ldapjs/CHANGES.md new file mode 100644 index 0000000..a29861e --- /dev/null +++ b/node_modules/ldapjs/CHANGES.md @@ -0,0 +1,104 @@ +# ldapjs Changelog + +## 2.0.0 + +- Going foward, please see https://github.com/ldapjs/node-ldapjs/releases + +## 1.0.2 + +- Update dtrace-provider dependency + +## 1.0.1 + +- Update dependencies + * assert-plus to 1.0.0 + * bunyan to 1.8.3 + * dashdash to 1.14.0 + * backoff to 2.5.0 + * once to 1.4.0 + * vasync to 1.6.4 + * verror to 1.8.1 + * dtrace-provider to 0.7.0 +- Drop any semblence of support for node 0.8.x + +## 1.0.0 + +- Update dependencies + * asn1 to 0.2.3 + * bunyan to 1.5.1 + * dtrace-provider to 0.6.0 +- Removed pooled client +- Removed custom formatting for GUIDs +- Completely overhaul DN parsing/formatting + - Add options for format preservation + - Removed `spaced()` and `rndSpaced` from DN API + - Fix parent/child rules regarding empty DNs +- Request routing overhaul + * #154 Route lookups do not depend on object property order + * #111 Null ('') DN will act as catch-all +- Add StartTLS support to client (Sponsored by: DoubleCheck Email Manager) +- Improve robustness of client reconnect logic +- Add 'resultError' event to client +- Update paged search automation in client +- Add Change.apply method for modifying objects +- #143 Preserve raw Buffer value in Control objects +- Test code coverage with node-istanbul +- Convert tests to node-tape +- Add controls for server-side sorting +- #201 Replace nopt with dashdash +- #134 Allow configuration of derefAliases client option +- #197 Properly dispatch unbind requests +- #196 Handle string ports properly in server.listen +- Add basic server API tests +- Store EqualityFilter value as Buffer +- Run full test suite during 'make test' +- #190 Add error code 123 from RFC4370 +- #178 Perform strict presence testing on attribute vals +- #183 Accept buffers or strings for cert/key in createServer +- #180 Add '-i, --insecure' option and to all ldapjs-\* CLIs +- #254 Allow simple client bind with empty credentials + +## 0.7.1 + +- #169 Update dependencies + * asn1 to 0.2.1 + * pooling to 0.4.6 + * assert-plus to 0.1.5 + * bunyan to 0.22.1 +- #173 Make dtrace-provider an optional dependency +- #142 Improve parser error handling +- #161 Properly handle close events on tls sockets +- #163 Remove buffertools dependency +- #162 Fix error event handling for pooled clients +- #159 Allow ext request message to have a buffer value +- #155 Make \*Filter.matches case insensitive for attrs + +## 0.7.0 + +- #87 Minor update to ClientPool event pass-through +- #145 Update pooling to 0.4.5 +- #144 Fix unhandled error during client connection +- Output ldapi:// URLs for UNIX domain sockets +- Support extensible matching of caseIgnore and caseIgnoreSubstrings +- Fix some ClientPool event handling +- Improve DN formatting flexibility + * Add 'spaced' function to DN objects allowing toggle of inter-RDN when + rendering to a string. ('dc=test,dc=tld' vs 'dc=test, dc=tld') + * Detect RDN spacing when parsing DN. +- #128 Fix user can't bind with inmemory example +- #139 Bump required tap version to 0.4.1 +- Allow binding ldap server on an ephemeral port + +## 0.6.3 + +- Update bunyan to 0.21.1 +- Remove listeners on the right object (s/client/res/) +- Replace log4js with bunyan for binaries +- #127 socket is closed issue with pools +- #122 Allow changing TLS connection options in client +- #120 Fix a bug with formatting digits less than 16. +- #118 Fix "failed to instantiate provider" warnings in console on SmartOS + +## 0.6.2 - 0.1.0 + +**See git history** diff --git a/node_modules/ldapjs/LICENSE b/node_modules/ldapjs/LICENSE new file mode 100644 index 0000000..a232e66 --- /dev/null +++ b/node_modules/ldapjs/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2019 LDAPjs, All rights reserved. + +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 diff --git a/node_modules/ldapjs/README.md b/node_modules/ldapjs/README.md new file mode 100644 index 0000000..4139f1d --- /dev/null +++ b/node_modules/ldapjs/README.md @@ -0,0 +1,71 @@ +# LDAPjs + +[![Build Status](https://github.com/ldapjs/node-ldapjs/workflows/Lint%20And%20Test/badge.svg)](https://github.com/ldapjs/node-ldapjs/actions) +[![Coverage Status](https://coveralls.io/repos/github/ldapjs/node-ldapjs/badge.svg)](https://coveralls.io/github/ldapjs/node-ldapjs/) + +LDAPjs makes the LDAP protocol a first class citizen in Node.js. + +## Usage + +For full docs, head on over to . + +```javascript +var ldap = require('ldapjs'); + +var server = ldap.createServer(); + +server.search('dc=example', function(req, res, next) { + var obj = { + dn: req.dn.toString(), + attributes: { + objectclass: ['organization', 'top'], + o: 'example' + } + }; + + if (req.filter.matches(obj.attributes)) + res.send(obj); + + res.end(); +}); + +server.listen(1389, function() { + console.log('ldapjs listening at ' + server.url); +}); +``` + +To run that, assuming you've got the [OpenLDAP](http://www.openldap.org/) +client on your system: + + ldapsearch -H ldap://localhost:1389 -x -b dc=example objectclass=* + +## Installation + + npm install ldapjs + +## Node.js Version Support + +As of `ldapjs@3` we only support the active Node.js LTS releases. +See [https://github.com/nodejs/release#release-schedule][schedule] for the LTS +release schedule. + +For a definitive list of Node.js version we support, see the version matrix +we test against in our [CI configuration][ci-config]. + +Note: given the release date of `ldapjs@3`, and the short window of time that +Node.js v14 had remaining on its LTS window, we opted to not support Node.js +v14 with `ldapjs@3` (we released late February 2023 and v14 goes into +maintenance in late April 2023). Also, Node.js v14 will be end-of-life (EOL) on +September 11, 2023; this is a very shortened EOL timeline and makes it even +more reasonable to not support it at this point. + +[schedule]: https://github.com/nodejs/release#release-schedule +[ci-config]: https://github.com/ldapjs/node-ldapjs/blob/master/.github/workflows/main.yml + +## License + +MIT. + +## Bugs + +See . diff --git a/node_modules/ldapjs/docker-compose.yml b/node_modules/ldapjs/docker-compose.yml new file mode 100644 index 0000000..19c4b5f --- /dev/null +++ b/node_modules/ldapjs/docker-compose.yml @@ -0,0 +1,10 @@ +services: + openldap: + image: ghcr.io/ldapjs/docker-test-openldap/openldap:2023-10-30 + ports: + - 389:389 + - 636:636 + healthcheck: + start_period: 3s + test: > + /usr/bin/ldapsearch -Y EXTERNAL -Q -H ldapi:// -b ou=people,dc=planetexpress,dc=com -LLL '(cn=Turanga Leela)' cn 1>/dev/null diff --git a/node_modules/ldapjs/docs/branding/public/CNAME b/node_modules/ldapjs/docs/branding/public/CNAME new file mode 100644 index 0000000..cbe04d8 --- /dev/null +++ b/node_modules/ldapjs/docs/branding/public/CNAME @@ -0,0 +1 @@ +ldapjs.org diff --git a/node_modules/ldapjs/docs/branding/public/media/css/style.css b/node_modules/ldapjs/docs/branding/public/media/css/style.css new file mode 100644 index 0000000..adaae73 --- /dev/null +++ b/node_modules/ldapjs/docs/branding/public/media/css/style.css @@ -0,0 +1,266 @@ + +/* ---- general styles */ + +body { + font: 13px "Lucida Grande", "Lucida Sans Unicode", arial, sans-serif; + line-height: 1.53846; /* 20px */ + color: #4a3f2d; +} + +:focus:not(:focus-visible) { + outline: 0; +} + +h1,h2,h3 { + font-weight:normal; +} + +h3{ + margin-bottom:0; +} + +ul, li { + margin:0px; + padding:0px; +} + +ul { + margin-left:40px; +} + +ul > li { + list-style:disc; + list-style-position:inside; + margin:10px 0px; +} + +hr { + border:none; + width:98%; + margin-left:-10px; + border-top:1px solid #CCCCCC; + border-bottom:1px solid #FFFFFF; +} + +code, +pre { + border:1px solid #CCCCCC; + background:#F2F0EE; + -webkit-border-radius:2px; + -moz-border-radius:2px; + border-radius:2px; + white-space:pre-wrap; +} +code { + padding: 0 0.2em; +} +pre { + margin: 1em 0; + padding: .75em; + overflow: auto; + padding:10px 1.2em; + margin-top:0; + margin-bottom:20px; +} +pre code { + border: medium none; + padding: 0; +} +a code { + text-decoration: underline; +} + +a { + color:#FD6512; + text-decoration:none; +} + +h4 { + font-size: 85%; + margin: 0; + padding: 0; + line-height: 1em; + display: inline; +} + +/* ---- header and sidebar */ + +#header { + background:#C3BDB3; + background:#1C313C; + height:66px; + left:0px; + position:absolute; + top:0px; + width:100%; + z-index:1; + font-size:0.7em; +} + +#header h1 { + width: 424px; + height: 35px; + display:block; + background: url(../img/logo.svg) no-repeat; + line-height:2.1em; + padding:0; + padding-left:140px; + margin-top:18px; + margin-left:20px; + color:white; + text-transform: uppercase; +} + +#sidebar { + background-color:#EDEBEA; + bottom:0px; + left:0px; + overflow:auto; + padding:20px 0px 0px 15px; + position:absolute; + top:66px; + width:265px; + z-index:1; +} + +#content { + top:64px; + bottom:0px; + right:0px; + left:290px; + padding:20px 30px 400px; + position:absolute; + overflow:auto; + z-index:0; +} + +#sidebar h1 { + font-size:1.2em; + padding:0px; + margin-top:15px; + margin-bottom:3px; +} + +#sidebar ul { + margin:3px 0 10px 0; +} + +#sidebar ul ul { + margin:3px 0 5px 10px; +} + +#sidebar li { + margin:0; + padding:0; + font-size:0.9em; +} + +#sidebar li, +#sidebar li a { + color:#5C5954; + list-style:none; + padding:1px 0px 1px 2px; +} + + +/* ---- intro */ + +.intro { + color:#29231A; + padding: 22px 25px; + background: #EDEBEA; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + -o-border-radius: 5px; + border-radius: 5px; + margin-bottom:40px; +} +.intro h1 { + color: #1C313C; +} +.intro h3 { + margin: 5px 0px 3px; + font-size: 100%; + font-weight: bold; +} +.intro ul { + list-style-type:disc; + padding-left:20px; + margin-left:0; +} +.intro ul li{ + margin:0; +} +.intro p { + padding-left:20px; + margin: 5px 0px 3px; +} + + + +h2 { + overflow: auto; + margin-top: 60px; + border-top: 2px solid #979592; + z-index: 3; +} +h1 + h2 { + margin-top: 0px; +} + +h2 span { + background: #979592; + float:right; + color:#fff; + margin:0; + margin-left:3px; + padding:0.3em 0.7em; + font-size: 0.55em; + word-spacing: 0.8em; /* separate verb from path */ + color:#fff; +} + + + + +/*---- print media */ + +@media print { + body { background:white; color:black; margin:0; } + #sidebar { + display: none; + } + #content { + position: relative; + padding: 5px; + left: 0px; + top: 0px; + } + h1, h2, h4 { + page-break-after: avoid; + } + pre { + page-break-inside: avoid; + } +} + +/* tables still need cellspacing="0" in the markup */ +table { + border-collapse:collapse; border-spacing:0; + margin: 20px 0; +} +th, +td { + border: solid #aaa; + border-width: 1px 0; + line-height: 23px; + padding: 0 12px; + text-align: left; + vertical-align: text-bottom; +} +th { + border-collapse: separate; +} +tbody tr:nth-child(odd) { + background-color: #f2f0ee; +} diff --git a/node_modules/ldapjs/docs/branding/public/media/img/logo.svg b/node_modules/ldapjs/docs/branding/public/media/img/logo.svg new file mode 100644 index 0000000..8246eb8 --- /dev/null +++ b/node_modules/ldapjs/docs/branding/public/media/img/logo.svg @@ -0,0 +1 @@ + diff --git a/node_modules/ldapjs/docs/branding/template.html b/node_modules/ldapjs/docs/branding/template.html new file mode 100644 index 0000000..01183cc --- /dev/null +++ b/node_modules/ldapjs/docs/branding/template.html @@ -0,0 +1,39 @@ + + + + %(title)s + + + + + +

+ + +
+%(content)s +
+ + + diff --git a/node_modules/ldapjs/docs/client.md b/node_modules/ldapjs/docs/client.md new file mode 100644 index 0000000..d88b223 --- /dev/null +++ b/node_modules/ldapjs/docs/client.md @@ -0,0 +1,491 @@ +--- +title: Client API | ldapjs +--- + +# ldapjs Client API + +
+ +This document covers the ldapjs client API and assumes that you are familiar +with LDAP. If you're not, read the [guide](guide.html) first. + +
+ +# Create a client + +The code to create a new client looks like: + +```js +const ldap = require('ldapjs'); + +const client = ldap.createClient({ + url: ['ldap://127.0.0.1:1389', 'ldap://127.0.0.2:1389'] +}); + +client.on('connectError', (err) => { + // handle connection error +}) +``` + +You can use `ldap://` or `ldaps://`; the latter would connect over SSL (note +that this will not use the LDAP TLS extended operation, but literally an SSL +connection to port 636, as in LDAP v2). The full set of options to create a +client is: + +|Attribute |Description | +|---------------|-----------------------------------------------------------| +|url |A string or array of valid LDAP URL(s) (proto/host/port) | +|socketPath |Socket path if using AF\_UNIX sockets | +|log |A compatible logger instance (Default: no-op logger) | +|timeout |Milliseconds client should let operations live for before timing out (Default: Infinity)| +|connectTimeout |Milliseconds client should wait before timing out on TCP connections (Default: OS default)| +|tlsOptions |Additional options passed to TLS connection layer when connecting via `ldaps://` (See: The TLS docs for node.js)| +|idleTimeout |Milliseconds after last activity before client emits idle event| +|reconnect |Try to reconnect when the connection gets lost (Default is false)| + +### url +This parameter takes a single connection string or an array of connection strings +as an input. In case an array is provided, the client tries to connect to the +servers in given order. To achieve random server strategy (e.g. to distribute +the load among the servers), please shuffle the array before passing it as an +argument. + +### Note On Logger + +A passed in logger is expected to conform to the [Bunyan](https://www.npmjs.com/package/bunyan) +API. Specifically, the logger is expected to have a `child()` method. If a logger +is supplied that does not have such a method, then a shim version is added +that merely returns the passed in logger. + +Known compatible loggers are: + ++ [Bunyan](https://www.npmjs.com/package/bunyan) ++ [Pino](https://www.npmjs.com/package/pino) + + +### Note On Error Handling + +The client is an `EventEmitter`. If you don't register an error handler and +e.g. a connection error occurs, Node.js will print a stack trace and exit the +process ([reference](https://nodejs.org/api/events.html#error-events)). + +## Connection management + +As LDAP is a stateful protocol (as opposed to HTTP), having connections torn +down from underneath you can be difficult to deal with. Several mechanisms +have been provided to mitigate this trouble. + +### Reconnect + +You can provide a Boolean option indicating if a reconnect should be tried. For +more sophisticated control, you can provide an Object with the properties +`initialDelay` (default: `100`), `maxDelay` (default: `10000`) and +`failAfter` (default: `Infinity`). +After the reconnect you maybe need to [bind](#bind) again. + +## Client events + +The client is an `EventEmitter` and can emit the following events: + +|Event |Description | +|---------------|----------------------------------------------------------| +|error |General error | +|connectRefused |Server refused connection. Most likely bad authentication | +|connectTimeout |Server timeout | +|connectError |Socket connection error | +|setupError |Setup error after successful connection | +|socketTimeout |Socket timeout | +|resultError |Search result error | +|timeout |Search result timeout | +|destroy |After client is disconnected | +|end |Socket end event | +|close |Socket closed | +|connect |Client connected | +|idle |Idle timeout reached | + +## Common patterns + +The last two parameters in every API are `controls` and `callback`. `controls` +can be either a single instance of a `Control` or an array of `Control` objects. +You can, and probably will, omit this option. + +Almost every operation has the callback form of `function(err, res)` where err +will be an instance of an `LDAPError` (you can use `instanceof` to switch). +You probably won't need to check the `res` parameter, but it's there if you do. + +# bind +`bind(dn, password, controls, callback)` + +Performs a bind operation against the LDAP server. + +The bind API only allows LDAP 'simple' binds (equivalent to HTTP Basic +Authentication) for now. Note that all client APIs can optionally take an array +of `Control` objects. You probably don't need them though... + +Example: + +```js +client.bind('cn=root', 'secret', (err) => { + assert.ifError(err); +}); +``` + +# add +`add(dn, entry, controls, callback)` + +Performs an add operation against the LDAP server. + +Allows you to add an entry (which is just a plain JS object), and as always, +controls are optional. + +Example: + +```js +const entry = { + cn: 'foo', + sn: 'bar', + email: ['foo@bar.com', 'foo1@bar.com'], + objectclass: 'fooPerson' +}; +client.add('cn=foo, o=example', entry, (err) => { + assert.ifError(err); +}); +``` + +# compare +`compare(dn, attribute, value, controls, callback)` + +Performs an LDAP compare operation with the given attribute and value against +the entry referenced by dn. + +Example: + +```js +client.compare('cn=foo, o=example', 'sn', 'bar', (err, matched) => { + assert.ifError(err); + + console.log('matched: ' + matched); +}); +``` + +# del +`del(dn, controls, callback)` + + +Deletes an entry from the LDAP server. + +Example: + +```js +client.del('cn=foo, o=example', (err) => { + assert.ifError(err); +}); +``` + +# exop +`exop(name, value, controls, callback)` + +Performs an LDAP extended operation against an LDAP server. `name` is typically +going to be an OID (well, the RFC says it must be; however, ldapjs has no such +restriction). `value` is completely arbitrary, and is whatever the exop says it +should be. + +Example (performs an LDAP 'whois' extended op): + +```js +client.exop('1.3.6.1.4.1.4203.1.11.3', (err, value, res) => { + assert.ifError(err); + + console.log('whois: ' + value); +}); +``` + +# modify +`modify(name, changes, controls, callback)` + +Performs an LDAP modify operation against the LDAP server. This API requires +you to pass in a `Change` object, which is described below. Note that you can +pass in a single `Change` or an array of `Change` objects. + +Example: + +```js +const change = new ldap.Change({ + operation: 'add', + modification: { + type: 'pets', + values: ['cat', 'dog'] + } +}); + +client.modify('cn=foo, o=example', change, (err) => { + assert.ifError(err); +}); +``` + +## Change + +A `Change` object maps to the LDAP protocol of a modify change, and requires you +to set the `operation` and `modification`. The `operation` is a string, and +must be one of: + +| Operation | Description | +|-----------|-------------| +| replace | Replaces the attribute referenced in `modification`. If the modification has no values, it is equivalent to a delete. | +| add | Adds the attribute value(s) referenced in `modification`. The attribute may or may not already exist. | +| delete | Deletes the attribute (and all values) referenced in `modification`. | + +`modification` is just a plain old JS object with the required type and values you want. + +| Operation | Description | +|-----------|-------------| +| type | String that defines the attribute type for the modification. | +| values | Defines the values for modification. | + + +# modifyDN +`modifyDN(dn, newDN, controls, callback)` + +Performs an LDAP modifyDN (rename) operation against an entry in the LDAP +server. A couple points with this client API: + +* There is no ability to set "keep old dn." It's always going to flag the old +dn to be purged. +* The client code will automatically figure out if the request is a "new +superior" request ("new superior" means move to a different part of the tree, +as opposed to just renaming the leaf). + +Example: + +```js +client.modifyDN('cn=foo, o=example', 'cn=bar', (err) => { + assert.ifError(err); +}); +``` + +# search +`search(base, options, controls, callback)` + +Performs a search operation against the LDAP server. + +The search operation is more complex than the other operations, so this one +takes an `options` object for all the parameters. However, ldapjs makes some +defaults for you so that if you pass nothing in, it's pretty much equivalent +to an HTTP GET operation (i.e., base search against the DN, filter set to +always match). + +Like every other operation, `base` is a DN string. + +Options can be a string representing a valid LDAP filter or an object +containing the following fields: + +|Attribute |Description | +|-----------|---------------------------------------------------| +|scope |One of `base`, `one`, or `sub`. Defaults to `base`.| +|filter |A string version of an LDAP filter (see below), or a programatically constructed `Filter` object. Defaults to `(objectclass=*)`.| +|attributes |attributes to select and return (if these are set, the server will return *only* these attributes). Defaults to the empty set, which means all attributes. You can provide a string if you want a single attribute or an array of string for one or many.| +|attrsOnly |boolean on whether you want the server to only return the names of the attributes, and not their values. Borderline useless. Defaults to false.| +|sizeLimit |the maximum number of entries to return. Defaults to 0 (unlimited).| +|timeLimit |the maximum amount of time the server should take in responding, in seconds. Defaults to 10. Lots of servers will ignore this.| +|paged |enable and/or configure automatic result paging| + +Responses inside callback of the `search` method are an `EventEmitter` where you will get a notification for +each `searchEntry` that comes back from the server. You will additionally be able to listen for a `searchRequest` +, `searchReference`, `error` and `end` event. +`searchRequest` is emitted immediately after every `SearchRequest` is sent with a `SearchRequest` parameter. You can do operations +like `client.abandon` with `searchRequest.messageId` to abandon this search request. Note that the `error` event will +only be for client/TCP errors, not LDAP error codes like the other APIs. You'll want to check the LDAP status code +(likely for `0`) on the `end` event to assert success. LDAP search results can give you a lot of status codes, such as +time or size exceeded, busy, inappropriate matching, etc., which is why this method doesn't try to wrap up the code +matching. + +Example: + +```js +const opts = { + filter: '(&(l=Seattle)(email=*@foo.com))', + scope: 'sub', + attributes: ['dn', 'sn', 'cn'] +}; + +client.search('o=example', opts, (err, res) => { + assert.ifError(err); + + res.on('searchRequest', (searchRequest) => { + console.log('searchRequest: ', searchRequest.messageId); + }); + res.on('searchEntry', (entry) => { + console.log('entry: ' + JSON.stringify(entry.pojo)); + }); + res.on('searchReference', (referral) => { + console.log('referral: ' + referral.uris.join()); + }); + res.on('error', (err) => { + console.error('error: ' + err.message); + }); + res.on('end', (result) => { + console.log('status: ' + result.status); + }); +}); +``` + +## Filter Strings + +The easiest way to write search filters is to write them compliant with RFC2254, +which is "The string representation of LDAP search filters." Note that +ldapjs doesn't support extensible matching, since it's one of those features +that almost nobody actually uses in practice. + +Assuming you don't really want to read the RFC, search filters in LDAP are +basically are a "tree" of attribute/value assertions, with the tree specified +in prefix notation. For example, let's start simple, and build up a complicated +filter. The most basic filter is equality, so let's assume you want to search +for an attribute `email` with a value of `foo@bar.com`. The syntax would be: + +``` +(email=foo@bar.com) +``` + +ldapjs requires all filters to be surrounded by '()' blocks. Ok, that was easy. +Let's now assume that you want to find all records where the email is actually +just anything in the "@bar.com" domain and the location attribute is set to +Seattle: + +``` +(&(email=*@bar.com)(l=Seattle)) +``` + +Now our filter is actually three LDAP filters. We have an `and` filter (single +amp `&`), an `equality` filter `(the l=Seattle)`, and a `substring` filter. +Substrings are wildcard filters. They use `*` as the wildcard. You can put more +than one wildcard for a given string. For example you could do `(email=*@*bar.com)` +to match any email of @bar.com or its subdomains like `"example@foo.bar.com"`. + +Now, let's say we also want to set our filter to include a +specification that either the employeeType *not* be a manager nor a secretary: + +``` +(&(email=*@bar.com)(l=Seattle)(!(|(employeeType=manager)(employeeType=secretary)))) +``` + +The `not` character is represented as a `!`, the `or` as a single pipe `|`. +It gets a little bit complicated, but it's actually quite powerful, and lets you +find almost anything you're looking for. + +## Paging +Many LDAP server enforce size limits upon the returned result set (commonly +1000). In order to retrieve results beyond this limit, a `PagedResultControl` +is passed between the client and server to iterate through the entire dataset. +While callers could choose to do this manually via the `controls` parameter to +`search()`, ldapjs has internal mechanisms to easily automate the process. The +most simple way to use the paging automation is to set the `paged` option to +true when performing a search: + +```js +const opts = { + filter: '(objectclass=commonobject)', + scope: 'sub', + paged: true, + sizeLimit: 200 +}; +client.search('o=largedir', opts, (err, res) => { + assert.ifError(err); + res.on('searchEntry', (entry) => { + // do per-entry processing + }); + res.on('page', (result) => { + console.log('page end'); + }); + res.on('error', (resErr) => { + assert.ifError(resErr); + }); + res.on('end', (result) => { + console.log('done '); + }); +}); +``` + +This will enable paging with a default page size of 199 (`sizeLimit` - 1) and +will output all of the resulting objects via the `searchEntry` event. At the +end of each result during the operation, a `page` event will be emitted as +well (which includes the intermediate `searchResult` object). + +For those wanting more precise control over the process, an object with several +parameters can be provided for the `paged` option. The `pageSize` parameter +sets the size of result pages requested from the server. If no value is +specified, it will fall back to the default (100 or `sizeLimit` - 1, to obey +the RFC). The `pagePause` parameter allows back-pressure to be exerted on the +paged search operation by pausing at the end of each page. When enabled, a +callback function is passed as an additional parameter to `page` events. The +client will wait to request the next page until that callback is executed. + +Here is an example where both of those parameters are used: + +```js +const queue = new MyWorkQueue(someSlowWorkFunction); +const opts = { + filter: '(objectclass=commonobject)', + scope: 'sub', + paged: { + pageSize: 250, + pagePause: true + }, +}; +client.search('o=largerdir', opts, (err, res) => { + assert.ifError(err); + res.on('searchEntry', (entry) => { + // Submit incoming objects to queue + queue.push(entry); + }); + res.on('page', (result, cb) => { + // Allow the queue to flush before fetching next page + queue.cbWhenFlushed(cb); + }); + res.on('error', (resErr) => { + assert.ifError(resErr); + }); + res.on('end', (result) => { + console.log('done'); + }); +}); +``` + +# starttls +`starttls(options, controls, callback)` + +Attempt to secure existing LDAP connection via STARTTLS. + +Example: + +```js +const opts = { + ca: [fs.readFileSync('mycacert.pem')] +}; + +client.starttls(opts, (err, res) => { + assert.ifError(err); + + // Client communication now TLS protected +}); +``` + + +# unbind +`unbind(callback)` + +Performs an unbind operation against the LDAP server. + +Note that unbind operation is not an opposite operation +for bind. Unbinding results in disconnecting the client +regardless of whether a bind operation was performed. + +The `callback` argument is optional as unbind does +not have a response. + +Example: + +```js +client.unbind((err) => { + assert.ifError(err); +}); +``` diff --git a/node_modules/ldapjs/docs/dn.md b/node_modules/ldapjs/docs/dn.md new file mode 100644 index 0000000..c95d511 --- /dev/null +++ b/node_modules/ldapjs/docs/dn.md @@ -0,0 +1,127 @@ +--- +title: DN API | ldapjs +--- + +# ldapjs DN API + +
+ +This document covers the ldapjs DN API and assumes that you are familiar +with LDAP. If you're not, read the [guide](guide.html) first. + +
+ +DNs are LDAP distinguished names, and are composed of a set of RDNs (relative +distinguished names). [RFC2253](http://www.ietf.org/rfc/rfc2253.txt) has the +complete specification, but basically an RDN is an attribute value assertion +with `=` as the seperator, like: `cn=foo` where 'cn' is 'commonName' and 'foo' +is the value. You can have compound RDNs by using the `+` character: +`cn=foo+sn=bar`. As stated above, DNs are a set of RDNs, typically separated +with the `,` character, like: `cn=foo, ou=people, o=example`. This uniquely +identifies an entry in the tree, and is read "bottom up". + +# parseDN(dnString) + +The `parseDN` API converts a string representation of a DN into an ldapjs DN +object; in most cases this will be handled for you under the covers of the +ldapjs framework, but if you need it, it's there. + +```js +const parseDN = require('ldapjs').parseDN; + +const dn = parseDN('cn=foo+sn=bar, ou=people, o=example'); +console.log(dn.toString()); +``` + +# DN + +The DN object is largely what you'll be interacting with, since all the server +APIs are setup to give you a DN object. + +## childOf(dn) + +Returns a boolean indicating whether 'this' is a child of the passed in dn. The +`dn` argument can be either a string or a DN. + +```js +server.add('o=example', (req, res, next) => { + if (req.dn.childOf('ou=people, o=example')) { + ... + } else { + ... + } +}); +``` + +## parentOf(dn) + +The inverse of `childOf`; returns a boolean on whether or not `this` is a parent +of the passed in dn. Like `childOf`, can take either a string or a DN. + +```js +server.add('o=example', (req, res, next) => { + const dn = parseDN('ou=people, o=example'); + if (dn.parentOf(req.dn)) { + ... + } else { + ... + } +}); +``` + +## equals(dn) + +Returns a boolean indicating whether `this` is equivalent to the passed in `dn` +argument. `dn` can be a string or a DN. + +```js +server.add('o=example', (req, res, next) => { + if (req.dn.equals('cn=foo, ou=people, o=example')) { + ... + } else { + ... + } +}); +``` + +## parent() + +Returns a DN object that is the direct parent of `this`. If there is no parent +this can return `null` (e.g. `parseDN('o=example').parent()` will return null). + + +## format(options) + +Convert a DN object to string according to specified formatting options. These +options are divided into two types. Preservation Options use data recorded +during parsing to preserve details of the original DN. Modification options +alter string formatting defaults. Preservation options _always_ take +precedence over Modification Options. + +Preservation Options: + + - `keepOrder`: Order of multi-value RDNs. + - `keepQuote`: RDN values which were quoted will remain so. + - `keepSpace`: Leading/trailing spaces will be output. + - `keepCase`: Parsed attribute name will be output instead of lowercased version. + +Modification Options: + +- `upperName`: RDN names will be uppercased instead of lowercased. +- `skipSpace`: Disable trailing space after RDN separators + +## setFormat(options) + +Sets the default `options` for string formatting when `toString` is called. +It accepts the same parameters as `format`. + + +## toString() + +Returns the string representation of `this`. + +```js +server.add('o=example', (req, res, next) => { + console.log(req.dn.toString()); +}); +``` diff --git a/node_modules/ldapjs/docs/errors.md b/node_modules/ldapjs/docs/errors.md new file mode 100644 index 0000000..b44c5ec --- /dev/null +++ b/node_modules/ldapjs/docs/errors.md @@ -0,0 +1,94 @@ +--- +title: Errors API | ldapjs +--- + +# ldapjs Errors API + +
+ +This document covers the ldapjs errors API and assumes that you are familiar +with LDAP. If you're not, read the [guide](guide.html) first. + +
+ +All errors in the ldapjs framework extend from an abstract error type called +`LDAPError`. In addition to the properties listed below, all errors will have +a `stack` property correctly set. + +In general, you'll be using the errors in ldapjs like: + +```js +const ldap = require('ldapjs'); + +const db = {}; + +server.add('o=example', (req, res, next) => { + const parent = req.dn.parent(); + if (parent) { + if (!db[parent.toString()]) + return next(new ldap.NoSuchObjectError(parent.toString())); + } + if (db[req.dn.toString()]) + return next(new ldap.EntryAlreadyExistsError(req.dn.toString())); + + ... +}); +``` + +I.e., if you just pass them into the `next()` handler, ldapjs will automatically +return the appropriate LDAP error message, and stop the handler chain. + +All errors will have the following properties: + +## code + +Returns the LDAP status code associated with this error. + +## name + +The name of this error. + +## message + +The message that will be returned to the client. + +# Complete list of LDAPError subclasses + +* OperationsError +* ProtocolError +* TimeLimitExceededError +* SizeLimitExceededError +* CompareFalseError +* CompareTrueError +* AuthMethodNotSupportedError +* StrongAuthRequiredError +* ReferralError +* AdminLimitExceededError +* UnavailableCriticalExtensionError +* ConfidentialityRequiredError +* SaslBindInProgressError +* NoSuchAttributeError +* UndefinedAttributeTypeError +* InappropriateMatchingError +* ConstraintViolationError +* AttributeOrValueExistsError +* InvalidAttriubteSyntaxError +* NoSuchObjectError +* AliasProblemError +* InvalidDnSyntaxError +* AliasDerefProblemError +* InappropriateAuthenticationError +* InvalidCredentialsError +* InsufficientAccessRightsError +* BusyError +* UnavailableError +* UnwillingToPerformError +* LoopDetectError +* NamingViolationError +* ObjectclassViolationError +* NotAllowedOnNonLeafError +* NotAllowedOnRdnError +* EntryAlreadyExistsError +* ObjectclassModsProhibitedError +* AffectsMultipleDsasError +* OtherError diff --git a/node_modules/ldapjs/docs/examples.md b/node_modules/ldapjs/docs/examples.md new file mode 100644 index 0000000..6c6b21c --- /dev/null +++ b/node_modules/ldapjs/docs/examples.md @@ -0,0 +1,625 @@ +--- +title: Examples | ldapjs +--- + +# ldapjs Examples + +
+ +This page contains a (hopefully) growing list of sample code to get you started +with ldapjs. + +
+ +# In-memory server + +```js +const ldap = require('ldapjs'); + + +///--- Shared handlers + +function authorize(req, res, next) { + /* Any user may search after bind, only cn=root has full power */ + const isSearch = (req instanceof ldap.SearchRequest); + if (!req.connection.ldap.bindDN.equals('cn=root') && !isSearch) + return next(new ldap.InsufficientAccessRightsError()); + + return next(); +} + + +///--- Globals + +const SUFFIX = 'o=joyent'; +const db = {}; +const server = ldap.createServer(); + + + +server.bind('cn=root', (req, res, next) => { + if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret') + return next(new ldap.InvalidCredentialsError()); + + res.end(); + return next(); +}); + +server.add(SUFFIX, authorize, (req, res, next) => { + const dn = req.dn.toString(); + + if (db[dn]) + return next(new ldap.EntryAlreadyExistsError(dn)); + + db[dn] = req.toObject().attributes; + res.end(); + return next(); +}); + +server.bind(SUFFIX, (req, res, next) => { + const dn = req.dn.toString(); + if (!db[dn]) + return next(new ldap.NoSuchObjectError(dn)); + + if (!db[dn].userpassword) + return next(new ldap.NoSuchAttributeError('userPassword')); + + if (db[dn].userpassword.indexOf(req.credentials) === -1) + return next(new ldap.InvalidCredentialsError()); + + res.end(); + return next(); +}); + +server.compare(SUFFIX, authorize, (req, res, next) => { + const dn = req.dn.toString(); + if (!db[dn]) + return next(new ldap.NoSuchObjectError(dn)); + + if (!db[dn][req.attribute]) + return next(new ldap.NoSuchAttributeError(req.attribute)); + + const matches = false; + const vals = db[dn][req.attribute]; + for (const value of vals) { + if (value === req.value) { + matches = true; + break; + } + } + + res.end(matches); + return next(); +}); + +server.del(SUFFIX, authorize, (req, res, next) => { + const dn = req.dn.toString(); + if (!db[dn]) + return next(new ldap.NoSuchObjectError(dn)); + + delete db[dn]; + + res.end(); + return next(); +}); + +server.modify(SUFFIX, authorize, (req, res, next) => { + const dn = req.dn.toString(); + if (!req.changes.length) + return next(new ldap.ProtocolError('changes required')); + if (!db[dn]) + return next(new ldap.NoSuchObjectError(dn)); + + const entry = db[dn]; + + for (const change of req.changes) { + mod = change.modification; + switch (change.operation) { + case 'replace': + if (!entry[mod.type]) + return next(new ldap.NoSuchAttributeError(mod.type)); + + if (!mod.vals || !mod.vals.length) { + delete entry[mod.type]; + } else { + entry[mod.type] = mod.vals; + } + + break; + + case 'add': + if (!entry[mod.type]) { + entry[mod.type] = mod.vals; + } else { + for (const v of mod.vals) { + if (entry[mod.type].indexOf(v) === -1) + entry[mod.type].push(v); + } + } + + break; + + case 'delete': + if (!entry[mod.type]) + return next(new ldap.NoSuchAttributeError(mod.type)); + + delete entry[mod.type]; + + break; + } + } + + res.end(); + return next(); +}); + +server.search(SUFFIX, authorize, (req, res, next) => { + const dn = req.dn.toString(); + if (!db[dn]) + return next(new ldap.NoSuchObjectError(dn)); + + let scopeCheck; + + switch (req.scope) { + case 'base': + if (req.filter.matches(db[dn])) { + res.send({ + dn: dn, + attributes: db[dn] + }); + } + + res.end(); + return next(); + + case 'one': + scopeCheck = (k) => { + if (req.dn.equals(k)) + return true; + + const parent = ldap.parseDN(k).parent(); + return (parent ? parent.equals(req.dn) : false); + }; + break; + + case 'sub': + scopeCheck = (k) => { + return (req.dn.equals(k) || req.dn.parentOf(k)); + }; + + break; + } + + const keys = Object.keys(db); + for (const key of keys) { + if (!scopeCheck(key)) + return; + + if (req.filter.matches(db[key])) { + res.send({ + dn: key, + attributes: db[key] + }); + } + } + + res.end(); + return next(); +}); + + + +///--- Fire it up + +server.listen(1389, () => { + console.log('LDAP server up at: %s', server.url); +}); +``` + +# /etc/passwd server + +```js +const fs = require('fs'); +const ldap = require('ldapjs'); +const { spawn } = require('child_process'); + + + +///--- Shared handlers + +function authorize(req, res, next) { + if (!req.connection.ldap.bindDN.equals('cn=root')) + return next(new ldap.InsufficientAccessRightsError()); + + return next(); +} + + +function loadPasswdFile(req, res, next) { + fs.readFile('/etc/passwd', 'utf8', (err, data) => { + if (err) + return next(new ldap.OperationsError(err.message)); + + req.users = {}; + + const lines = data.split('\n'); + for (const line of lines) { + if (!line || /^#/.test(line)) + continue; + + const record = line.split(':'); + if (!record || !record.length) + continue; + + req.users[record[0]] = { + dn: 'cn=' + record[0] + ', ou=users, o=myhost', + attributes: { + cn: record[0], + uid: record[2], + gid: record[3], + description: record[4], + homedirectory: record[5], + shell: record[6] || '', + objectclass: 'unixUser' + } + }; + } + + return next(); + }); +} + + +const pre = [authorize, loadPasswdFile]; + + + +///--- Mainline + +const server = ldap.createServer(); + +server.bind('cn=root', (req, res, next) => { + if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret') + return next(new ldap.InvalidCredentialsError()); + + res.end(); + return next(); +}); + + +server.add('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].cn) + return next(new ldap.ConstraintViolationError('cn required')); + + if (req.users[req.dn.rdns[0].cn]) + return next(new ldap.EntryAlreadyExistsError(req.dn.toString())); + + const entry = req.toObject().attributes; + + if (entry.objectclass.indexOf('unixUser') === -1) + return next(new ldap.ConstraintViolationError('entry must be a unixUser')); + + const opts = ['-m']; + if (entry.description) { + opts.push('-c'); + opts.push(entry.description[0]); + } + if (entry.homedirectory) { + opts.push('-d'); + opts.push(entry.homedirectory[0]); + } + if (entry.gid) { + opts.push('-g'); + opts.push(entry.gid[0]); + } + if (entry.shell) { + opts.push('-s'); + opts.push(entry.shell[0]); + } + if (entry.uid) { + opts.push('-u'); + opts.push(entry.uid[0]); + } + opts.push(entry.cn[0]); + const useradd = spawn('useradd', opts); + + const messages = []; + + useradd.stdout.on('data', (data) => { + messages.push(data.toString()); + }); + useradd.stderr.on('data', (data) => { + messages.push(data.toString()); + }); + + useradd.on('exit', (code) => { + if (code !== 0) { + let msg = '' + code; + if (messages.length) + msg += ': ' + messages.join(); + return next(new ldap.OperationsError(msg)); + } + + res.end(); + return next(); + }); +}); + + +server.modify('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].cn || !req.users[req.dn.rdns[0].cn]) + return next(new ldap.NoSuchObjectError(req.dn.toString())); + + if (!req.changes.length) + return next(new ldap.ProtocolError('changes required')); + + const user = req.users[req.dn.rdns[0].cn].attributes; + let mod; + + for (const change of req.changes) { + mod = change.modification; + switch (change.operation) { + case 'replace': + if (mod.type !== 'userpassword' || !mod.vals || !mod.vals.length) + return next(new ldap.UnwillingToPerformError('only password updates ' + + 'allowed')); + break; + case 'add': + case 'delete': + return next(new ldap.UnwillingToPerformError('only replace allowed')); + } + } + + const passwd = spawn('chpasswd', ['-c', 'MD5']); + passwd.stdin.end(user.cn + ':' + mod.vals[0], 'utf8'); + + passwd.on('exit', (code) => { + if (code !== 0) + return next(new ldap.OperationsError('' + code)); + + res.end(); + return next(); + }); +}); + + +server.del('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].cn || !req.users[req.dn.rdns[0].cn]) + return next(new ldap.NoSuchObjectError(req.dn.toString())); + + const userdel = spawn('userdel', ['-f', req.dn.rdns[0].cn]); + + const messages = []; + userdel.stdout.on('data', (data) => { + messages.push(data.toString()); + }); + userdel.stderr.on('data', (data) => { + messages.push(data.toString()); + }); + + userdel.on('exit', (code) => { + if (code !== 0) { + let msg = '' + code; + if (messages.length) + msg += ': ' + messages.join(); + return next(new ldap.OperationsError(msg)); + } + + res.end(); + return next(); + }); +}); + + +server.search('o=myhost', pre, (req, res, next) => { + const keys = Object.keys(req.users); + for (const k of keys) { + if (req.filter.matches(req.users[k].attributes)) + res.send(req.users[k]); + } + + res.end(); + return next(); +}); + + + +// LDAP "standard" listens on 389, but whatever. +server.listen(1389, '127.0.0.1', () => { + console.log('/etc/passwd LDAP server up at: %s', server.url); +}); +``` + +# Address Book + +This example is courtesy of [Diogo Resende](https://github.com/dresende) and +illustrates setting up an address book for typical mail clients such as +Thunderbird or Evolution over a MySQL database. + +```js +// MySQL test: (create on database 'abook' with username 'abook' and password 'abook') +// +// CREATE TABLE IF NOT EXISTS `users` ( +// `id` int(5) unsigned NOT NULL AUTO_INCREMENT, +// `username` varchar(50) NOT NULL, +// `password` varchar(50) NOT NULL, +// PRIMARY KEY (`id`), +// KEY `username` (`username`) +// ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +// INSERT INTO `users` (`username`, `password`) VALUES +// ('demo', 'demo'); +// CREATE TABLE IF NOT EXISTS `contacts` ( +// `id` int(5) unsigned NOT NULL AUTO_INCREMENT, +// `user_id` int(5) unsigned NOT NULL, +// `name` varchar(100) NOT NULL, +// `email` varchar(255) NOT NULL, +// PRIMARY KEY (`id`), +// KEY `user_id` (`user_id`) +// ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +// INSERT INTO `contacts` (`user_id`, `name`, `email`) VALUES +// (1, 'John Doe', 'john.doe@example.com'), +// (1, 'Jane Doe', 'jane.doe@example.com'); +// + +const ldap = require('ldapjs'); +const mysql = require("mysql"); +const server = ldap.createServer(); +const addrbooks = {}; +const userinfo = {}; +const ldap_port = 389; +const basedn = "dc=example, dc=com"; +const company = "Example"; +const db = mysql.createClient({ + user: "abook", + password: "abook", + database: "abook" +}); + +db.query("SELECT c.*,u.username,u.password " + + "FROM contacts c JOIN users u ON c.user_id=u.id", + (err, contacts) => { + if (err) { + console.log("Error fetching contacts", err); + process.exit(1); + } + + for (const contact of contacts) { + if (!addrbooks.hasOwnProperty(contact.username)) { + addrbooks[contact.username] = []; + userinfo["cn=" + contact.username + ", " + basedn] = { + abook: addrbooks[contact.username], + pwd: contact.password + }; + } + + const p = contact.name.indexOf(" "); + if (p != -1) + contact.firstname = contact.name.substr(0, p); + + p = contact.name.lastIndexOf(" "); + if (p != -1) + contact.surname = contact.name.substr(p + 1); + + addrbooks[contact.username].push({ + dn: "cn=" + contact.name + ", " + basedn, + attributes: { + objectclass: [ "top" ], + cn: contact.name, + mail: contact.email, + givenname: contact.firstname, + sn: contact.surname, + ou: company + } + }); + } + + server.bind(basedn, (req, res, next) => { + const username = req.dn.toString(); + const password = req.credentials; + + if (!userinfo.hasOwnProperty(username) || + userinfo[username].pwd != password) { + return next(new ldap.InvalidCredentialsError()); + } + + res.end(); + return next(); + }); + + server.search(basedn, (req, res, next) => { + const binddn = req.connection.ldap.bindDN.toString(); + + if (userinfo.hasOwnProperty(binddn)) { + for (const abook of userinfo[binddn].abook) { + if (req.filter.matches(abook.attributes)) + res.send(abook); + } + } + res.end(); + }); + + server.listen(ldap_port, () => { + console.log("Addressbook started at %s", server.url); + }); +}); +``` + +To test out this example, try: + +```shell +$ ldapsearch -H ldap://localhost:389 -x -D cn=demo,dc=example,dc=com \ + -w demo -b "dc=example,dc=com" objectclass=* +``` + +# Multi-threaded Server + +This example demonstrates multi-threading via the `cluster` module utilizing a `net` server for initial socket receipt. An alternate example demonstrating use of the `connectionRouter` `serverOptions` hook is available in the `examples` directory. + +```js +const cluster = require('cluster'); +const ldap = require('ldapjs'); +const net = require('net'); +const os = require('os'); + +const threads = []; +threads.getNext = function () { + return (Math.floor(Math.random() * this.length)); +}; + +const serverOptions = { + port: 1389 +}; + +if (cluster.isMaster) { + const server = net.createServer(serverOptions, (socket) => { + socket.pause(); + console.log('ldapjs client requesting connection'); + let routeTo = threads.getNext(); + threads[routeTo].send({ type: 'connection' }, socket); + }); + + for (let i = 0; i < os.cpus().length; i++) { + let thread = cluster.fork({ + 'id': i + }); + thread.id = i; + thread.on('message', function (msg) { + + }); + threads.push(thread); + } + + server.listen(serverOptions.port, function () { + console.log('ldapjs listening at ldap://127.0.0.1:' + serverOptions.port); + }); +} else { + const server = ldap.createServer(serverOptions); + + let threadId = process.env.id; + + process.on('message', (msg, socket) => { + switch (msg.type) { + case 'connection': + server.newConnection(socket); + socket.resume(); + console.log('ldapjs client connection accepted on ' + threadId.toString()); + } + }); + + server.search('dc=example', function (req, res, next) { + console.log('ldapjs search initiated on ' + threadId.toString()); + var obj = { + dn: req.dn.toString(), + attributes: { + objectclass: ['organization', 'top'], + o: 'example' + } + }; + + if (req.filter.matches(obj.attributes)) + res.send(obj); + + res.end(); + }); +} +``` diff --git a/node_modules/ldapjs/docs/filters.md b/node_modules/ldapjs/docs/filters.md new file mode 100644 index 0000000..2413f80 --- /dev/null +++ b/node_modules/ldapjs/docs/filters.md @@ -0,0 +1,317 @@ +--- +title: Filters API | ldapjs +--- + +# ldapjs Filters API + +
+ +This document covers the ldapjs filters API and assumes that you are familiar +with LDAP. If you're not, read the [guide](guide.html) first. + +
+ +LDAP search filters are really the backbone of LDAP search operations, and +ldapjs tries to get you in "easy" with them if your dataset is small, and also +lets you introspect them if you want to write a "query planner". For reference, +make sure to read over [RFC2254](http://www.ietf.org/rfc/rfc2254.txt), as this +explains the LDAPv3 text filter representation. + +ldapjs gives you a distinct object type mapping to each filter that is +context-sensitive. However, _all_ filters have a `matches()` method on them, if +that's all you need. Most filters will have an `attribute` property on them, +since "simple" filters all operate on an attribute/value assertion. The +"complex" filters are really aggregations of other filters (i.e. 'and'), and so +these don't provide that property. + +All Filters in the ldapjs framework extend from `Filter`, which wil have the +property `type` available; this will return a string name for the filter, and +will be one of: + +# parseFilter(filterString) + +Parses an [RFC2254](http://www.ietf.org/rfc/rfc2254.txt) filter string into an +ldapjs object(s). If the filter is "complex", it will be a "tree" of objects. +For example: + +```js +const parseFilter = require('ldapjs').parseFilter; + +const f = parseFilter('(objectclass=*)'); +``` + +Is a "simple" filter, and would just return a `PresenceFilter` object. However, + +```js +const f = parseFilter('(&(employeeType=manager)(l=Seattle))'); +``` + +Would return an `AndFilter`, which would have a `filters` array of two +`EqualityFilter` objects. + +`parseFilter` will throw if an invalid string is passed in (that is, a +syntactically invalid string). + +# EqualityFilter + +The equality filter is used to check exact matching of attribute/value +assertions. This object will have an `attribute` and `value` property, and the +`name` property will be `equal`. + +The string syntax for an equality filter is `(attr=value)`. + +The `matches()` method will return true IFF the passed in object has a +key matching `attribute` and a value matching `value`. + +```js +const f = new EqualityFilter({ + attribute: 'cn', + value: 'foo' +}); + +f.matches({cn: 'foo'}); => true +f.matches({cn: 'bar'}); => false +``` + +Equality matching uses "strict" type JavaScript comparison, and by default +everything in ldapjs (and LDAP) is a UTF-8 string. If you want comparison +of numbers, or something else, you'll need to use a middleware interceptor +that transforms values of objects. + +# PresenceFilter + +The presence filter is used to check if an object has an attribute at all, with +any value. This object will have an `attribute` property, and the `name` +property will be `present`. + +The string syntax for a presence filter is `(attr=*)`. + +The `matches()` method will return true IFF the passed in object has a +key matching `attribute`. + +```js +const f = new PresenceFilter({ + attribute: 'cn' +}); + +f.matches({cn: 'foo'}); => true +f.matches({sn: 'foo'}); => false +``` + +# SubstringFilter + +The substring filter is used to do wildcard matching of a string value. This +object will have an `attribute` property and then it will have an `initial` +property, which is the prefix match, an `any` which will be an array of strings +that are to be found _somewhere_ in the target string, and a `final` property, +which will be the suffix match of the string. `any` and `final` are both +optional. The `name` property will be `substring`. + +The string syntax for a presence filter is `(attr=foo*bar*cat*dog)`, which would +map to: + +```js +{ + initial: 'foo', + any: ['bar', 'cat'], + final: 'dog' +} +``` + +The `matches()` method will return true IFF the passed in object has a +key matching `attribute` and the "regex" matches the value + +```js +const f = new SubstringFilter({ + attribute: 'cn', + initial: 'foo', + any: ['bar'], + final: 'baz' +}); + +f.matches({cn: 'foobigbardogbaz'}); => true +f.matches({sn: 'fobigbardogbaz'}); => false +``` + +# GreaterThanEqualsFilter + +The ge filter is used to do comparisons and ordering based on the value type. As +mentioned elsewhere, by default everything in LDAP and ldapjs is a string, so +this filter's `matches()` would be using lexicographical ordering of strings. +If you wanted `>=` semantics over numeric values, you would need to add some +middleware to convert values before comparison (and the value of the filter). +Note that the ldapjs schema middleware will do this. + +The GreaterThanEqualsFilter will have an `attribute` property, a `value` +property and the `name` property will be `ge`. + +The string syntax for a ge filter is: + +``` +(cn>=foo) +``` + +The `matches()` method will return true IFF the passed in object has a +key matching `attribute` and the value is `>=` this filter's `value`. + +```js +const f = new GreaterThanEqualsFilter({ + attribute: 'cn', + value: 'foo', +}); + +f.matches({cn: 'foobar'}); => true +f.matches({cn: 'abc'}); => false +``` + +# LessThanEqualsFilter + +The le filter is used to do comparisons and ordering based on the value type. As +mentioned elsewhere, by default everything in LDAP and ldapjs is a string, so +this filter's `matches()` would be using lexicographical ordering of strings. +If you wanted `<=` semantics over numeric values, you would need to add some +middleware to convert values before comparison (and the value of the filter). +Note that the ldapjs schema middleware will do this. + +The string syntax for a le filter is: + +``` +(cn<=foo) +``` + +The LessThanEqualsFilter will have an `attribute` property, a `value` +property and the `name` property will be `le`. + +The `matches()` method will return true IFF the passed in object has a +key matching `attribute` and the value is `<=` this filter's `value`. + +```js +const f = new LessThanEqualsFilter({ + attribute: 'cn', + value: 'foo', +}); + +f.matches({cn: 'abc'}); => true +f.matches({cn: 'foobar'}); => false +``` + +# AndFilter + +The and filter is a complex filter that simply contains "child" filters. The +object will have a `filters` property which is an array of `Filter` objects. The +`name` property will be `and`. + +The string syntax for an and filter is (assuming below we're and'ing two +equality filters): + +``` +(&(cn=foo)(sn=bar)) +``` + +The `matches()` method will return true IFF the passed in object matches all +the filters in the `filters` array. + +```js +const f = new AndFilter({ + filters: [ + new EqualityFilter({ + attribute: 'cn', + value: 'foo' + }), + new EqualityFilter({ + attribute: 'sn', + value: 'bar' + }) + ] +}); + +f.matches({cn: 'foo', sn: 'bar'}); => true +f.matches({cn: 'foo', sn: 'baz'}); => false +``` + +# OrFilter + +The or filter is a complex filter that simply contains "child" filters. The +object will have a `filters` property which is an array of `Filter` objects. The +`name` property will be `or`. + +The string syntax for an or filter is (assuming below we're or'ing two +equality filters): + +``` +(|(cn=foo)(sn=bar)) +``` + +The `matches()` method will return true IFF the passed in object matches *any* +of the filters in the `filters` array. + +```js +const f = new OrFilter({ + filters: [ + new EqualityFilter({ + attribute: 'cn', + value: 'foo' + }), + new EqualityFilter({ + attribute: 'sn', + value: 'bar' + }) + ] +}); + +f.matches({cn: 'foo', sn: 'baz'}); => true +f.matches({cn: 'bar', sn: 'baz'}); => false +``` + +# NotFilter + +The not filter is a complex filter that contains a single "child" filter. The +object will have a `filter` property which is an instance of a `Filter` object. +The `name` property will be `not`. + +The string syntax for a not filter is (assuming below we're not'ing an +equality filter): + +``` +(!(cn=foo)) +``` + +The `matches()` method will return true IFF the passed in object does not match +the filter in the `filter` property. + +```js +const f = new NotFilter({ + filter: new EqualityFilter({ + attribute: 'cn', + value: 'foo' + }) +}); + +f.matches({cn: 'bar'}); => true +f.matches({cn: 'foo'}); => false +``` + +# ApproximateFilter + +The approximate filter is used to check "approximate" matching of +attribute/value assertions. This object will have an `attribute` and +`value` property, and the `name` property will be `approx`. + +As a side point, this is a useless filter. It's really only here if you have +some whacky client that's sending this. It just does an exact match (which +is what ActiveDirectory does too). + +The string syntax for an equality filter is `(attr~=value)`. + +The `matches()` method will return true IFF the passed in object has a +key matching `attribute` and a value exactly matching `value`. + +```js +const f = new ApproximateFilter({ + attribute: 'cn', + value: 'foo' +}); + +f.matches({cn: 'foo'}); => true +f.matches({cn: 'bar'}); => false +``` diff --git a/node_modules/ldapjs/docs/guide.md b/node_modules/ldapjs/docs/guide.md new file mode 100644 index 0000000..0115336 --- /dev/null +++ b/node_modules/ldapjs/docs/guide.md @@ -0,0 +1,697 @@ +--- +title: LDAP Guide | ldapjs +--- + +# LDAP Guide + +
+ +This guide was written assuming that you (1) don't know anything about ldapjs, +and perhaps more importantly (2) know little, if anything about LDAP. If you're +already an LDAP whiz, please don't read this and feel it's condescending. Most +people don't know how LDAP works, other than that "it's that thing that has my +password." + +By the end of this guide, we'll have a simple LDAP server that accomplishes a +"real" task. + +
+ +# What exactly is LDAP? + +If you haven't already read the +[wikipedia](http://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) +entry (which you should go do right now), LDAP is the "Lightweight Directory +Access Protocol". A directory service basically breaks down as follows: + +* A directory is a tree of entries (similar to but different than an FS). +* Every entry has a unique name in the tree. +* An entry is a set of attributes. +* An attribute is a key/value(s) pairing (multivalue is natural). + +It might be helpful to visualize: + +``` + o=example + / \ + ou=users ou=groups + / | | \ + cn=john cn=jane cn=dudes cn=dudettes + / +keyid=foo +``` + +Let's say we wanted to look at the record cn=john: + +```shell +dn: cn=john, ou=users, o=example +cn: john +sn: smith +email: john@example.com +email: john.smith@example.com +objectClass: person +``` + +A few things to note: + +* All names in a directory tree are actually referred to as a _distinguished +name_, or _dn_ for short. A dn is comprised of attributes that lead to that +node in the tree, as shown above (the syntax is foo=bar, ...). +* The root of the tree is at the right of the _dn_, which is inverted from a +filesystem hierarchy. +* Every entry in the tree is an _instance of_ an _objectclass_. +* An _objectclass_ is a schema concept; think of it like a table in a +traditional ORM. +* An _objectclass_ defines what _attributes_ an entry can have (on the ORM +analogy, an _attribute_ would be like a column). + +That's it. LDAP, then, is the protocol for interacting with the directory tree, +and it's comprehensively specified for common operations, like +add/update/delete and importantly, search. Really, the power of LDAP comes +through the search operations defined in the protocol, which are richer +than HTTP query string filtering, but less powerful than full SQL. You can +think of LDAP as a NoSQL/document store with a well-defined query syntax. + +So, why isn't LDAP more popular for a lot of applications? Like anything else +that has "simple" or "lightweight" in the name, it's not really that +lightweight. In particular, almost all of the implementations of LDAP stem +from the original University of Michigan codebase written in 1996. At that +time, the original intention of LDAP was to be an IP-accessible gateway to the +much more complex X.500 directories, which means that a lot of that +baggage has carried through to today. That makes for a high barrier to entry, +when most applications just don't need most of those features. + +## How is ldapjs any different? + +Well, on the one hand, since ldapjs has to be 100% wire compatible with LDAP to +be useful, it's not. On the other hand, there are no forced assumptions about +what you need and don't need for your use of a directory system. For example, +want to run with no-schema in OpenLDAP/389DS/et al? Good luck. Most of the +server implementations support arbitrary "backends" for persistence, but really +you'll be using [BDB](http://www.oracle.com/technetwork/database/berkeleydb/overview/index.html). + +Want to run schema-less in ldapjs, or wire it up with some mongoose models? No +problem. Want to back it to redis? Should be able to get some basics up in a +day or two. + +Basically, the ldapjs philosophy is to deal with the "muck" of LDAP, and then +get out of the way so you can just use the "good parts." + +# Ok, cool. Learn me some LDAP! + +With the initial fluff out of the way, let's do something crazy to teach +you some LDAP. Let's put an LDAP server up over the top of your (Linux) host's +/etc/passwd and /etc/group files. Usually sysadmins "go the other way," and +replace /etc/passwd with a +[PAM](http://en.wikipedia.org/wiki/Pluggable_authentication_module "Pluggable +authentication module") module to LDAP. While this is probably not a super +useful real-world use case, it will teach you some of the basics. If it is +useful to you, then that's gravy. + +## Install + +If you don't already have node.js and npm, clearly you need those, so follow +the steps at [nodejs.org](http://nodejs.org) and [npmjs.org](http://npmjs.org), +respectively. After that, run: + +```shell +$ npm install ldapjs +``` + +Rather than overload you with client-side programming for now, we'll use +the OpenLDAP CLI to interact with our server. It's almost certainly already +installed on your system, but if not, you can get it from brew/apt/yum/your +package manager here. + +To get started, open some file, and let's get the library loaded and a server +created: + +```js +const ldap = require('ldapjs'); + +const server = ldap.createServer(); + +server.listen(1389, () => { + console.log('/etc/passwd LDAP server up at: %s', server.url); +}); +``` + +And run that. Doing anything will give you errors (LDAP "No Such Object") +since we haven't added any support in yet, but go ahead and try it anyway: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -b "o=myhost" objectclass=* +``` + +Before we go any further, note that the complete code for the server we are +about to build up is on the [examples](examples.html) page. + +## Bind + +So, lesson #1 about LDAP: unlike HTTP, it's connection-oriented; that means that +you authenticate (in LDAP nomenclature this is called a _bind_), and all +subsequent operations operate at the level of priviledge you established during +a bind. You can bind any number of times on a single connection and change that +identity. Technically, it's optional, and you can support _anonymous_ +operations from clients, but (1) you probably don't want that, and (2) most +LDAP clients will initiate a bind anyway (OpenLDAP will), so let's add it in +and get it out of our way. + +What we're going to do is add a "root" user to our LDAP server. This root user +has no correspondence to our Unix root user, it's just something we're making up +and going to use for allowing an (LDAP) admin to do anything. To do so, add +this code into your file: + +```js +server.bind('cn=root', (req, res, next) => { + if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret') + return next(new ldap.InvalidCredentialsError()); + + res.end(); + return next(); +}); +``` + +Not very secure, but this is a demo. What we did there was "mount" a tree in +the ldapjs server, and add a handler for the _bind_ method. If you've ever used +express, this pattern should be really familiar; you can add any number of +handlers in, as we'll see later. + +On to the meat of the method. What's up with this? + +```js +if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret') +``` + +The first part `req.dn.toString() !== 'cn=root'`: you're probably thinking +"WTF?!? Does ldapjs allow something other than cn=root into this handler?" Sort +of. It allows cn=root *and any children* into that handler. So the entries +`cn=root` and `cn=evil, cn=root` would both match and flow into this handler. +Hence that check. The second check `req.credentials` is probably obvious, but +it brings up an important point, and that is the `req`, `res` objects in ldapjs +are not homogenous across server operation types. Unlike HTTP, there's not a +single message format, so each of the operations has fields and functions +appropriate to that type. The LDAP bind operation has `credentials`, which are +a string representation of the client's password. This is logically the same as +HTTP Basic Authentication (there are other mechanisms, but that's out of scope +for a getting started guide). Ok, if either of those checks failed, we pass a +new ldapjs `Error` back into the server, and it will (1) halt the chain, and (2) +send the proper error code back to the client. + +Lastly, assuming that this request was ok, we just end the operation with +`res.end()`. The `return next()` isn't strictly necessary, since here we only +have one handler in the chain, but it's good habit to always do that, so if you +add another handler in later you won't get bit by it not being invoked. + +Blah blah, let's try running the ldap client again, first with a bad password: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w foo -b "o=myhost" objectclass=* + +ldap_bind: Invalid credentials (49) + matched DN: cn=root + additional info: Invalid Credentials +``` + +And again with the correct one: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w secret -LLL -b "o=myhost" objectclass=* + +No such object (32) +Additional information: No tree found for: o=myhost +``` + +Don't worry about all the flags we're passing into OpenLDAP, that's just to make +their CLI less annonyingly noisy. This time, we got another `No such object` +error, but it's for the tree `o=myhost`. That means our bind went through, and +our search failed, since we haven't yet added a search handler. Just one more +small thing to do first. + +Remember earlier I said there were no authorization rules baked into LDAP? Well, +we added a bind route, so the only user that can authenticate is `cn=root`, but +what if the remote end doesn't authenticate at all? Right, nothing says they +*have to* bind, that's just what the common clients do. Let's add a quick +authorization handler that we'll use in all our subsequent routes: + +```js +function authorize(req, res, next) { + if (!req.connection.ldap.bindDN.equals('cn=root')) + return next(new ldap.InsufficientAccessRightsError()); + + return next(); +} +``` + +Should be pretty self-explanatory, but as a reminder, LDAP is connection +oriented, so we check that the connection remote user was indeed our `cn=root` +(by default ldapjs will have a DN of `cn=anonymous` if the client didn't bind). + +## Search + +We said we wanted to allow LDAP operations over /etc/passwd, so let's detour +for a moment to explain an /etc/passwd record. + +```shell +jsmith:x:1001:1000:Joe Smith,Room 1007,(234)555-8910,(234)555-0044,email:/home/jsmith:/bin/sh +``` + +The sample record above maps to: + +|Field |Description | +|-------------------|-----------------------------------| +|jsmith |Username | +|x |Placeholder for password hash | +|1001 |Numeric UID | +|1000 |Numeric Primary GID | +|'Joe Smith,...' |DisplayName | +|/home/jsmith |Home directory | +|/bin/sh |Shell | + +Let's write some handlers to parse that and transform it into an LDAP search +record (note, you'll need to add `const fs = require('fs');` at the top of the +source file). + +First, make a handler that just loads the "user database" in a "pre" handler: + +```js +function loadPasswdFile(req, res, next) { + fs.readFile('/etc/passwd', 'utf8', (err, data) => { + if (err) + return next(new ldap.OperationsError(err.message)); + + req.users = {}; + + const lines = data.split('\n'); + for (const line of lines) { + if (!line || /^#/.test(line)) + continue; + + const record = line.split(':'); + if (!record || !record.length) + continue; + + req.users[record[0]] = { + dn: 'cn=' + record[0] + ', ou=users, o=myhost', + attributes: { + cn: record[0], + uid: record[2], + gid: record[3], + description: record[4], + homedirectory: record[5], + shell: record[6] || '', + objectclass: 'unixUser' + } + }; + } + + return next(); + }); +} +``` + +Ok, all that did is tack the /etc/passwd records onto req.users so that any +subsequent handler doesn't have to reload the file. Next, let's write a search +handler to process that: + +```js +const pre = [authorize, loadPasswdFile]; + +server.search('o=myhost', pre, (req, res, next) => { + const keys = Object.keys(req.users); + for (const k of keys) { + if (req.filter.matches(req.users[k].attributes)) + res.send(req.users[k]); + } + + res.end(); + return next(); +}); +``` + +And try running: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w secret -LLL -b "o=myhost" cn=root +dn: cn=root, ou=users, o=myhost +cn: root +uid: 0 +gid: 0 +description: System Administrator +homedirectory: /var/root +shell: /bin/sh +objectclass: unixUser +``` + +Sweet! Try this out too: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w secret -LLL -b "o=myhost" objectclass=* +... +``` + +You should have seen an entry for every record in /etc/passwd with the second. +What all did we do here? A lot. Let's break this down... + +### What did I just do on the command line? + +Let's start with looking at what you even asked for: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w secret -LLL -b "o=myhost" cn=root +``` + +We can throw away `ldapsearch -H -x -D -w -LLL`, as those just specify the URL +to connect to, the bind credentials and the `-LLL` just quiets down OpenLDAP. +That leaves us with: `-b "o=myhost" cn=root`. + +The `-b o=myhost` tells our LDAP server where to _start_ looking in +the tree for entries that might match the search filter, which above is +`cn=root`. + +In this little LDAP example, we're mostly throwing out any qualification of the +"tree," since there's not actually a tree in /etc/passwd (we will extend later +with /etc/group). Remember how I said ldapjs gets out of the way and doesn't +force anything on you? Here's an example. If we wanted an LDAP server to run +over the filesystem, we actually would use this, but here, meh. + +Next, `cn=root` is the search "filter". LDAP has a rich specification of +filters, where you can specify `and`, `or`, `not`, `>=`, `<=`, `equal`, +`wildcard`, `present` and a few other esoteric things. Really, `equal`, +`wildcard`, `present` and the boolean operators are all you'll likely ever need. +So, the filter `cn=root` is an "equality" filter, and says to only return +entries that have attributes that match that. In the second invocation, we used +a 'presence' filter, to say 'return any entries that have an objectclass' +attribute, which in LDAP parlance is saying "give me everything." + +### The code + +In the code above, let's ignore the fs and split stuff, since really all we +did was read in /etc/passwd line by line. After that, we looked at each record +and made the cheesiest transform ever, which is making up a "search entry." A +search entry _must_ have a DN so the client knows what record it is, and a set +of attributes. So that's why we did this: + +```js +const entry = { + dn: 'cn=' + record[0] + ', ou=users, o=myhost', + attributes: { + cn: record[0], + uid: record[2], + gid: record[3], + description: record[4], + homedirectory: record[5], + shell: record[6] || '', + objectclass: 'unixUser' + } +}; +``` + +Next, we let ldapjs do all the hard work of figuring out LDAP search filters +for us by calling `req.filter.matches`. If it matched, we return the whole +record with `res.send`. In this little example we're running O(n), so for +something big and/or slow, you'd have to do some work to effectively write a +query planner (or just not support it...). For some reference code, check out +`node-ldapjs-riak`, which takes on the fairly difficult task of writing a 'full' +LDAP server over riak. + +To demonstrate what ldapjs is doing for you, let's find all users who have a +shell set to `/bin/false` and whose name starts with `p` (I'm doing this +on Ubuntu). Then, let's say we only care about their login name and primary +group id. We'd do this: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -D cn=root -w secret -LLL -b "o=myhost" "(&(shell=/bin/false)(cn=p*))" cn gid +dn: cn=proxy, ou=users, o=myhost +cn: proxy +gid: 13 + +dn: cn=pulse, ou=users, o=myhost +cn: pulse +gid: 114 +``` + +## Add + +This is going to be a little bit ghetto, since what we're going to do is just +use node's child process module to spawn calls to `adduser`. Go ahead and add +the following code in as another handler (you'll need a +`const { spawn } = require('child_process');` at the top of your file): + +```js +server.add('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].attrs.cn) + return next(new ldap.ConstraintViolationError('cn required')); + + if (req.users[req.dn.rdns[0].attrs.cn.value]) + return next(new ldap.EntryAlreadyExistsError(req.dn.toString())); + + const entry = req.toObject().attributes; + + if (entry.objectclass.indexOf('unixUser') === -1) + return next(new ldap.ConstraintViolationError('entry must be a unixUser')); + + const opts = ['-m']; + if (entry.description) { + opts.push('-c'); + opts.push(entry.description[0]); + } + if (entry.homedirectory) { + opts.push('-d'); + opts.push(entry.homedirectory[0]); + } + if (entry.gid) { + opts.push('-g'); + opts.push(entry.gid[0]); + } + if (entry.shell) { + opts.push('-s'); + opts.push(entry.shell[0]); + } + if (entry.uid) { + opts.push('-u'); + opts.push(entry.uid[0]); + } + opts.push(entry.cn[0]); + const useradd = spawn('useradd', opts); + + const messages = []; + + useradd.stdout.on('data', (data) => { + messages.push(data.toString()); + }); + useradd.stderr.on('data', (data) => { + messages.push(data.toString()); + }); + + useradd.on('exit', (code) => { + if (code !== 0) { + let msg = '' + code; + if (messages.length) + msg += ': ' + messages.join(); + return next(new ldap.OperationsError(msg)); + } + + res.end(); + return next(); + }); +}); +``` + +Then, you'll need to be root to have this running, so start your server with +`sudo` (or be root, whatever). Now, go ahead and create a file called +`user.ldif` with the following contents: + +```shell +dn: cn=ldapjs, ou=users, o=myhost +objectClass: unixUser +cn: ldapjs +shell: /bin/bash +description: Created via ldapadd +``` + +Now go ahead and invoke with: + +```shell +$ ldapadd -H ldap://localhost:1389 -x -D cn=root -w secret -f ./user.ldif +adding new entry "cn=ldapjs, ou=users, o=myhost" +``` + +Let's confirm he got added with an ldapsearch: + +```shell +$ ldapsearch -H ldap://localhost:1389 -LLL -x -D cn=root -w secret -b "ou=users, o=myhost" cn=ldapjs +dn: cn=ldapjs, ou=users, o=myhost +cn: ldapjs +uid: 1001 +gid: 1001 +description: Created via ldapadd +homedirectory: /home/ldapjs +shell: /bin/bash +objectclass: unixUser +``` + +As before, here's a breakdown of the code: + +```js +server.add('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].attrs.cn) + return next(new ldap.ConstraintViolationError('cn required')); + + if (req.users[req.dn.rdns[0].attrs.cn.value]) + return next(new ldap.EntryAlreadyExistsError(req.dn.toString())); + + const entry = req.toObject().attributes; + + if (entry.objectclass.indexOf('unixUser') === -1) + return next(new ldap.ConstraintViolationError('entry must be a unixUser')); +}); +``` + +A few new things: + +* We mounted this handler at `ou=users, o=myhost`. Why? What if we want to +extend this little project with groups? We probably want those under a +different part of the tree. +* We did some really minimal schema enforcement by: + + Checking that the leaf RDN (relative distinguished name) was a _cn_ +attribute. + + We then did `req.toObject()`. As mentioned before, each of the req/res +objects have special APIs that make sense for that operation. Without getting +into the details, the LDAP add operation on the wire doesn't look like a JS +object, and we want to support both the LDAP nerd that wants to see what +got sent, and the "easy" case. So use `.toObject()`. Note we also filtered +out to the `attributes` portion of the object since that's all we're really +looking at. + + Lastly, we did a super minimal check to see if the entry was of type +`unixUser`. Frankly for this case, it's kind of useless, but it does illustrate +one point: attribute names are case-insensitive, so ldapjs converts them all to +lower case (note the client sent _objectClass_ over the wire). + +After that, we really just delegated off to the _useradd_ command. As far as I +know, there is not a node.js module that wraps up `getpwent` and friends, +otherwise we'd use that. + +Now, what's missing? Oh, right, we need to let you set a password. Well, let's +support that via the _modify_ command. + +## Modify + +Unlike HTTP, "partial" document updates are fully specified as part of the +RFC, so appending, removing, or replacing a single attribute is pretty natural. +Go ahead and add the following code into your source file: + +```js +server.modify('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].attrs.cn || !req.users[req.dn.rdns[0].attrs.cn.value]) + return next(new ldap.NoSuchObjectError(req.dn.toString())); + + if (!req.changes.length) + return next(new ldap.ProtocolError('changes required')); + + const user = req.users[req.dn.rdns[0].attrs.cn.value].attributes; + let mod; + + for (const i = 0; i < req.changes.length; i++) { + mod = req.changes[i].modification; + switch (req.changes[i].operation) { + case 'replace': + if (mod.type !== 'userpassword' || !mod.vals || !mod.vals.length) + return next(new ldap.UnwillingToPerformError('only password updates ' + + 'allowed')); + break; + case 'add': + case 'delete': + return next(new ldap.UnwillingToPerformError('only replace allowed')); + } + } + + const passwd = spawn('chpasswd', ['-c', 'MD5']); + passwd.stdin.end(user.cn + ':' + mod.vals[0], 'utf8'); + + passwd.on('exit', (code) => { + if (code !== 0) + return next(new ldap.OperationsError(code)); + + res.end(); + return next(); + }); +}); +``` + +Basically, we made sure the remote client was targeting an entry that exists, +ensuring that they were asking to "replace" the `userPassword` attribute (which +is the 'standard' LDAP attribute for passwords; if you think it's easier to use +'password', knock yourself out), and then just delegating to the `chpasswd` +command (which lets you change a user's password over stdin). Next, go ahead +and create a `passwd.ldif` file: + +```shell +dn: cn=ldapjs, ou=users, o=myhost +changetype: modify +replace: userPassword +userPassword: secret +- +``` + +And then run the OpenLDAP CLI: + +```shell +$ ldapmodify -H ldap://localhost:1389 -x -D cn=root -w secret -f ./passwd.ldif +``` + +You should now be able to login to your box as the ldapjs user. Let's get +the last "mainline" piece of work out of the way, and delete the user. + +## Delete + +Delete is pretty straightforward. The client gives you a dn to delete, and you +delete it :). Add the following code into your server: + +```js +server.del('ou=users, o=myhost', pre, (req, res, next) => { + if (!req.dn.rdns[0].attrs.cn || !req.users[req.dn.rdns[0].attrs.cn.value]) + return next(new ldap.NoSuchObjectError(req.dn.toString())); + + const userdel = spawn('userdel', ['-f', req.dn.rdns[0].attrs.cn.value]); + + const messages = []; + userdel.stdout.on('data', (data) => { + messages.push(data.toString()); + }); + userdel.stderr.on('data', (data) => { + messages.push(data.toString()); + }); + + userdel.on('exit', (code) => { + if (code !== 0) { + let msg = '' + code; + if (messages.length) + msg += ': ' + messages.join(); + return next(new ldap.OperationsError(msg)); + } + + res.end(); + return next(); + }); +}); +``` + +And then run the following command: + +```shell +$ ldapdelete -H ldap://localhost:1389 -x -D cn=root -w secret "cn=ldapjs, ou=users, o=myhost" +``` + +# Where to go from here + +The complete source code for this example server is available in +[examples](examples.html). Make sure to read up on the [server](server.html) +and [client](client.html) APIs. If you're looking for a "drop in" solution, +take a look at [ldapjs-riak](https://github.com/mcavage/node-ldapjs-riak). + +[Mozilla](https://wiki.mozilla.org/Mozilla_LDAP_SDK_Programmer%27s_Guide/Understanding_LDAP) +still maintains some web pages with LDAP overviews if you look around, if you're +looking for more tutorials. After that, you'll need to work your way through +the [RFCs](http://tools.ietf.org/html/rfc4510) as you work through the APIs in +ldapjs. diff --git a/node_modules/ldapjs/docs/index.md b/node_modules/ldapjs/docs/index.md new file mode 100644 index 0000000..c6a26c3 --- /dev/null +++ b/node_modules/ldapjs/docs/index.md @@ -0,0 +1,95 @@ +--- +title: ldapjs +--- + +
+Reimagining LDAP for Node.js +
+ +# Overview + +
+ +ldapjs is a pure JavaScript, from-scratch framework for implementing +[LDAP](http://tools.ietf.org/html/rfc4510) clients and servers in +[Node.js](http://nodejs.org). It is intended for developers used to interacting +with HTTP services in node and [restify](http://restify.com). + +
+ +```js +const ldap = require('ldapjs'); + +const server = ldap.createServer(); + +server.search('o=example', (req, res, next) => { + const obj = { + dn: req.dn.toString(), + attributes: { + objectclass: ['organization', 'top'], + o: 'example' + } + }; + + if (req.filter.matches(obj.attributes)) + res.send(obj); + + res.end(); +}); + +server.listen(1389, () => { + console.log('LDAP server listening at %s', server.url); +}); +``` + +Try hitting that with: + +```shell +$ ldapsearch -H ldap://localhost:1389 -x -b o=example objectclass=* +``` + +# Features + +ldapjs implements most of the common operations in the LDAP v3 RFC(s), for +both client and server. It is 100% wire-compatible with the LDAP protocol +itself, and is interoperable with [OpenLDAP](http://openldap.org) and any other +LDAPv3-compliant implementation. ldapjs gives you a powerful routing and +"intercepting filter" pattern for implementing server(s). It is intended +that you can build LDAP over anything you want, not just traditional databases. + +# Getting started + +```shell +$ npm install ldapjs +``` + +If you're new to LDAP, check out the [guide](guide.html). Otherwise, the +API documentation is: + + +|Section |Content | +|---------------------------|-------------------------------------------| +|[Server API](server.html) |Reference for implementing LDAP servers. | +|[Client API](client.html) |Reference for implementing LDAP clients. | +|[DN API](dn.html) |API reference for the DN class. | +|[Filter API](filters.html) |API reference for LDAP search filters. | +|[Error API](errors.html) |Listing of all ldapjs Error objects. | +|[Examples](examples.html) |Collection of sample/getting started code. | + +# More information + +- License:[MIT](http://opensource.org/licenses/mit-license.php) +- Code: [ldapjs/node-ldapjs](https://github.com/ldapjs/node-ldapjs) + +# What's not in the box? + +Since most developers and system(s) adminstrators struggle with some of the +esoteric features of LDAP, not all features in LDAP are implemented here. +Specifically: + +* LDIF +* Aliases +* Attributes by OID +* Extensible matching + +There are a few others, but those are the "big" ones. diff --git a/node_modules/ldapjs/docs/server.md b/node_modules/ldapjs/docs/server.md new file mode 100644 index 0000000..9366cf0 --- /dev/null +++ b/node_modules/ldapjs/docs/server.md @@ -0,0 +1,614 @@ +--- +title: Server API | ldapjs +--- + +# ldapjs Server API + +
+ +This document covers the ldapjs server API and assumes that you are familiar +with LDAP. If you're not, read the [guide](guide.html) first. + +
+ +# Create a server + +The code to create a new server looks like: + +```js +const server = ldap.createServer(); +``` + +The full list of options is: + +||log||You can optionally pass in a Bunyan compatible logger instance the client will use to acquire a child logger.|| +||certificate||A PEM-encoded X.509 certificate; will cause this server to run in TLS mode.|| +||key||A PEM-encoded private key that corresponds to _certificate_ for SSL.|| + +### Note On Logger + +The passed in logger is expected to conform to the Log4j standard API. +Internally, [abstract-logging](https://www.npmjs.com/packages/abstract-logging) is +used to implement the interface. As a result, no log messages will be generated +unless an external logger is supplied. + +Known compatible loggers are: + ++ [Bunyan](https://www.npmjs.com/package/bunyan) ++ [Pino](https://www.npmjs.com/package/pino) + +## Properties on the server object + +### maxConnections + +Set this property to reject connections when the server's connection count gets +high. + +### connections (getter only) - DEPRECATED + +The number of concurrent connections on the server. This property is deprecated, +please use server.getConnections() instead. + +### url + +Returns the fully qualified URL this server is listening on. For example: +`ldaps://10.1.2.3:1636`. If you haven't yet called `listen`, it will always +return `ldap://localhost:389`. + +### Event: 'close' +`function() {}` + +Emitted when the server closes. + +## Listening for requests + +The LDAP server API wraps up and mirrors the node.js `server.listen` family of +APIs. + +After calling `listen`, the property `url` on the server object itself will be +available. + +Example: + +```js + server.listen(389, '127.0.0.1', function() { + console.log('LDAP server listening at: ' + server.url); + }); +``` + +### Port and Host +`listen(port, [host], [callback])` + +Begin accepting connections on the specified port and host. If the host is +omitted, the server will accept connections directed to the IPv4 address +`127.0.0.1`. To listen on any other address, supply said address as the `host` +parameter. For example, to listen on all available IPv6 addresses supply +`::` as the `host` (note, this _may_ also result in listening on all +available IPv4 addresses, depending on operating system behavior). + +We highly recommend being as explicit as possible with the `host` parameter. +Listening on all available addresses (through `::` or `0.0.0.0`) can lead +to potential security issues. + +This function is asynchronous. The last parameter callback will be called when +the server has been bound. + +### Unix Domain Socket +`listen(path, [callback])` + +Start a UNIX socket server listening for connections on the given path. + +This function is asynchronous. The last parameter callback will be called when +the server has been bound. + +### File descriptor +`listenFD(fd)` + +Start a server listening for connections on the given file descriptor. + +This file descriptor must have already had the `bind(2)` and `listen(2)` system +calls invoked on it. Additionally, it must be set non-blocking; try +`fcntl(fd, F_SETFL, O_NONBLOCK)`. + +## Inspecting server state + +### server.getConnections(callback) + +The LDAP server API mirrors the [Node.js `server.getConnections` API](https://nodejs.org/dist/latest-v12.x/docs/api/net.html#net_server_getconnections_callback). Callback +should take two arguments err and count. + +# Routes + +The LDAP server API is meant to be the LDAP-equivalent of the express/restify +paradigm of programming. Essentially every method is of the form +`OP(req, res, next)` where OP is one of bind, add, del, etc. You can chain +handlers together by calling `next()` and ordering your functions in the +definition of the route. For example: + +```js +function authorize(req, res, next) { + if (!req.connection.ldap.bindDN.equals('cn=root')) + return next(new ldap.InsufficientAccessRightsError()); + + return next(); +} + +server.search('o=example', authorize, function(req, res, next) { ... }); +``` + +Note that ldapjs is also slightly different, since it's often going to be backed +to a DB-like entity, in that it also has an API where you can pass in a +'backend' object. This is necessary if there are persistent connection pools, +caching, etc. that need to be placed in an object. + +For example [ldapjs-riak](https://github.com/mcavage/node-ldapjs-riak) is a +complete implementation of the LDAP protocol over +[Riak](https://github.com/basho/riak). Getting an LDAP server up with riak +looks like: + +```js +const ldap = require('ldapjs'); +const ldapRiak = require('ldapjs-riak'); + +const server = ldap.createServer(); +const backend = ldapRiak.createBackend({ + "host": "localhost", + "port": 8098, + "bucket": "example", + "indexes": ["l", "cn"], + "uniqueIndexes": ["uid"], + "numConnections": 5 +}); + +server.add("o=example", + backend, + backend.add()); +... +``` + +The first parameter to an ldapjs route is always the point in the +tree to mount the handler chain at. The second argument is _optionally_ a +backend object. After that you can pass in an arbitrary combination of +functions in the form `f(req, res, next)` or arrays of functions of the same +signature (ldapjs will unroll them). + +Unlike HTTP, LDAP operations do not have a heterogeneous wire format, so each +operation requires specific methods/fields on the request/response +objects. However, there is a `.use()` method availabe, similar to +that on express/connect, allowing you to chain up "middleware": + +```js +server.use(function(req, res, next) { + console.log('hello world'); + return next(); +}); +``` + +## Common Request Elements + +All request objects have the `dn` getter on it, which is "context-sensitive" +and returns the point in the tree that the operation wants to operate on. The +LDAP protocol itself sadly doesn't define operations this way, and has a unique +name for just about every op. So, ldapjs calls it `dn`. The DN object itself +is documented at [DN](dn.html). + +All requests have an optional array of `Control` objects. `Control` will have +the properties `type` (string), `criticality` (boolean), and optionally, a +string `value`. + +All request objects will have a `connection` object, which is the `net.Socket` +associated to this request. Off the `connection` object is an `ldap` object. +The most important property to pay attention to is the `bindDN` property +which will be an instance of an `ldap.DN` object. This is what the client +authenticated as on this connection. If the client didn't bind, then a DN object +will be there defaulted to `cn=anonymous`. + +Additionally, request will have a `logId` parameter you can use to uniquely +identify the request/connection pair in logs (includes the LDAP messageId). + +## Common Response Elements + +All response objects will have an `end` method on them. By default, calling +`res.end()` with no arguments will return SUCCESS (0x00) to the client +(with the exception of `compare` which will return COMPARE\_TRUE (0x06)). You +can pass in a status code to the `end()` method to return an alternate status +code. + +However, it's more common/easier to use the `return next(new LDAPError())` +pattern, since ldapjs will fill in the extra LDAPResult fields like matchedDN +and error message for you. + +## Errors + +ldapjs includes an exception hierarchy that directly corresponds to the RFC list +of error codes. The complete list is documented in [errors](errors.html). But +the paradigm is something defined like CONSTRAINT\_VIOLATION in the RFC would be +`ConstraintViolationError` in ldapjs. Upon calling `next(new LDAPError())`, +ldapjs will _stop_ calling your handler chain. For example: + +```js +server.search('o=example', + (req, res, next) => { return next(); }, + (req, res, next) => { return next(new ldap.OperationsError()); }, + (req, res, next) => { res.end(); } +); +``` + +In the code snipped above, the third handler would never get invoked. + +# Bind + +Adds a mount in the tree to perform LDAP binds with. Example: + +```js +server.bind('ou=people, o=example', (req, res, next) => { + console.log('bind DN: ' + req.dn.toString()); + console.log('bind PW: ' + req.credentials); + res.end(); +}); +``` + +## BindRequest + +BindRequest objects have the following properties: + +### version + +The LDAP protocol version the client is requesting to run this connection on. +Note that ldapjs only supports LDAP version 3. + +### name + +The DN the client is attempting to bind as (note this is the same as the `dn` +property). + +### authentication + +The method of authentication. Right now only `simple` is supported. + +### credentials + +The credentials to go with the `name/authentication` pair. For `simple`, this +will be the plain-text password. + +## BindResponse + +No extra methods above an `LDAPResult` API call. + +# Add + +Adds a mount in the tree to perform LDAP adds with. + +```js +server.add('ou=people, o=example', (req, res, next) => { + console.log('DN: ' + req.dn.toString()); + console.log('Entry attributes: ' + req.toObject().attributes); + res.end(); +}); +``` + +## AddRequest + +AddRequest objects have the following properties: + +### entry + +The DN the client is attempting to add (this is the same as the `dn` +property). + +### attributes + +The set of attributes in this entry. This will be an array of +`Attribute` objects (which have a type and an array of values). This directly +maps to how the request came in off the wire. It's likely you'll want to use +`toObject()` and iterate that way, since that will transform an AddRequest into +a standard JavaScript object. + +### toObject() + +This operation will return a plain JavaScript object from the request that looks +like: + +```js +{ + dn: 'cn=foo, o=example', // string, not DN object + attributes: { + cn: ['foo'], + sn: ['bar'], + objectclass: ['person', 'top'] + } +} +``` + +## AddResponse + +No extra methods above an `LDAPResult` API call. + +# Search + +Adds a handler for the LDAP search operation. + +```js +server.search('o=example', (req, res, next) => { + console.log('base object: ' + req.dn.toString()); + console.log('scope: ' + req.scope); + console.log('filter: ' + req.filter.toString()); + res.end(); +}); +``` + +## SearchRequest + +SearchRequest objects have the following properties: + +### baseObject + +The DN the client is attempting to start the search at (equivalent to `dn`). + +### scope + +(string) one of: + +* base +* one +* sub + +### derefAliases + +An integer (defined in the LDAP protocol). Defaults to '0' (meaning +never deref). + +### sizeLimit + +The number of entries to return. Defaults to '0' (unlimited). ldapjs doesn't +currently automatically enforce this, but probably will at some point. + +### timeLimit + +Maximum amount of time the server should take in sending search entries. +Defaults to '0' (unlimited). + +### typesOnly + +Whether to return only the names of attributes, and not the values. Defaults to +'false'. ldapjs will take care of this for you. + +### filter + +The [filter](filters.html) object that the client requested. Notably this has +a `matches()` method on it that you can leverage. For an example of +introspecting a filter, take a look at the ldapjs-riak source. + +### attributes + +An optional list of attributes to restrict the returned result sets to. ldapjs +will automatically handle this for you. + +## SearchResponse + +### send(entry) + +Allows you to send a `SearchEntry` object. You do not need to +explicitly pass in a `SearchEntry` object, and can instead just send a plain +JavaScript object that matches the format used from `AddRequest.toObject()`. + + +```js +server.search('o=example', (req, res, next) => { + const obj = { + dn: 'o=example', + attributes: { + objectclass: ['top', 'organization'], + o: ['example'] + } + }; + + if (req.filter.matches(obj)) + res.send(obj) + + res.end(); +}); +``` + +# modify + +Allows you to handle an LDAP modify operation. + +```js +server.modify('o=example', (req, res, next) => { + console.log('DN: ' + req.dn.toString()); + console.log('changes:'); + for (const c of req.changes) { + console.log(' operation: ' + c.operation); + console.log(' modification: ' + c.modification.toString()); + } + res.end(); +}); +``` + +## ModifyRequest + +ModifyRequest objects have the following properties: + +### object + +The DN the client is attempting to update (this is the same as the `dn` +property). + +### changes + +An array of `Change` objects the client is attempting to perform. See below for +details on the `Change` object. + +## Change + +The `Change` object will have the following properties: + +### operation + +A string, and will be one of: 'add', 'delete', or 'replace'. + +### modification + +Will be an `Attribute` object, which will have a 'type' (string) field, and +'vals', which will be an array of string values. + +## ModifyResponse + +No extra methods above an `LDAPResult` API call. + +# del + +Allows you to handle an LDAP delete operation. + +```js +server.del('o=example', (req, res, next) => { + console.log('DN: ' + req.dn.toString()); + res.end(); +}); +``` + +## DeleteRequest + +### entry + +The DN the client is attempting to delete (this is the same as the `dn` +property). + +## DeleteResponse + +No extra methods above an `LDAPResult` API call. + +# compare + +Allows you to handle an LDAP compare operation. + +```js +server.compare('o=example', (req, res, next) => { + console.log('DN: ' + req.dn.toString()); + console.log('attribute name: ' + req.attribute); + console.log('attribute value: ' + req.value); + res.end(req.value === 'foo'); +}); +``` + +## CompareRequest + +### entry + +The DN the client is attempting to compare (this is the same as the `dn` +property). + +### attribute + +The string name of the attribute to compare values of. + +### value + +The string value of the attribute to compare. + +## CompareResponse + +The `end()` method for compare takes a boolean, as opposed to a numeric code +(you can still pass in a numeric LDAP status code if you want). Beyond +that, there are no extra methods above an `LDAPResult` API call. + +# modifyDN + +Allows you to handle an LDAP modifyDN operation. + +```js +server.modifyDN('o=example', (req, res, next) => { + console.log('DN: ' + req.dn.toString()); + console.log('new RDN: ' + req.newRdn.toString()); + console.log('deleteOldRDN: ' + req.deleteOldRdn); + console.log('new superior: ' + + (req.newSuperior ? req.newSuperior.toString() : '')); + + res.end(); +}); +``` + +## ModifyDNRequest + +### entry + +The DN the client is attempting to rename (this is the same as the `dn` +property). + +### newRdn + +The leaf RDN the client wants to rename this entry to. This will be a DN object. + +### deleteOldRdn + +Whether or not to delete the old RDN (i.e., rename vs copy). Defaults to 'true'. + +### newSuperior + +Optional (DN). If the modifyDN operation wishes to relocate the entry in the +tree, the `newSuperior` field will contain the new parent. + +## ModifyDNResponse + +No extra methods above an `LDAPResult` API call. + +# exop + +Allows you to handle an LDAP extended operation. Extended operations are pretty +much arbitrary extensions, by definition. Typically the extended 'name' is an +OID, but ldapjs makes no such restrictions; it just needs to be a string. +Unlike the other operations, extended operations don't map to any location in +the tree, so routing here will be exact match, as opposed to subtree. + +```js +// LDAP whoami +server.exop('1.3.6.1.4.1.4203.1.11.3', (req, res, next) => { + console.log('name: ' + req.name); + console.log('value: ' + req.value); + res.value = 'u:xxyyz@EXAMPLE.NET'; + res.end(); + return next(); +}); +``` + +## ExtendedRequest + +### name + +Will always be a match to the route-defined name. Clients must include this +in their requests. + +### value + +Optional string. The arbitrary blob the client sends for this extended +operation. + +## ExtendedResponse + +### name + +The name of the extended operation. ldapjs will automatically set this. + +### value + +The arbitrary (string) value to send back as part of the response. + +# unbind + +ldapjs by default provides an unbind handler that just disconnects the client +and cleans up any internals (in ldapjs core). You can override this handler +if you need to clean up any items in your backend, or perform any other cleanup +tasks you need to. + +```js +server.unbind((req, res, next) => { + res.end(); +}); +``` + +Note that the LDAP unbind operation actually doesn't send any response (by +definition in the RFC), so the UnbindResponse is really just a stub that +ultimately calls `net.Socket.end()` for you. There are no properties available +on either the request or response objects, except, of course, for `end()` on the +response. diff --git a/node_modules/ldapjs/examples/cluster-threading-net-server.js b/node_modules/ldapjs/examples/cluster-threading-net-server.js new file mode 100644 index 0000000..4d49089 --- /dev/null +++ b/node_modules/ldapjs/examples/cluster-threading-net-server.js @@ -0,0 +1,65 @@ +const cluster = require('cluster') +const ldap = require('ldapjs') +const net = require('net') +const os = require('os') + +const threads = [] +threads.getNext = function () { + return (Math.floor(Math.random() * this.length)) +} + +const serverOptions = { + port: 1389 +} + +if (cluster.isMaster) { + const server = net.createServer(serverOptions, (socket) => { + socket.pause() + console.log('ldapjs client requesting connection') + const routeTo = threads.getNext() + threads[routeTo].send({ type: 'connection' }, socket) + }) + + for (let i = 0; i < os.cpus().length; i++) { + const thread = cluster.fork({ + id: i + }) + thread.id = i + thread.on('message', function () { + + }) + threads.push(thread) + } + + server.listen(serverOptions.port, function () { + console.log('ldapjs listening at ldap://127.0.0.1:' + serverOptions.port) + }) +} else { + const server = ldap.createServer(serverOptions) + + const threadId = process.env.id + + process.on('message', (msg, socket) => { + switch (msg.type) { + case 'connection': + server.newConnection(socket) + socket.resume() + console.log('ldapjs client connection accepted on ' + threadId.toString()) + } + }) + + server.search('dc=example', function (req, res) { + console.log('ldapjs search initiated on ' + threadId.toString()) + const obj = { + dn: req.dn.toString(), + attributes: { + objectclass: ['organization', 'top'], + o: 'example' + } + } + + if (req.filter.matches(obj.attributes)) { res.send(obj) } + + res.end() + }) +} diff --git a/node_modules/ldapjs/examples/cluster-threading.js b/node_modules/ldapjs/examples/cluster-threading.js new file mode 100644 index 0000000..8def06a --- /dev/null +++ b/node_modules/ldapjs/examples/cluster-threading.js @@ -0,0 +1,65 @@ +const cluster = require('cluster') +const ldap = require('ldapjs') +const os = require('os') + +const threads = [] +threads.getNext = function () { + return (Math.floor(Math.random() * this.length)) +} + +const serverOptions = { + connectionRouter: (socket) => { + socket.pause() + console.log('ldapjs client requesting connection') + const routeTo = threads.getNext() + threads[routeTo].send({ type: 'connection' }, socket) + } +} + +const server = ldap.createServer(serverOptions) + +if (cluster.isMaster) { + for (let i = 0; i < os.cpus().length; i++) { + const thread = cluster.fork({ + id: i + }) + thread.id = i + thread.on('message', function () { + + }) + threads.push(thread) + } + + server.listen(1389, function () { + console.log('ldapjs listening at ' + server.url) + }) +} else { + const threadId = process.env.id + serverOptions.connectionRouter = () => { + console.log('should not be hit') + } + + process.on('message', (msg, socket) => { + switch (msg.type) { + case 'connection': + server.newConnection(socket) + socket.resume() + console.log('ldapjs client connection accepted on ' + threadId.toString()) + } + }) + + server.search('dc=example', function (req, res) { + console.log('ldapjs search initiated on ' + threadId.toString()) + const obj = { + dn: req.dn.toString(), + attributes: { + objectclass: ['organization', 'top'], + o: 'example' + } + } + + if (req.filter.matches(obj.attributes)) { res.send(obj) } + + res.end() + }) +} diff --git a/node_modules/ldapjs/examples/inmemory.js b/node_modules/ldapjs/examples/inmemory.js new file mode 100644 index 0000000..000641b --- /dev/null +++ b/node_modules/ldapjs/examples/inmemory.js @@ -0,0 +1,177 @@ +const ldap = require('../lib/index') + +/// --- Shared handlers + +function authorize (req, res, next) { + /* Any user may search after bind, only cn=root has full power */ + const isSearch = (req instanceof ldap.SearchRequest) + if (!req.connection.ldap.bindDN.equals('cn=root') && !isSearch) { return next(new ldap.InsufficientAccessRightsError()) } + + return next() +} + +/// --- Globals + +const SUFFIX = 'o=smartdc' +const db = {} +const server = ldap.createServer() + +server.bind('cn=root', function (req, res, next) { + if (req.dn.toString() !== 'cn=root' || req.credentials !== 'secret') { return next(new ldap.InvalidCredentialsError()) } + + res.end() + return next() +}) + +server.add(SUFFIX, authorize, function (req, res, next) { + const dn = req.dn.toString() + + if (db[dn]) { return next(new ldap.EntryAlreadyExistsError(dn)) } + + db[dn] = req.toObject().attributes + res.end() + return next() +}) + +server.bind(SUFFIX, function (req, res, next) { + const dn = req.dn.toString() + if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) } + + if (!db[dn].userpassword) { return next(new ldap.NoSuchAttributeError('userPassword')) } + + if (db[dn].userpassword.indexOf(req.credentials) === -1) { return next(new ldap.InvalidCredentialsError()) } + + res.end() + return next() +}) + +server.compare(SUFFIX, authorize, function (req, res, next) { + const dn = req.dn.toString() + if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) } + + if (!db[dn][req.attribute]) { return next(new ldap.NoSuchAttributeError(req.attribute)) } + + let matches = false + const vals = db[dn][req.attribute] + for (let i = 0; i < vals.length; i++) { + if (vals[i] === req.value) { + matches = true + break + } + } + + res.end(matches) + return next() +}) + +server.del(SUFFIX, authorize, function (req, res, next) { + const dn = req.dn.toString() + if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) } + + delete db[dn] + + res.end() + return next() +}) + +server.modify(SUFFIX, authorize, function (req, res, next) { + const dn = req.dn.toString() + if (!req.changes.length) { return next(new ldap.ProtocolError('changes required')) } + if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) } + + const entry = db[dn] + + let mod + for (let i = 0; i < req.changes.length; i++) { + mod = req.changes[i].modification + switch (req.changes[i].operation) { + case 'replace': + if (!entry[mod.type]) { return next(new ldap.NoSuchAttributeError(mod.type)) } + + if (!mod.vals || !mod.vals.length) { + delete entry[mod.type] + } else { + entry[mod.type] = mod.vals + } + + break + + case 'add': + if (!entry[mod.type]) { + entry[mod.type] = mod.vals + } else { + mod.vals.forEach(function (v) { + if (entry[mod.type].indexOf(v) === -1) { entry[mod.type].push(v) } + }) + } + + break + + case 'delete': + if (!entry[mod.type]) { return next(new ldap.NoSuchAttributeError(mod.type)) } + + delete entry[mod.type] + + break + } + } + + res.end() + return next() +}) + +server.search(SUFFIX, authorize, function (req, res, next) { + const dn = req.dn.toString() + if (!db[dn]) { return next(new ldap.NoSuchObjectError(dn)) } + + let scopeCheck + + switch (req.scope) { + case 'base': + if (req.filter.matches(db[dn])) { + res.send({ + dn, + attributes: db[dn] + }) + } + + res.end() + return next() + + case 'one': + scopeCheck = function (k) { + if (req.dn.equals(k)) { return true } + + const parent = ldap.parseDN(k).parent() + return (parent ? parent.equals(req.dn) : false) + } + break + + case 'sub': + scopeCheck = function (k) { + return (req.dn.equals(k) || req.dn.parentOf(k)) + } + + break + } + + Object.keys(db).forEach(function (key) { + if (!scopeCheck(key)) { return } + + if (req.filter.matches(db[key])) { + res.send({ + dn: key, + attributes: db[key] + }) + } + }) + + res.end() + return next() +}) + +/// --- Fire it up + +server.listen(1389, function () { + console.log('LDAP server up at: %s', server.url) +}) diff --git a/node_modules/ldapjs/lib/client/client.js b/node_modules/ldapjs/lib/client/client.js new file mode 100644 index 0000000..10959fc --- /dev/null +++ b/node_modules/ldapjs/lib/client/client.js @@ -0,0 +1,1345 @@ +'use strict' + +const requestQueueFactory = require('./request-queue') +const messageTrackerFactory = require('./message-tracker') +const { MAX_MSGID } = require('./constants') + +const EventEmitter = require('events').EventEmitter +const net = require('net') +const tls = require('tls') +const util = require('util') + +const once = require('once') +const backoff = require('backoff') +const vasync = require('vasync') +const assert = require('assert-plus') +const VError = require('verror').VError + +const Attribute = require('@ldapjs/attribute') +const Change = require('@ldapjs/change') +const Control = require('../controls/index').Control +const { Control: LdapControl } = require('@ldapjs/controls') +const SearchPager = require('./search_pager') +const Protocol = require('@ldapjs/protocol') +const { DN } = require('@ldapjs/dn') +const errors = require('../errors') +const filters = require('@ldapjs/filter') +const Parser = require('../messages/parser') +const url = require('../url') +const CorkedEmitter = require('../corked_emitter') + +/// --- Globals + +const messages = require('@ldapjs/messages') +const { + AbandonRequest, + AddRequest, + BindRequest, + CompareRequest, + DeleteRequest, + ExtensionRequest: ExtendedRequest, + ModifyRequest, + ModifyDnRequest: ModifyDNRequest, + SearchRequest, + UnbindRequest, + LdapResult: LDAPResult, + SearchResultEntry: SearchEntry, + SearchResultReference: SearchReference +} = messages + +const PresenceFilter = filters.PresenceFilter + +const ConnectionError = errors.ConnectionError + +const CMP_EXPECT = [errors.LDAP_COMPARE_TRUE, errors.LDAP_COMPARE_FALSE] + +// node 0.6 got rid of FDs, so make up a client id for logging +let CLIENT_ID = 0 + +/// --- Internal Helpers + +function nextClientId () { + if (++CLIENT_ID === MAX_MSGID) { return 1 } + + return CLIENT_ID +} + +function validateControls (controls) { + if (Array.isArray(controls)) { + controls.forEach(function (c) { + if (!(c instanceof Control) && !(c instanceof LdapControl)) { throw new TypeError('controls must be [Control]') } + }) + } else if (controls instanceof Control || controls instanceof LdapControl) { + controls = [controls] + } else { + throw new TypeError('controls must be [Control]') + } + + return controls +} + +function ensureDN (input) { + if (DN.isDn(input)) { + return input + } else if (typeof (input) === 'string') { + return DN.fromString(input) + } else { + throw new Error('invalid DN') + } +} + +/// --- API + +/** + * Constructs a new client. + * + * The options object is required, and must contain either a URL (string) or + * a socketPath (string); the socketPath is only if you want to talk to an LDAP + * server over a Unix Domain Socket. Additionally, you can pass in a bunyan + * option that is the result of `new Logger()`, presumably after you've + * configured it. + * + * @param {Object} options must have either url or socketPath. + * @throws {TypeError} on bad input. + */ +function Client (options) { + assert.ok(options) + + EventEmitter.call(this, options) + + const self = this + this.urls = options.url ? [].concat(options.url).map(url.parse) : [] + this._nextServer = 0 + // updated in connectSocket() after each connect + this.host = undefined + this.port = undefined + this.secure = undefined + this.url = undefined + this.tlsOptions = options.tlsOptions + this.socketPath = options.socketPath || false + + this.log = options.log.child({ clazz: 'Client' }, true) + + this.timeout = parseInt((options.timeout || 0), 10) + this.connectTimeout = parseInt((options.connectTimeout || 0), 10) + this.idleTimeout = parseInt((options.idleTimeout || 0), 10) + if (options.reconnect) { + // Fall back to defaults if options.reconnect === true + const rOpts = (typeof (options.reconnect) === 'object') + ? options.reconnect + : {} + this.reconnect = { + initialDelay: parseInt(rOpts.initialDelay || 100, 10), + maxDelay: parseInt(rOpts.maxDelay || 10000, 10), + failAfter: parseInt(rOpts.failAfter, 10) || Infinity + } + } + + this.queue = requestQueueFactory({ + size: parseInt((options.queueSize || 0), 10), + timeout: parseInt((options.queueTimeout || 0), 10) + }) + if (options.queueDisable) { + this.queue.freeze() + } + + // Implicitly configure setup action to bind the client if bindDN and + // bindCredentials are passed in. This will more closely mimic PooledClient + // auto-login behavior. + if (options.bindDN !== undefined && + options.bindCredentials !== undefined) { + this.on('setup', function (clt, cb) { + clt.bind(options.bindDN, options.bindCredentials, function (err) { + if (err) { + if (self._socket) { + self._socket.destroy() + } + self.emit('error', err) + } + cb(err) + }) + }) + } + + this._socket = null + this.connected = false + this.connect() +} +util.inherits(Client, EventEmitter) +module.exports = Client + +/** + * Sends an abandon request to the LDAP server. + * + * The callback will be invoked as soon as the data is flushed out to the + * network, as there is never a response from abandon. + * + * @param {Number} messageId the messageId to abandon. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err). + * @throws {TypeError} on invalid input. + */ +Client.prototype.abandon = function abandon (messageId, controls, callback) { + assert.number(messageId, 'messageId') + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + const req = new AbandonRequest({ + abandonId: messageId, + controls + }) + + return this._send(req, 'abandon', null, callback) +} + +/** + * Adds an entry to the LDAP server. + * + * Entry can be either [Attribute] or a plain JS object where the + * values are either a plain value or an array of values. Any value (that's + * not an array) will get converted to a string, so keep that in mind. + * + * @param {String} name the DN of the entry to add. + * @param {Object} entry an array of Attributes to be added or a JS object. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.add = function add (name, entry, controls, callback) { + assert.ok(name !== undefined, 'name') + assert.object(entry, 'entry') + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + if (Array.isArray(entry)) { + entry.forEach(function (a) { + if (!Attribute.isAttribute(a)) { throw new TypeError('entry must be an Array of Attributes') } + }) + } else { + const save = entry + + entry = [] + Object.keys(save).forEach(function (k) { + const attr = new Attribute({ type: k }) + if (Array.isArray(save[k])) { + save[k].forEach(function (v) { + attr.addValue(v.toString()) + }) + } else if (Buffer.isBuffer(save[k])) { + attr.addValue(save[k]) + } else { + attr.addValue(save[k].toString()) + } + entry.push(attr) + }) + } + + const req = new AddRequest({ + entry: ensureDN(name), + attributes: entry, + controls + }) + + return this._send(req, [errors.LDAP_SUCCESS], null, callback) +} + +/** + * Performs a simple authentication against the server. + * + * @param {String} name the DN to bind as. + * @param {String} credentials the userPassword associated with name. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.bind = function bind (name, + credentials, + controls, + callback, + _bypass) { + if ( + typeof (name) !== 'string' && + Object.prototype.toString.call(name) !== '[object LdapDn]' + ) { + throw new TypeError('name (string) required') + } + assert.optionalString(credentials, 'credentials') + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + const req = new BindRequest({ + name: name || '', + authentication: 'Simple', + credentials: credentials || '', + controls + }) + + // Connection errors will be reported to the bind callback too (useful when the LDAP server is not available) + const self = this + function callbackWrapper (err, ret) { + self.removeListener('connectError', callbackWrapper) + callback(err, ret) + } + this.addListener('connectError', callbackWrapper) + + return this._send(req, [errors.LDAP_SUCCESS], null, callbackWrapper, _bypass) +} + +/** + * Compares an attribute/value pair with an entry on the LDAP server. + * + * @param {String} name the DN of the entry to compare attributes with. + * @param {String} attr name of an attribute to check. + * @param {String} value value of an attribute to check. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, boolean, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.compare = function compare (name, + attr, + value, + controls, + callback) { + assert.ok(name !== undefined, 'name') + assert.string(attr, 'attr') + assert.string(value, 'value') + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + const req = new CompareRequest({ + entry: ensureDN(name), + attribute: attr, + value, + controls + }) + + return this._send(req, CMP_EXPECT, null, function (err, res) { + if (err) { return callback(err) } + + return callback(null, (res.status === errors.LDAP_COMPARE_TRUE), res) + }) +} + +/** + * Deletes an entry from the LDAP server. + * + * @param {String} name the DN of the entry to delete. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.del = function del (name, controls, callback) { + assert.ok(name !== undefined, 'name') + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + const req = new DeleteRequest({ + entry: ensureDN(name), + controls + }) + + return this._send(req, [errors.LDAP_SUCCESS], null, callback) +} + +/** + * Performs an extended operation on the LDAP server. + * + * Pretty much none of the LDAP extended operations return an OID + * (responseName), so I just don't bother giving it back in the callback. + * It's on the third param in `res` if you need it. + * + * @param {String} name the OID of the extended operation to perform. + * @param {String} value value to pass in for this operation. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, value, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.exop = function exop (name, value, controls, callback) { + assert.string(name, 'name') + if (typeof (value) === 'function') { + callback = value + controls = [] + value = undefined + } + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + const req = new ExtendedRequest({ + requestName: name, + requestValue: value, + controls + }) + + return this._send(req, [errors.LDAP_SUCCESS], null, function (err, res) { + if (err) { return callback(err) } + + return callback(null, res.responseValue || '', res) + }) +} + +/** + * Performs an LDAP modify against the server. + * + * @param {String} name the DN of the entry to modify. + * @param {Change} change update to perform (can be [Change]). + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.modify = function modify (name, change, controls, callback) { + assert.ok(name !== undefined, 'name') + assert.object(change, 'change') + + const changes = [] + + function changeFromObject (obj) { + if (!obj.operation && !obj.type) { throw new Error('change.operation required') } + if (typeof (obj.modification) !== 'object') { throw new Error('change.modification (object) required') } + + if (Object.keys(obj.modification).length === 2 && + typeof (obj.modification.type) === 'string' && + Array.isArray(obj.modification.vals)) { + // Use modification directly if it's already normalized: + changes.push(new Change({ + operation: obj.operation || obj.type, + modification: obj.modification + })) + } else { + // Normalize the modification object + Object.keys(obj.modification).forEach(function (k) { + const mod = {} + mod[k] = obj.modification[k] + changes.push(new Change({ + operation: obj.operation || obj.type, + modification: mod + })) + }) + } + } + + if (Change.isChange(change)) { + changes.push(change) + } else if (Array.isArray(change)) { + change.forEach(function (c) { + if (Change.isChange(c)) { + changes.push(c) + } else { + changeFromObject(c) + } + }) + } else { + changeFromObject(change) + } + + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + const req = new ModifyRequest({ + object: ensureDN(name), + changes, + controls + }) + + return this._send(req, [errors.LDAP_SUCCESS], null, callback) +} + +/** + * Performs an LDAP modifyDN against the server. + * + * This does not allow you to keep the old DN, as while the LDAP protocol + * has a facility for that, it's stupid. Just Search/Add. + * + * This will automatically deal with "new superior" logic. + * + * @param {String} name the DN of the entry to modify. + * @param {String} newName the new DN to move this entry to. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.modifyDN = function modifyDN (name, + newName, + controls, + callback) { + assert.ok(name !== undefined, 'name') + assert.string(newName, 'newName') + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback) + + const newDN = DN.fromString(newName) + + const req = new ModifyDNRequest({ + entry: DN.fromString(name), + deleteOldRdn: true, + controls + }) + + if (newDN.length !== 1) { + req.newRdn = DN.fromString(newDN.shift().toString()) + req.newSuperior = newDN + } else { + req.newRdn = newDN + } + + return this._send(req, [errors.LDAP_SUCCESS], null, callback) +} + +/** + * Performs an LDAP search against the server. + * + * Note that the defaults for options are a 'base' search, if that's what + * you want you can just pass in a string for options and it will be treated + * as the search filter. Also, you can either pass in programatic Filter + * objects or a filter string as the filter option. + * + * Note that this method is 'special' in that the callback 'res' param will + * have two important events on it, namely 'entry' and 'end' that you can hook + * to. The former will emit a SearchEntry object for each record that comes + * back, and the latter will emit a normal LDAPResult object. + * + * @param {String} base the DN in the tree to start searching at. + * @param {Object} options parameters: + * - {String} scope default of 'base'. + * - {String} filter default of '(objectclass=*)'. + * - {Array} attributes [string] to return. + * - {Boolean} attrsOnly whether to return values. + * @param {Control} controls (optional) either a Control or [Control]. + * @param {Function} callback of the form f(err, res). + * @throws {TypeError} on invalid input. + */ +Client.prototype.search = function search (base, + options, + controls, + callback, + _bypass) { + assert.ok(base !== undefined, 'search base') + if (Array.isArray(options) || (options instanceof Control)) { + controls = options + options = {} + } else if (typeof (options) === 'function') { + callback = options + controls = [] + options = { + filter: new PresenceFilter({ attribute: 'objectclass' }) + } + } else if (typeof (options) === 'string') { + options = { filter: filters.parseString(options) } + } else if (typeof (options) !== 'object') { + throw new TypeError('options (object) required') + } + if (typeof (options.filter) === 'string') { + options.filter = filters.parseString(options.filter) + } else if (!options.filter) { + options.filter = new PresenceFilter({ attribute: 'objectclass' }) + } else if (Object.prototype.toString.call(options.filter) !== '[object FilterString]') { + throw new TypeError('options.filter (Filter) required') + } + if (typeof (controls) === 'function') { + callback = controls + controls = [] + } else { + controls = validateControls(controls) + } + assert.func(callback, 'callback') + + if (options.attributes) { + if (!Array.isArray(options.attributes)) { + if (typeof (options.attributes) === 'string') { + options.attributes = [options.attributes] + } else { + throw new TypeError('options.attributes must be an Array of Strings') + } + } + } + + const self = this + const baseDN = ensureDN(base) + + function sendRequest (ctrls, emitter, cb) { + const req = new SearchRequest({ + baseObject: baseDN, + scope: options.scope || 'base', + filter: options.filter, + derefAliases: options.derefAliases || Protocol.search.NEVER_DEREF_ALIASES, + sizeLimit: options.sizeLimit || 0, + timeLimit: options.timeLimit || 10, + typesOnly: options.typesOnly || false, + attributes: options.attributes || [], + controls: ctrls + }) + + return self._send(req, + [errors.LDAP_SUCCESS], + emitter, + cb, + _bypass) + } + + if (options.paged) { + // Perform automated search paging + const pageOpts = typeof (options.paged) === 'object' ? options.paged : {} + let size = 100 // Default page size + if (pageOpts.pageSize > 0) { + size = pageOpts.pageSize + } else if (options.sizeLimit > 1) { + // According to the RFC, servers should ignore the paging control if + // pageSize >= sizelimit. Some might still send results, but it's safer + // to stay under that figure when assigning a default value. + size = options.sizeLimit - 1 + } + + const pager = new SearchPager({ + callback, + controls, + pageSize: size, + pagePause: pageOpts.pagePause, + sendRequest + }) + pager.begin() + } else { + sendRequest(controls, new CorkedEmitter(), callback) + } +} + +/** + * Unbinds this client from the LDAP server. + * + * Note that unbind does not have a response, so this callback is actually + * optional; either way, the client is disconnected. + * + * @param {Function} callback of the form f(err). + * @throws {TypeError} if you pass in callback as not a function. + */ +Client.prototype.unbind = function unbind (callback) { + if (!callback) { callback = function () {} } + + if (typeof (callback) !== 'function') { throw new TypeError('callback must be a function') } + + // When the socket closes, it is useful to know whether it was due to a + // user-initiated unbind or something else. + this.unbound = true + + if (!this._socket) { return callback() } + + const req = new UnbindRequest() + return this._send(req, 'unbind', null, callback) +} + +/** + * Attempt to secure connection with StartTLS. + */ +Client.prototype.starttls = function starttls (options, + controls, + callback, + _bypass) { + assert.optionalObject(options) + options = options || {} + callback = once(callback) + const self = this + + if (this._starttls) { + return callback(new Error('STARTTLS already in progress or active')) + } + + function onSend (sendErr, emitter) { + if (sendErr) { + callback(sendErr) + return + } + /* + * Now that the request has been sent, block all outgoing messages + * until an error is received or we successfully complete the setup. + */ + // TODO: block traffic + self._starttls = { + started: true + } + + emitter.on('error', function (err) { + self._starttls = null + callback(err) + }) + emitter.on('end', function (_res) { + const sock = self._socket + /* + * Unplumb socket data during SSL negotiation. + * This will prevent the LDAP parser from stumbling over the TLS + * handshake and raising a ruckus. + */ + sock.removeAllListeners('data') + + options.socket = sock + const secure = tls.connect(options) + secure.once('secureConnect', function () { + /* + * Wire up 'data' and 'error' handlers like the normal socket. + * Handling 'end' events isn't necessary since the underlying socket + * will handle those. + */ + secure.removeAllListeners('error') + secure.on('data', function onData (data) { + self.log.trace('data event: %s', util.inspect(data)) + + self._tracker.parser.write(data) + }) + secure.on('error', function (err) { + self.log.trace({ err }, 'error event: %s', new Error().stack) + + self.emit('error', err) + sock.destroy() + }) + callback(null) + }) + secure.once('error', function (err) { + // If the SSL negotiation failed, to back to plain mode. + self._starttls = null + secure.removeAllListeners() + callback(err) + }) + self._starttls.success = true + self._socket = secure + }) + } + + const req = new ExtendedRequest({ + requestName: '1.3.6.1.4.1.1466.20037', + requestValue: null, + controls + }) + + return this._send(req, + [errors.LDAP_SUCCESS], + new EventEmitter(), + onSend, + _bypass) +} + +/** + * Disconnect from the LDAP server and do not allow reconnection. + * + * If the client is instantiated with proper reconnection options, it's + * possible to initiate new requests after a call to unbind since the client + * will attempt to reconnect in order to fulfill the request. + * + * Calling destroy will prevent any further reconnection from occurring. + * + * @param {Object} err (Optional) error that was cause of client destruction + */ +Client.prototype.destroy = function destroy (err) { + this.destroyed = true + this.queue.freeze() + // Purge any queued requests which are now meaningless + this.queue.flush(function (msg, expect, emitter, cb) { + if (typeof (cb) === 'function') { + cb(new Error('client destroyed')) + } + }) + if (this.connected) { + this.unbind() + } + if (this._socket) { + this._socket.destroy() + } + + this.emit('destroy', err) +} + +/** + * Initiate LDAP connection. + */ +Client.prototype.connect = function connect () { + if (this.connecting || this.connected) { + return + } + const self = this + const log = this.log + let socket + let tracker + + // Establish basic socket connection + function connectSocket (cb) { + const server = self.urls[self._nextServer] + self._nextServer = (self._nextServer + 1) % self.urls.length + + cb = once(cb) + + function onResult (err, res) { + if (err) { + if (self.connectTimer) { + clearTimeout(self.connectTimer) + self.connectTimer = null + } + self.emit('connectError', err) + } + cb(err, res) + } + function onConnect () { + if (self.connectTimer) { + clearTimeout(self.connectTimer) + self.connectTimer = null + } + socket.removeAllListeners('error') + .removeAllListeners('connect') + .removeAllListeners('secureConnect') + + tracker.id = nextClientId() + '__' + tracker.id + self.log = self.log.child({ ldap_id: tracker.id }, true) + + // Move on to client setup + setupClient(cb) + } + + const port = (server && server.port) || self.socketPath + const host = server && server.hostname + if (server && server.secure) { + socket = tls.connect(port, host, self.tlsOptions) + socket.once('secureConnect', onConnect) + } else { + socket = net.connect(port, host) + socket.once('connect', onConnect) + } + socket.once('error', onResult) + initSocket(server) + + // Setup connection timeout handling, if desired + if (self.connectTimeout) { + self.connectTimer = setTimeout(function onConnectTimeout () { + if (!socket || !socket.readable || !socket.writeable) { + socket.destroy() + self._socket = null + onResult(new ConnectionError('connection timeout')) + } + }, self.connectTimeout) + } + } + + // Initialize socket events and LDAP parser. + function initSocket (server) { + tracker = messageTrackerFactory({ + id: server ? server.href : self.socketPath, + parser: new Parser({ log }) + }) + + // This won't be set on TLS. So. Very. Annoying. + if (typeof (socket.setKeepAlive) !== 'function') { + socket.setKeepAlive = function setKeepAlive (enable, delay) { + return socket.socket + ? socket.socket.setKeepAlive(enable, delay) + : false + } + } + + socket.on('data', function onData (data) { + log.trace('data event: %s', util.inspect(data)) + + tracker.parser.write(data) + }) + + // The "router" + // + // This is invoked after the incoming BER has been parsed into a JavaScript + // object. + tracker.parser.on('message', function onMessage (message) { + message.connection = self._socket + const trackedObject = tracker.fetch(message.messageId) + if (!trackedObject) { + log.error({ message: message.pojo }, 'unmatched server message received') + return false + } + + const { message: trackedMessage, callback } = trackedObject + + if (!callback) { + log.error({ message: message.pojo }, 'unsolicited message') + return false + } + + // Some message types have narrower implementations and require extra + // parsing to be complete. In particular, ExtensionRequest messages will + // return responses that do not identify the request that generated them. + // Therefore, we have to match the response to the request and handle + // the extra processing accordingly. + switch (trackedMessage.type) { + case 'ExtensionRequest': { + const extensionType = ExtendedRequest.recognizedOIDs().lookupName(trackedMessage.requestName) + switch (extensionType) { + case 'PASSWORD_MODIFY': { + message = messages.PasswordModifyResponse.fromResponse(message) + break + } + + case 'WHO_AM_I': { + message = messages.WhoAmIResponse.fromResponse(message) + break + } + + default: + } + + break + } + + default: + } + + return callback(message) + }) + + tracker.parser.on('error', function onParseError (err) { + self.emit('error', new VError(err, 'Parser error for %s', + tracker.id)) + self.connected = false + socket.end() + }) + } + + // After connect, register socket event handlers and run any setup actions + function setupClient (cb) { + cb = once(cb) + + // Indicate failure if anything goes awry during setup + function bail (err) { + socket.destroy() + cb(err || new Error('client error during setup')) + } + // Work around lack of close event on tls.socket in node < 0.11 + ((socket.socket) ? socket.socket : socket).once('close', bail) + socket.once('error', bail) + socket.once('end', bail) + socket.once('timeout', bail) + socket.once('cleanupSetupListeners', function onCleanup () { + socket.removeListener('error', bail) + .removeListener('close', bail) + .removeListener('end', bail) + .removeListener('timeout', bail) + }) + + self._socket = socket + self._tracker = tracker + + // Run any requested setup (such as automatically performing a bind) on + // socket before signalling successful connection. + // This setup needs to bypass the request queue since all other activity is + // blocked until the connection is considered fully established post-setup. + // Only allow bind/search/starttls for now. + const basicClient = { + bind: function bindBypass (name, credentials, controls, callback) { + return self.bind(name, credentials, controls, callback, true) + }, + search: function searchBypass (base, options, controls, callback) { + return self.search(base, options, controls, callback, true) + }, + starttls: function starttlsBypass (options, controls, callback) { + return self.starttls(options, controls, callback, true) + }, + unbind: self.unbind.bind(self) + } + vasync.forEachPipeline({ + func: function (f, callback) { + f(basicClient, callback) + }, + inputs: self.listeners('setup') + }, function (err, _res) { + if (err) { + self.emit('setupError', err) + } + cb(err) + }) + } + + // Wire up "official" event handlers after successful connect/setup + function postSetup () { + // cleanup the listeners we attached in setup phrase. + socket.emit('cleanupSetupListeners'); + + // Work around lack of close event on tls.socket in node < 0.11 + ((socket.socket) ? socket.socket : socket).once('close', + self._onClose.bind(self)) + socket.on('end', function onEnd () { + log.trace('end event') + + self.emit('end') + socket.end() + }) + socket.on('error', function onSocketError (err) { + log.trace({ err }, 'error event: %s', new Error().stack) + + self.emit('error', err) + socket.destroy() + }) + socket.on('timeout', function onTimeout () { + log.trace('timeout event') + + self.emit('socketTimeout') + socket.end() + }) + + const server = self.urls[self._nextServer] + if (server) { + self.host = server.hostname + self.port = server.port + self.secure = server.secure + } + } + + let retry + let failAfter + if (this.reconnect) { + retry = backoff.exponential({ + initialDelay: this.reconnect.initialDelay, + maxDelay: this.reconnect.maxDelay + }) + failAfter = this.reconnect.failAfter + if (this.urls.length > 1 && failAfter) { + failAfter *= this.urls.length + } + } else { + retry = backoff.exponential({ + initialDelay: 1, + maxDelay: 2 + }) + failAfter = this.urls.length || 1 + } + retry.failAfter(failAfter) + + retry.on('ready', function (num, _delay) { + if (self.destroyed) { + // Cease connection attempts if destroyed + return + } + connectSocket(function (err) { + if (!err) { + postSetup() + self.connecting = false + self.connected = true + self.emit('connect', socket) + self.log.debug('connected after %d attempt(s)', num + 1) + // Flush any queued requests + self._flushQueue() + self._connectRetry = null + } else { + retry.backoff(err) + } + }) + }) + retry.on('fail', function (err) { + if (self.destroyed) { + // Silence any connect/setup errors if destroyed + return + } + self.log.debug('failed to connect after %d attempts', failAfter) + // Communicate the last-encountered error + if (err instanceof ConnectionError) { + self.emitError('connectTimeout', err) + } else if (err.code === 'ECONNREFUSED') { + self.emitError('connectRefused', err) + } else { + self.emit('error', err) + } + }) + + this._connectRetry = retry + this.connecting = true + retry.backoff() +} + +/// --- Private API + +/** + * Flush queued requests out to the socket. + */ +Client.prototype._flushQueue = function _flushQueue () { + // Pull items we're about to process out of the queue. + this.queue.flush(this._send.bind(this)) +} + +/** + * Clean up socket/parser resources after socket close. + */ +Client.prototype._onClose = function _onClose (closeError) { + const socket = this._socket + const tracker = this._tracker + socket.removeAllListeners('connect') + .removeAllListeners('data') + .removeAllListeners('drain') + .removeAllListeners('end') + .removeAllListeners('error') + .removeAllListeners('timeout') + this._socket = null + this.connected = false; + + ((socket.socket) ? socket.socket : socket).removeAllListeners('close') + + this.log.trace('close event had_err=%s', closeError ? 'yes' : 'no') + + this.emit('close', closeError) + // On close we have to walk the outstanding messages and go invoke their + // callback with an error. + tracker.purge(function (msgid, cb) { + if (socket.unbindMessageID !== msgid) { + return cb(new ConnectionError(tracker.id + ' closed')) + } else { + // Unbinds will be communicated as a success since we're closed + // TODO: we are faking this "UnbindResponse" object in order to make + // tests pass. There is no such thing as an "unbind response" in the LDAP + // protocol. When the client is revamped, this logic should be removed. + // ~ jsumners 2023-02-16 + const Unbind = class extends LDAPResult { + messageID = msgid + messageId = msgid + status = 'unbind' + } + const unbind = new Unbind() + return cb(unbind) + } + }) + + // Trash any parser or starttls state + this._tracker = null + delete this._starttls + + // Automatically fire reconnect logic if the socket was closed for any reason + // other than a user-initiated unbind. + if (this.reconnect && !this.unbound) { + this.connect() + } + this.unbound = false + return false +} + +/** + * Maintain idle timer for client. + * + * Will start timer to fire 'idle' event if conditions are satisfied. If + * conditions are not met and a timer is running, it will be cleared. + * + * @param {Boolean} override explicitly disable timer. + */ +Client.prototype._updateIdle = function _updateIdle (override) { + if (this.idleTimeout === 0) { + return + } + // Client must be connected but not waiting on any request data + const self = this + function isIdle (disable) { + return ((disable !== true) && + (self._socket && self.connected) && + (self._tracker.pending === 0)) + } + if (isIdle(override)) { + if (!this._idleTimer) { + this._idleTimer = setTimeout(function () { + // Double-check idleness in case socket was torn down + if (isIdle()) { + self.emit('idle') + } + }, this.idleTimeout) + } + } else { + if (this._idleTimer) { + clearTimeout(this._idleTimer) + this._idleTimer = null + } + } +} + +/** + * Attempt to send an LDAP request. + */ +Client.prototype._send = function _send (message, + expect, + emitter, + callback, + _bypass) { + assert.ok(message) + assert.ok(expect) + assert.optionalObject(emitter) + assert.ok(callback) + + // Allow connect setup traffic to bypass checks + if (_bypass && this._socket && this._socket.writable) { + return this._sendSocket(message, expect, emitter, callback) + } + if (!this._socket || !this.connected) { + if (!this.queue.enqueue(message, expect, emitter, callback)) { + callback(new ConnectionError('connection unavailable')) + } + // Initiate reconnect if needed + if (this.reconnect) { + this.connect() + } + return false + } else { + this._flushQueue() + return this._sendSocket(message, expect, emitter, callback) + } +} + +Client.prototype._sendSocket = function _sendSocket (message, + expect, + emitter, + callback) { + const conn = this._socket + const tracker = this._tracker + const log = this.log + const self = this + let timer = false + let sentEmitter = false + + function sendResult (event, obj) { + if (event === 'error') { + self.emit('resultError', obj) + } + if (emitter) { + if (event === 'error') { + // Error will go unhandled if emitter hasn't been sent via callback. + // Execute callback with the error instead. + if (!sentEmitter) { return callback(obj) } + } + return emitter.emit(event, obj) + } + + if (event === 'error') { return callback(obj) } + + return callback(null, obj) + } + + function messageCallback (msg) { + if (timer) { clearTimeout(timer) } + + log.trace({ msg: msg ? msg.pojo : null }, 'response received') + + if (expect === 'abandon') { return sendResult('end', null) } + + if (msg instanceof SearchEntry || msg instanceof SearchReference) { + let event = msg.constructor.name + // Generate the event name for the event emitter, i.e. "searchEntry" + // and "searchReference". + event = (event[0].toLowerCase() + event.slice(1)).replaceAll('Result', '') + return sendResult(event, msg) + } else { + tracker.remove(message.messageId) + // Potentially mark client as idle + self._updateIdle() + + if (msg instanceof LDAPResult) { + if (msg.status !== 0 && expect.indexOf(msg.status) === -1) { + return sendResult('error', errors.getError(msg)) + } + return sendResult('end', msg) + } else if (msg instanceof Error) { + return sendResult('error', msg) + } else { + return sendResult('error', new errors.ProtocolError(msg.type)) + } + } + } + + function onRequestTimeout () { + self.emit('timeout', message) + const { callback: cb } = tracker.fetch(message.messageId) + if (cb) { + // FIXME: the timed-out request should be abandoned + cb(new errors.TimeoutError('request timeout (client interrupt)')) + } + } + + function writeCallback () { + if (expect === 'abandon') { + // Mark the messageId specified as abandoned + tracker.abandon(message.abandonId) + // No need to track the abandon request itself + tracker.remove(message.id) + return callback(null) + } else if (expect === 'unbind') { + conn.unbindMessageID = message.id + // Mark client as disconnected once unbind clears the socket + self.connected = false + // Some servers will RST the connection after receiving an unbind. + // Socket errors are blackholed since the connection is being closed. + conn.removeAllListeners('error') + conn.on('error', function () {}) + conn.end() + } else if (emitter) { + sentEmitter = true + callback(null, emitter) + emitter.emit('searchRequest', message) + return + } + return false + } + + // Start actually doing something... + tracker.track(message, messageCallback) + // Mark client as active + this._updateIdle(true) + + if (self.timeout) { + log.trace('Setting timeout to %d', self.timeout) + timer = setTimeout(onRequestTimeout, self.timeout) + } + + log.trace('sending request %j', message.pojo) + + try { + const messageBer = message.toBer() + return conn.write(messageBer.buffer, writeCallback) + } catch (e) { + if (timer) { clearTimeout(timer) } + + log.trace({ err: e }, 'Error writing message to socket') + return callback(e) + } +} + +Client.prototype.emitError = function emitError (event, err) { + if (event !== 'error' && err && this.listenerCount(event) === 0) { + if (typeof err === 'string') { + err = event + ': ' + err + } else if (err.message) { + err.message = event + ': ' + err.message + } + this.emit('error', err) + } + this.emit(event, err) +} diff --git a/node_modules/ldapjs/lib/client/constants.js b/node_modules/ldapjs/lib/client/constants.js new file mode 100644 index 0000000..4a8ac9d --- /dev/null +++ b/node_modules/ldapjs/lib/client/constants.js @@ -0,0 +1,7 @@ +'use strict' + +module.exports = { + // https://tools.ietf.org/html/rfc4511#section-4.1.1 + // Message identifiers are an integer between (0, maxint). + MAX_MSGID: Math.pow(2, 31) - 1 +} diff --git a/node_modules/ldapjs/lib/client/index.js b/node_modules/ldapjs/lib/client/index.js new file mode 100644 index 0000000..64f2a69 --- /dev/null +++ b/node_modules/ldapjs/lib/client/index.js @@ -0,0 +1,23 @@ +'use strict' + +const logger = require('../logger') +const Client = require('./client') + +module.exports = { + Client, + createClient: function createClient (options) { + if (isObject(options) === false) throw TypeError('options (object) required') + if (options.url && typeof options.url !== 'string' && !Array.isArray(options.url)) throw TypeError('options.url (string|array) required') + if (options.socketPath && typeof options.socketPath !== 'string') throw TypeError('options.socketPath must be a string') + if ((options.url && options.socketPath) || !(options.url || options.socketPath)) throw TypeError('options.url ^ options.socketPath (String) required') + if (!options.log) options.log = logger + if (isObject(options.log) !== true) throw TypeError('options.log must be an object') + if (!options.log.child) options.log.child = function () { return options.log } + + return new Client(options) + } +} + +function isObject (input) { + return Object.prototype.toString.apply(input) === '[object Object]' +} diff --git a/node_modules/ldapjs/lib/client/message-tracker/ge-window.js b/node_modules/ldapjs/lib/client/message-tracker/ge-window.js new file mode 100644 index 0000000..58bde78 --- /dev/null +++ b/node_modules/ldapjs/lib/client/message-tracker/ge-window.js @@ -0,0 +1,25 @@ +'use strict' + +const { MAX_MSGID } = require('../constants') + +/** + * Compare a reference id with another id to determine "greater than or equal" + * between the two values according to a sliding window. + * + * @param {integer} ref + * @param {integer} comp + * + * @returns {boolean} `true` if the `comp` value is >= to the `ref` value + * within the computed window, otherwise `false`. + */ +module.exports = function geWindow (ref, comp) { + let max = ref + Math.floor(MAX_MSGID / 2) + const min = ref + if (max >= MAX_MSGID) { + // Handle roll-over + max = max - MAX_MSGID - 1 + return ((comp <= max) || (comp >= min)) + } else { + return ((comp <= max) && (comp >= min)) + } +} diff --git a/node_modules/ldapjs/lib/client/message-tracker/id-generator.js b/node_modules/ldapjs/lib/client/message-tracker/id-generator.js new file mode 100644 index 0000000..3756314 --- /dev/null +++ b/node_modules/ldapjs/lib/client/message-tracker/id-generator.js @@ -0,0 +1,23 @@ +'use strict' + +const { MAX_MSGID } = require('../constants') + +/** + * Returns a function that generates message identifiers. According to RFC 4511 + * the identifers should be `(0, MAX_MSGID)`. The returned function handles + * this and wraps around when the maximum has been reached. + * + * @param {integer} [start=0] Starting number in the identifier sequence. + * + * @returns {function} This function accepts no parameters and returns an + * increasing sequence identifier each invocation until it reaches the maximum + * identifier. At this point the sequence starts over. + */ +module.exports = function idGeneratorFactory (start = 0) { + let currentID = start + return function nextID () { + const id = currentID + 1 + currentID = (id >= MAX_MSGID) ? 1 : id + return currentID + } +} diff --git a/node_modules/ldapjs/lib/client/message-tracker/index.js b/node_modules/ldapjs/lib/client/message-tracker/index.js new file mode 100644 index 0000000..6c71b68 --- /dev/null +++ b/node_modules/ldapjs/lib/client/message-tracker/index.js @@ -0,0 +1,161 @@ +'use strict' + +const idGeneratorFactory = require('./id-generator') +const purgeAbandoned = require('./purge-abandoned') + +/** + * Returns a message tracker object that keeps track of which message + * identifiers correspond to which message handlers. Also handles keeping track + * of abandoned messages. + * + * @param {object} options + * @param {string} options.id An identifier for the tracker. + * @param {object} options.parser An object that will be used to parse messages. + * + * @returns {MessageTracker} + */ +module.exports = function messageTrackerFactory (options) { + if (Object.prototype.toString.call(options) !== '[object Object]') { + throw Error('options object is required') + } + if (!options.id || typeof options.id !== 'string') { + throw Error('options.id string is required') + } + if (!options.parser || Object.prototype.toString.call(options.parser) !== '[object Object]') { + throw Error('options.parser object is required') + } + + let currentID = 0 + const nextID = idGeneratorFactory() + const messages = new Map() + const abandoned = new Map() + + /** + * @typedef {object} MessageTracker + * @property {string} id The identifier of the tracker as supplied via the options. + * @property {object} parser The parser object given by the the options. + */ + const tracker = { + id: options.id, + parser: options.parser + } + + /** + * Count of messages awaiting response. + * + * @alias pending + * @memberof! MessageTracker# + */ + Object.defineProperty(tracker, 'pending', { + get () { + return messages.size + } + }) + + /** + * Move a specific message to the abanded track. + * + * @param {integer} msgID The identifier for the message to move. + * + * @memberof MessageTracker + * @method abandon + */ + tracker.abandon = function abandonMessage (msgID) { + if (messages.has(msgID) === false) return false + const toAbandon = messages.get(msgID) + abandoned.set(msgID, { + age: currentID, + message: toAbandon.message, + cb: toAbandon.callback + }) + return messages.delete(msgID) + } + + /** + * @typedef {object} Tracked + * @property {object} message The tracked message. Usually the outgoing + * request object. + * @property {Function} callback The handler to use when receiving a + * response to the tracked message. + */ + + /** + * Retrieves the message handler for a message. Removes abandoned messages + * that have been given time to be resolved. + * + * @param {integer} msgID The identifier for the message to get the handler for. + * + * @memberof MessageTracker + * @method fetch + */ + tracker.fetch = function fetchMessage (msgID) { + const tracked = messages.get(msgID) + if (tracked) { + purgeAbandoned(msgID, abandoned) + return tracked + } + + // We sent an abandon request but the server either wasn't able to process + // it or has not received it yet. Therefore, we received a response for the + // abandoned message. So we must return the abandoned message's callback + // to be processed normally. + const abandonedMsg = abandoned.get(msgID) + if (abandonedMsg) { + return { message: abandonedMsg, callback: abandonedMsg.cb } + } + + return null + } + + /** + * Removes all message tracks, cleans up the abandoned track, and invokes + * a callback for each message purged. + * + * @param {function} cb A function with the signature `(msgID, handler)`. + * + * @memberof MessageTracker + * @method purge + */ + tracker.purge = function purgeMessages (cb) { + messages.forEach((val, key) => { + purgeAbandoned(key, abandoned) + tracker.remove(key) + cb(key, val.callback) + }) + } + + /** + * Removes a message from all tracking. + * + * @param {integer} msgID The identifier for the message to remove from tracking. + * + * @memberof MessageTracker + * @method remove + */ + tracker.remove = function removeMessage (msgID) { + if (messages.delete(msgID) === false) { + abandoned.delete(msgID) + } + } + + /** + * Add a message handler to be tracked. + * + * @param {object} message The message object to be tracked. This object will + * have a new property added to it: `messageId`. + * @param {function} callback The handler for the message. + * + * @memberof MessageTracker + * @method track + */ + tracker.track = function trackMessage (message, callback) { + currentID = nextID() + // This side effect is not ideal but the client doesn't attach the tracker + // to itself until after the `.connect` method has fired. If this can be + // refactored later, then we can possibly get rid of this side effect. + message.messageId = currentID + messages.set(currentID, { callback, message }) + } + + return tracker +} diff --git a/node_modules/ldapjs/lib/client/message-tracker/purge-abandoned.js b/node_modules/ldapjs/lib/client/message-tracker/purge-abandoned.js new file mode 100644 index 0000000..8fc6cab --- /dev/null +++ b/node_modules/ldapjs/lib/client/message-tracker/purge-abandoned.js @@ -0,0 +1,34 @@ +'use strict' + +const { AbandonedError } = require('../../errors') +const geWindow = require('./ge-window') + +/** + * Given a `msgID` and a set of `abandoned` messages, remove any abandoned + * messages that existed _prior_ to the specified `msgID`. For example, let's + * assume the server has sent 3 messages: + * + * 1. A search message. + * 2. An abandon message for the search message. + * 3. A new search message. + * + * When the response for message #1 comes in, if it does, it will be processed + * normally due to the specification. Message #2 will not receive a response, or + * if the server does send one since the spec sort of allows it, we won't do + * anything with it because we just discard that listener. Now the response + * for message #3 comes in. At this point, we will issue a purge of responses + * by passing in `msgID = 3`. This result is that we will remove the tracking + * for message #1. + * + * @param {integer} msgID An upper bound for the messages to be purged. + * @param {Map} abandoned A set of abandoned messages. Each message is an object + * `{ age: , cb: }` where `age` was the current message id when the + * abandon message was sent. + */ +module.exports = function purgeAbandoned (msgID, abandoned) { + abandoned.forEach((val, key) => { + if (geWindow(val.age, msgID) === false) return + val.cb(new AbandonedError('client request abandoned')) + abandoned.delete(key) + }) +} diff --git a/node_modules/ldapjs/lib/client/request-queue/enqueue.js b/node_modules/ldapjs/lib/client/request-queue/enqueue.js new file mode 100644 index 0000000..e3ea6e8 --- /dev/null +++ b/node_modules/ldapjs/lib/client/request-queue/enqueue.js @@ -0,0 +1,36 @@ +'use strict' + +/** + * Adds requests to the queue. If a timeout has been added to the queue then + * this will freeze the queue with the newly added item, flush it, and then + * unfreeze it when the queue has been cleared. + * + * @param {object} message An LDAP message object. + * @param {object} expect An expectation object. + * @param {object} emitter An event emitter or `null`. + * @param {function} cb A callback to invoke when the request is finished. + * + * @returns {boolean} `true` if the requested was queued. `false` if the queue + * is not accepting any requests. + */ +module.exports = function enqueue (message, expect, emitter, cb) { + if (this._queue.size >= this.size || this._frozen) { + return false + } + + this._queue.add({ message, expect, emitter, cb }) + + if (this.timeout === 0) return true + if (this._timer === null) return true + + // A queue can have a specified time allotted for it to be cleared. If that + // time has been reached, reject new entries until the queue has been cleared. + this._timer = setTimeout(queueTimeout.bind(this), this.timeout) + + return true + + function queueTimeout () { + this.freeze() + this.purge() + } +} diff --git a/node_modules/ldapjs/lib/client/request-queue/flush.js b/node_modules/ldapjs/lib/client/request-queue/flush.js new file mode 100644 index 0000000..c0f581c --- /dev/null +++ b/node_modules/ldapjs/lib/client/request-queue/flush.js @@ -0,0 +1,24 @@ +'use strict' + +/** + * Invokes all requests in the queue by passing them to the supplied callback + * function and then clears all items from the queue. + * + * @param {function} cb A function used to handle the requests. + */ +module.exports = function flush (cb) { + if (this._timer) { + clearTimeout(this._timer) + this._timer = null + } + + // We must get a local copy of the queue and clear it before iterating it. + // The client will invoke this flush function _many_ times. If we try to + // iterate it without a local copy and clearing first then we will overflow + // the stack. + const requests = Array.from(this._queue.values()) + this._queue.clear() + for (const req of requests) { + cb(req.message, req.expect, req.emitter, req.cb) + } +} diff --git a/node_modules/ldapjs/lib/client/request-queue/index.js b/node_modules/ldapjs/lib/client/request-queue/index.js new file mode 100644 index 0000000..6fb1325 --- /dev/null +++ b/node_modules/ldapjs/lib/client/request-queue/index.js @@ -0,0 +1,39 @@ +'use strict' + +const enqueue = require('./enqueue') +const flush = require('./flush') +const purge = require('./purge') + +/** + * Builds a request queue object and returns it. + * + * @param {object} [options] + * @param {integer} [options.size] Maximum size of the request queue. Must be + * a number greater than `0` if supplied. Default: `Infinity`. + * @param {integer} [options.timeout] Time in milliseconds a queue has to + * complete the requests it contains. + * + * @returns {object} A queue instance. + */ +module.exports = function requestQueueFactory (options) { + const opts = Object.assign({}, options) + const q = { + size: (opts.size > 0) ? opts.size : Infinity, + timeout: (opts.timeout > 0) ? opts.timeout : 0, + _queue: new Set(), + _timer: null, + _frozen: false + } + + q.enqueue = enqueue.bind(q) + q.flush = flush.bind(q) + q.purge = purge.bind(q) + q.freeze = function freeze () { + this._frozen = true + } + q.thaw = function thaw () { + this._frozen = false + } + + return q +} diff --git a/node_modules/ldapjs/lib/client/request-queue/purge.js b/node_modules/ldapjs/lib/client/request-queue/purge.js new file mode 100644 index 0000000..dd0dc46 --- /dev/null +++ b/node_modules/ldapjs/lib/client/request-queue/purge.js @@ -0,0 +1,12 @@ +'use strict' + +const { TimeoutError } = require('../../errors') + +/** + * Flushes the queue by rejecting all pending requests with a timeout error. + */ +module.exports = function purge () { + this.flush(function flushCB (a, b, c, cb) { + cb(new TimeoutError('request queue timeout')) + }) +} diff --git a/node_modules/ldapjs/lib/client/search_pager.js b/node_modules/ldapjs/lib/client/search_pager.js new file mode 100644 index 0000000..a9befc2 --- /dev/null +++ b/node_modules/ldapjs/lib/client/search_pager.js @@ -0,0 +1,167 @@ +'use strict' + +const EventEmitter = require('events').EventEmitter +const util = require('util') +const assert = require('assert-plus') +const { PagedResultsControl } = require('@ldapjs/controls') +const CorkedEmitter = require('../corked_emitter.js') + +/// --- API + +/** + * Handler object for paged search operations. + * + * Provided to consumers in place of the normal search EventEmitter it adds the + * following new events: + * 1. page - Emitted whenever the end of a result page is encountered. + * If this is the last page, 'end' will also be emitted. + * The event passes two arguments: + * 1. The result object (similar to 'end') + * 2. A callback function optionally used to continue the search + * operation if the pagePause option was specified during + * initialization. + * 2. pageError - Emitted if the server does not support paged search results + * If there are no listeners for this event, the 'error' event + * will be emitted (and 'end' will not be). By listening to + * 'pageError', a successful search that lacks paging will be + * able to emit 'end'. + */ +function SearchPager (opts) { + assert.object(opts) + assert.func(opts.callback) + assert.number(opts.pageSize) + assert.func(opts.sendRequest) + + CorkedEmitter.call(this, {}) + + this.callback = opts.callback + this.controls = opts.controls + this.pageSize = opts.pageSize + this.pagePause = opts.pagePause + this.sendRequest = opts.sendRequest + + this.controls.forEach(function (control) { + if (control.type === PagedResultsControl.OID) { + // The point of using SearchPager is not having to do this. + // Toss an error if the pagedResultsControl is present + throw new Error('redundant pagedResultControl') + } + }) + + this.finished = false + this.started = false + + const emitter = new EventEmitter() + emitter.on('searchRequest', this.emit.bind(this, 'searchRequest')) + emitter.on('searchEntry', this.emit.bind(this, 'searchEntry')) + emitter.on('end', this._onEnd.bind(this)) + emitter.on('error', this._onError.bind(this)) + this.childEmitter = emitter +} +util.inherits(SearchPager, CorkedEmitter) +module.exports = SearchPager + +/** + * Start the paged search. + */ +SearchPager.prototype.begin = function begin () { + // Starting first page + this._nextPage(null) +} + +SearchPager.prototype._onEnd = function _onEnd (res) { + const self = this + let cookie = null + res.controls.forEach(function (control) { + if (control.type === PagedResultsControl.OID) { + cookie = control.value.cookie + } + }) + // Pass a noop callback by default for page events + const nullCb = function () { } + + if (cookie === null) { + // paged search not supported + this.finished = true + this.emit('page', res, nullCb) + const err = new Error('missing paged control') + err.name = 'PagedError' + if (this.listeners('pageError').length > 0) { + this.emit('pageError', err) + // If the consumer as subscribed to pageError, SearchPager is absolved + // from delivering the fault via the 'error' event. Emitting an 'end' + // event after 'error' breaks the contract that the standard client + // provides, so it's only a possibility if 'pageError' is used instead. + this.emit('end', res) + } else { + this.emit('error', err) + // No end event possible per explanation above. + } + return + } + + if (cookie.length === 0) { + // end of paged results + this.finished = true + this.emit('page', nullCb) + this.emit('end', res) + } else { + if (this.pagePause) { + // Wait to fetch next page until callback is invoked + // Halt page fetching if called with error + this.emit('page', res, function (err) { + if (!err) { + self._nextPage(cookie) + } else { + // the paged search has been canceled so emit an end + self.emit('end', res) + } + }) + } else { + this.emit('page', res, nullCb) + this._nextPage(cookie) + } + } +} + +SearchPager.prototype._onError = function _onError (err) { + this.finished = true + this.emit('error', err) +} + +/** + * Initiate a search for the next page using the returned cookie value. + */ +SearchPager.prototype._nextPage = function _nextPage (cookie) { + const controls = this.controls.slice(0) + controls.push(new PagedResultsControl({ + value: { + size: this.pageSize, + cookie + } + })) + + this.sendRequest(controls, this.childEmitter, this._sendCallback.bind(this)) +} + +/** + * Callback provided to the client API for successful transmission. + */ +SearchPager.prototype._sendCallback = function _sendCallback (err) { + if (err) { + this.finished = true + if (!this.started) { + // EmitSend error during the first page, bail via callback + this.callback(err, null) + } else { + this.emit('error', err) + } + } else { + // search successfully send + if (!this.started) { + this.started = true + // send self as emitter as the client would + this.callback(null, this) + } + } +} diff --git a/node_modules/ldapjs/lib/controls/index.js b/node_modules/ldapjs/lib/controls/index.js new file mode 100644 index 0000000..5f3dfc7 --- /dev/null +++ b/node_modules/ldapjs/lib/controls/index.js @@ -0,0 +1,4 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + +const controls = require('@ldapjs/controls') +module.exports = controls diff --git a/node_modules/ldapjs/lib/corked_emitter.js b/node_modules/ldapjs/lib/corked_emitter.js new file mode 100644 index 0000000..575014d --- /dev/null +++ b/node_modules/ldapjs/lib/corked_emitter.js @@ -0,0 +1,50 @@ +'use strict' + +const EventEmitter = require('events').EventEmitter + +/** + * A CorkedEmitter is a variant of an EventEmitter where events emitted + * wait for the appearance of the first listener of any kind. That is, + * a CorkedEmitter will store all .emit()s it receives, to be replayed + * later when an .on() is applied. + * It is meant for situations where the consumers of the emitter are + * unable to register listeners right away, and cannot afford to miss + * any events emitted from the start. + * Note that, whenever the first emitter (for any event) appears, + * the emitter becomes uncorked and works as usual for ALL events, and + * will not cache anything anymore. This is necessary to avoid + * re-ordering emits - either everything is being buffered, or nothing. + */ +function CorkedEmitter () { + const self = this + EventEmitter.call(self) + /** + * An array of arguments objects (array-likes) to emit on open. + */ + self._outstandingEmits = [] + /** + * Whether the normal flow of emits is restored yet. + */ + self._opened = false + // When the first listener appears, we enqueue an opening. + // It is not done immediately, so that other listeners can be + // registered in the same critical section. + self.once('newListener', function () { + setImmediate(function releaseStoredEvents () { + self._opened = true + self._outstandingEmits.forEach(function (args) { + self.emit.apply(self, args) + }) + }) + }) +} +CorkedEmitter.prototype = Object.create(EventEmitter.prototype) +CorkedEmitter.prototype.emit = function emit (eventName) { + if (this._opened || eventName === 'newListener') { + EventEmitter.prototype.emit.apply(this, arguments) + } else { + this._outstandingEmits.push(arguments) + } +} + +module.exports = CorkedEmitter diff --git a/node_modules/ldapjs/lib/errors/codes.js b/node_modules/ldapjs/lib/errors/codes.js new file mode 100644 index 0000000..944398a --- /dev/null +++ b/node_modules/ldapjs/lib/errors/codes.js @@ -0,0 +1,47 @@ +'use strict' + +module.exports = { + LDAP_SUCCESS: 0, + LDAP_OPERATIONS_ERROR: 1, + LDAP_PROTOCOL_ERROR: 2, + LDAP_TIME_LIMIT_EXCEEDED: 3, + LDAP_SIZE_LIMIT_EXCEEDED: 4, + LDAP_COMPARE_FALSE: 5, + LDAP_COMPARE_TRUE: 6, + LDAP_AUTH_METHOD_NOT_SUPPORTED: 7, + LDAP_STRONG_AUTH_REQUIRED: 8, + LDAP_REFERRAL: 10, + LDAP_ADMIN_LIMIT_EXCEEDED: 11, + LDAP_UNAVAILABLE_CRITICAL_EXTENSION: 12, + LDAP_CONFIDENTIALITY_REQUIRED: 13, + LDAP_SASL_BIND_IN_PROGRESS: 14, + LDAP_NO_SUCH_ATTRIBUTE: 16, + LDAP_UNDEFINED_ATTRIBUTE_TYPE: 17, + LDAP_INAPPROPRIATE_MATCHING: 18, + LDAP_CONSTRAINT_VIOLATION: 19, + LDAP_ATTRIBUTE_OR_VALUE_EXISTS: 20, + LDAP_INVALID_ATTRIBUTE_SYNTAX: 21, + LDAP_NO_SUCH_OBJECT: 32, + LDAP_ALIAS_PROBLEM: 33, + LDAP_INVALID_DN_SYNTAX: 34, + LDAP_ALIAS_DEREF_PROBLEM: 36, + LDAP_INAPPROPRIATE_AUTHENTICATION: 48, + LDAP_INVALID_CREDENTIALS: 49, + LDAP_INSUFFICIENT_ACCESS_RIGHTS: 50, + LDAP_BUSY: 51, + LDAP_UNAVAILABLE: 52, + LDAP_UNWILLING_TO_PERFORM: 53, + LDAP_LOOP_DETECT: 54, + LDAP_SORT_CONTROL_MISSING: 60, + LDAP_INDEX_RANGE_ERROR: 61, + LDAP_NAMING_VIOLATION: 64, + LDAP_OBJECTCLASS_VIOLATION: 65, + LDAP_NOT_ALLOWED_ON_NON_LEAF: 66, + LDAP_NOT_ALLOWED_ON_RDN: 67, + LDAP_ENTRY_ALREADY_EXISTS: 68, + LDAP_OBJECTCLASS_MODS_PROHIBITED: 69, + LDAP_AFFECTS_MULTIPLE_DSAS: 71, + LDAP_CONTROL_ERROR: 76, + LDAP_OTHER: 80, + LDAP_PROXIED_AUTHORIZATION_DENIED: 123 +} diff --git a/node_modules/ldapjs/lib/errors/index.js b/node_modules/ldapjs/lib/errors/index.js new file mode 100644 index 0000000..203a98b --- /dev/null +++ b/node_modules/ldapjs/lib/errors/index.js @@ -0,0 +1,147 @@ +'use strict' + +const util = require('util') +const assert = require('assert-plus') + +const LDAPResult = require('../messages').LDAPResult + +/// --- Globals + +const CODES = require('./codes') +const ERRORS = [] + +/// --- Error Base class + +function LDAPError (message, dn, caller) { + if (Error.captureStackTrace) { Error.captureStackTrace(this, caller || LDAPError) } + + this.lde_message = message + this.lde_dn = dn +} +util.inherits(LDAPError, Error) +Object.defineProperties(LDAPError.prototype, { + name: { + get: function getName () { return 'LDAPError' }, + configurable: false + }, + code: { + get: function getCode () { return CODES.LDAP_OTHER }, + configurable: false + }, + message: { + get: function getMessage () { + return this.lde_message || this.name + }, + set: function setMessage (message) { + this.lde_message = message + }, + configurable: false + }, + dn: { + get: function getDN () { + return (this.lde_dn ? this.lde_dn.toString() : '') + }, + configurable: false + } +}) + +/// --- Exported API + +module.exports = {} +module.exports.LDAPError = LDAPError + +// Some whacky games here to make sure all the codes are exported +Object.keys(CODES).forEach(function (code) { + module.exports[code] = CODES[code] + if (code === 'LDAP_SUCCESS') { return } + + let err = '' + let msg = '' + const pieces = code.split('_').slice(1) + for (let i = 0; i < pieces.length; i++) { + const lc = pieces[i].toLowerCase() + const key = lc.charAt(0).toUpperCase() + lc.slice(1) + err += key + msg += key + ((i + 1) < pieces.length ? ' ' : '') + } + + if (!/\w+Error$/.test(err)) { err += 'Error' } + + // At this point LDAP_OPERATIONS_ERROR is now OperationsError in $err + // and 'Operations Error' in $msg + module.exports[err] = function (message, dn, caller) { + LDAPError.call(this, message, dn, caller || module.exports[err]) + } + module.exports[err].constructor = module.exports[err] + util.inherits(module.exports[err], LDAPError) + Object.defineProperties(module.exports[err].prototype, { + name: { + get: function getName () { return err }, + configurable: false + }, + code: { + get: function getCode () { return CODES[code] }, + configurable: false + } + }) + + ERRORS[CODES[code]] = { + err, + message: msg + } +}) + +module.exports.getError = function (res) { + assert.ok(res instanceof LDAPResult, 'res (LDAPResult) required') + + const errObj = ERRORS[res.status] + const E = module.exports[errObj.err] + return new E(res.errorMessage || errObj.message, + res.matchedDN || null, + module.exports.getError) +} + +module.exports.getMessage = function (code) { + assert.number(code, 'code (number) required') + + const errObj = ERRORS[code] + return (errObj && errObj.message ? errObj.message : '') +} + +/// --- Custom application errors + +function ConnectionError (message) { + LDAPError.call(this, message, null, ConnectionError) +} +util.inherits(ConnectionError, LDAPError) +module.exports.ConnectionError = ConnectionError +Object.defineProperties(ConnectionError.prototype, { + name: { + get: function () { return 'ConnectionError' }, + configurable: false + } +}) + +function AbandonedError (message) { + LDAPError.call(this, message, null, AbandonedError) +} +util.inherits(AbandonedError, LDAPError) +module.exports.AbandonedError = AbandonedError +Object.defineProperties(AbandonedError.prototype, { + name: { + get: function () { return 'AbandonedError' }, + configurable: false + } +}) + +function TimeoutError (message) { + LDAPError.call(this, message, null, TimeoutError) +} +util.inherits(TimeoutError, LDAPError) +module.exports.TimeoutError = TimeoutError +Object.defineProperties(TimeoutError.prototype, { + name: { + get: function () { return 'TimeoutError' }, + configurable: false + } +}) diff --git a/node_modules/ldapjs/lib/index.js b/node_modules/ldapjs/lib/index.js new file mode 100644 index 0000000..e49ada0 --- /dev/null +++ b/node_modules/ldapjs/lib/index.js @@ -0,0 +1,84 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + +const logger = require('./logger') + +const client = require('./client') +const Attribute = require('@ldapjs/attribute') +const Change = require('@ldapjs/change') +const Protocol = require('@ldapjs/protocol') +const Server = require('./server') + +const controls = require('./controls') +const persistentSearch = require('./persistent_search') +const dn = require('@ldapjs/dn') +const errors = require('./errors') +const filters = require('@ldapjs/filter') +const messages = require('./messages') +const url = require('./url') + +const hasOwnProperty = (target, val) => Object.prototype.hasOwnProperty.call(target, val) + +/// --- API + +module.exports = { + Client: client.Client, + createClient: client.createClient, + + Server, + createServer: function (options) { + if (options === undefined) { options = {} } + + if (typeof (options) !== 'object') { throw new TypeError('options (object) required') } + + if (!options.log) { + options.log = logger + } + + return new Server(options) + }, + + Attribute, + Change, + + dn, + DN: dn.DN, + RDN: dn.RDN, + parseDN: dn.DN.fromString, + + persistentSearch, + PersistentSearchCache: persistentSearch.PersistentSearchCache, + + filters, + parseFilter: filters.parseString, + + url, + parseURL: url.parse +} + +/// --- Export all the childrenz + +let k + +for (k in Protocol) { + if (hasOwnProperty(Protocol, k)) { module.exports[k] = Protocol[k] } +} + +for (k in messages) { + if (hasOwnProperty(messages, k)) { module.exports[k] = messages[k] } +} + +for (k in controls) { + if (hasOwnProperty(controls, k)) { module.exports[k] = controls[k] } +} + +for (k in filters) { + if (hasOwnProperty(filters, k)) { + if (k !== 'parse' && k !== 'parseString') { module.exports[k] = filters[k] } + } +} + +for (k in errors) { + if (hasOwnProperty(errors, k)) { + module.exports[k] = errors[k] + } +} diff --git a/node_modules/ldapjs/lib/logger.js b/node_modules/ldapjs/lib/logger.js new file mode 100644 index 0000000..1622872 --- /dev/null +++ b/node_modules/ldapjs/lib/logger.js @@ -0,0 +1,6 @@ +'use strict' + +const logger = require('abstract-logging') +logger.child = function () { return logger } + +module.exports = logger diff --git a/node_modules/ldapjs/lib/messages/index.js b/node_modules/ldapjs/lib/messages/index.js new file mode 100644 index 0000000..8baa126 --- /dev/null +++ b/node_modules/ldapjs/lib/messages/index.js @@ -0,0 +1,39 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + +const messages = require('@ldapjs/messages') + +const Parser = require('./parser') + +const SearchResponse = require('./search_response') + +/// --- API + +module.exports = { + + LDAPMessage: messages.LdapMessage, + LDAPResult: messages.LdapResult, + Parser, + + AbandonRequest: messages.AbandonRequest, + AbandonResponse: messages.AbandonResponse, + AddRequest: messages.AddRequest, + AddResponse: messages.AddResponse, + BindRequest: messages.BindRequest, + BindResponse: messages.BindResponse, + CompareRequest: messages.CompareRequest, + CompareResponse: messages.CompareResponse, + DeleteRequest: messages.DeleteRequest, + DeleteResponse: messages.DeleteResponse, + ExtendedRequest: messages.ExtensionRequest, + ExtendedResponse: messages.ExtensionResponse, + ModifyRequest: messages.ModifyRequest, + ModifyResponse: messages.ModifyResponse, + ModifyDNRequest: messages.ModifyDnRequest, + ModifyDNResponse: messages.ModifyDnResponse, + SearchRequest: messages.SearchRequest, + SearchEntry: messages.SearchResultEntry, + SearchReference: messages.SearchResultReference, + SearchResponse, + UnbindRequest: messages.UnbindRequest + +} diff --git a/node_modules/ldapjs/lib/messages/parser.js b/node_modules/ldapjs/lib/messages/parser.js new file mode 100644 index 0000000..307d4e5 --- /dev/null +++ b/node_modules/ldapjs/lib/messages/parser.js @@ -0,0 +1,249 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + +const EventEmitter = require('events').EventEmitter +const util = require('util') + +const assert = require('assert-plus') +const asn1 = require('@ldapjs/asn1') +const logger = require('../logger') + +const messages = require('@ldapjs/messages') +const AbandonRequest = messages.AbandonRequest +const AddRequest = messages.AddRequest +const AddResponse = messages.AddResponse +const BindRequest = messages.BindRequest +const BindResponse = messages.BindResponse +const CompareRequest = messages.CompareRequest +const CompareResponse = messages.CompareResponse +const DeleteRequest = messages.DeleteRequest +const DeleteResponse = messages.DeleteResponse +const ExtendedRequest = messages.ExtensionRequest +const ExtendedResponse = messages.ExtensionResponse +const ModifyRequest = messages.ModifyRequest +const ModifyResponse = messages.ModifyResponse +const ModifyDNRequest = messages.ModifyDnRequest +const ModifyDNResponse = messages.ModifyDnResponse +const SearchRequest = messages.SearchRequest +const SearchEntry = messages.SearchResultEntry +const SearchReference = messages.SearchResultReference +const SearchResponse = require('./search_response') +const UnbindRequest = messages.UnbindRequest +const LDAPResult = messages.LdapResult + +const Protocol = require('@ldapjs/protocol') + +/// --- Globals + +const BerReader = asn1.BerReader + +/// --- API + +function Parser (options = {}) { + assert.object(options) + + EventEmitter.call(this) + + this.buffer = null + this.log = options.log || logger +} +util.inherits(Parser, EventEmitter) + +/** + * The LDAP server/client implementations will receive data from a stream and feed + * it into this method. This method will collect that data into an internal + * growing buffer. As that buffer fills with enough data to constitute a valid + * LDAP message, the data will be parsed, emitted as a message object, and + * reset the buffer to account for any next message in the stream. + */ +Parser.prototype.write = function (data) { + if (!data || !Buffer.isBuffer(data)) { throw new TypeError('data (buffer) required') } + + let nextMessage = null + const self = this + + function end () { + if (nextMessage) { return self.write(nextMessage) } + + return true + } + + self.buffer = self.buffer ? Buffer.concat([self.buffer, data]) : data + + let ber = new BerReader(self.buffer) + + let foundSeq = false + try { + foundSeq = ber.readSequence() + } catch (e) { + this.emit('error', e) + } + + if (!foundSeq || ber.remain < ber.length) { + // ENOTENOUGH + return false + } else if (ber.remain > ber.length) { + // ETOOMUCH + + // This is an odd branch. Basically, it is setting `nextMessage` to + // a buffer that represents data part of a message subsequent to the one + // being processed. It then re-creates `ber` as a representation of + // the message being processed and advances its offset to the value + // position of the TLV. + + // Set `nextMessage` to the bytes subsequent to the current message's + // value bytes. That is, slice from the byte immediately following the + // current message's value bytes until the end of the buffer. + nextMessage = self.buffer.slice(ber.offset + ber.length) + + const currOffset = ber.offset + ber = new BerReader(ber.buffer.subarray(0, currOffset + ber.length)) + ber.readSequence() + + assert.equal(ber.remain, ber.length) + } + + // If we're here, ber holds the message, and nextMessage is temporarily + // pointing at the next sequence of data (if it exists) + self.buffer = null + + let message + try { + if (Object.prototype.toString.call(ber) === '[object BerReader]') { + // Parse the BER into a JavaScript object representation. The message + // objects require the full sequence in order to construct the object. + // At this point, we have already read the sequence tag and length, so + // we need to rewind the buffer a bit. The `.sequenceToReader` method + // does this for us. + message = messages.LdapMessage.parse(ber.sequenceToReader()) + } else { + // Bail here if peer isn't speaking protocol at all + message = this.getMessage(ber) + } + + if (!message) { + return end() + } + + // TODO: find a better way to handle logging now that messages and the + // server are decoupled. ~ jsumners 2023-02-17 + message.log = this.log + } catch (e) { + this.emit('error', e, message) + return false + } + + this.emit('message', message) + return end() +} + +Parser.prototype.getMessage = function (ber) { + assert.ok(ber) + + const self = this + + const messageId = ber.readInt() + const type = ber.readSequence() + + let Message + switch (type) { + case Protocol.operations.LDAP_REQ_ABANDON: + Message = AbandonRequest + break + + case Protocol.operations.LDAP_REQ_ADD: + Message = AddRequest + break + + case Protocol.operations.LDAP_RES_ADD: + Message = AddResponse + break + + case Protocol.operations.LDAP_REQ_BIND: + Message = BindRequest + break + + case Protocol.operations.LDAP_RES_BIND: + Message = BindResponse + break + + case Protocol.operations.LDAP_REQ_COMPARE: + Message = CompareRequest + break + + case Protocol.operations.LDAP_RES_COMPARE: + Message = CompareResponse + break + + case Protocol.operations.LDAP_REQ_DELETE: + Message = DeleteRequest + break + + case Protocol.operations.LDAP_RES_DELETE: + Message = DeleteResponse + break + + case Protocol.operations.LDAP_REQ_EXTENSION: + Message = ExtendedRequest + break + + case Protocol.operations.LDAP_RES_EXTENSION: + Message = ExtendedResponse + break + + case Protocol.operations.LDAP_REQ_MODIFY: + Message = ModifyRequest + break + + case Protocol.operations.LDAP_RES_MODIFY: + Message = ModifyResponse + break + + case Protocol.operations.LDAP_REQ_MODRDN: + Message = ModifyDNRequest + break + + case Protocol.operations.LDAP_RES_MODRDN: + Message = ModifyDNResponse + break + + case Protocol.operations.LDAP_REQ_SEARCH: + Message = SearchRequest + break + + case Protocol.operations.LDAP_RES_SEARCH_ENTRY: + Message = SearchEntry + break + + case Protocol.operations.LDAP_RES_SEARCH_REF: + Message = SearchReference + break + + case Protocol.operations.LDAP_RES_SEARCH: + Message = SearchResponse + break + + case Protocol.operations.LDAP_REQ_UNBIND: + Message = UnbindRequest + break + + default: + this.emit('error', + new Error('Op 0x' + (type ? type.toString(16) : '??') + + ' not supported'), + new LDAPResult({ + messageId, + protocolOp: type || Protocol.operations.LDAP_RES_EXTENSION + })) + + return false + } + + return new Message({ + messageId, + log: self.log + }) +} + +/// --- Exports + +module.exports = Parser diff --git a/node_modules/ldapjs/lib/messages/search_response.js b/node_modules/ldapjs/lib/messages/search_response.js new file mode 100644 index 0000000..c9d88c6 --- /dev/null +++ b/node_modules/ldapjs/lib/messages/search_response.js @@ -0,0 +1,122 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + +const assert = require('assert-plus') + +const Attribute = require('@ldapjs/attribute') +const { + SearchResultEntry: SearchEntry, + SearchResultReference: SearchReference, + SearchResultDone +} = require('@ldapjs/messages') + +const parseDN = require('@ldapjs/dn').DN.fromString + +/// --- API + +class SearchResponse extends SearchResultDone { + attributes + notAttributes + sentEntries + + constructor (options = {}) { + super(options) + + this.attributes = options.attributes ? options.attributes.slice() : [] + this.notAttributes = [] + this.sentEntries = 0 + } +} + +/** + * Allows you to send a SearchEntry back to the client. + * + * @param {Object} entry an instance of SearchEntry. + * @param {Boolean} nofiltering skip filtering notAttributes and '_' attributes. + * Defaults to 'false'. + */ +SearchResponse.prototype.send = function (entry, nofiltering) { + if (!entry || typeof (entry) !== 'object') { throw new TypeError('entry (SearchEntry) required') } + if (nofiltering === undefined) { nofiltering = false } + if (typeof (nofiltering) !== 'boolean') { throw new TypeError('noFiltering must be a boolean') } + + const self = this + + const savedAttrs = {} + let save = null + if (entry instanceof SearchEntry || entry instanceof SearchReference) { + if (!entry.messageId) { entry.messageId = this.messageId } + if (entry.messageId !== this.messageId) { + throw new Error('SearchEntry messageId mismatch') + } + } else { + if (!entry.attributes) { throw new Error('entry.attributes required') } + + const all = (self.attributes.indexOf('*') !== -1) + // Filter attributes in a plain object according to the magic `_` prefix + // and presence in `notAttributes`. + Object.keys(entry.attributes).forEach(function (a) { + const _a = a.toLowerCase() + if (!nofiltering && _a.length && _a[0] === '_') { + savedAttrs[a] = entry.attributes[a] + delete entry.attributes[a] + } else if (!nofiltering && self.notAttributes.indexOf(_a) !== -1) { + savedAttrs[a] = entry.attributes[a] + delete entry.attributes[a] + } else if (all) { + // do nothing + } else if (self.attributes.length && self.attributes.indexOf(_a) === -1) { + savedAttrs[a] = entry.attributes[a] + delete entry.attributes[a] + } + }) + + save = entry + entry = new SearchEntry({ + objectName: typeof (save.dn) === 'string' ? parseDN(save.dn) : save.dn, + messageId: self.messageId, + attributes: Attribute.fromObject(entry.attributes) + }) + } + + try { + this.log.debug('%s: sending: %j', this.connection.ldap.id, entry.pojo) + + this.connection.write(entry.toBer().buffer) + this.sentEntries++ + + // Restore attributes + Object.keys(savedAttrs).forEach(function (k) { + save.attributes[k] = savedAttrs[k] + }) + } catch (e) { + this.log.warn(e, '%s failure to write message %j', + this.connection.ldap.id, this.pojo) + } +} + +SearchResponse.prototype.createSearchEntry = function (object) { + assert.object(object) + + const entry = new SearchEntry({ + messageId: this.messageId, + objectName: object.objectName || object.dn, + attributes: object.attributes ?? [] + }) + return entry +} + +SearchResponse.prototype.createSearchReference = function (uris) { + if (!uris) { throw new TypeError('uris ([string]) required') } + + if (!Array.isArray(uris)) { uris = [uris] } + + const self = this + return new SearchReference({ + messageId: self.messageId, + uri: uris + }) +} + +/// --- Exports + +module.exports = SearchResponse diff --git a/node_modules/ldapjs/lib/persistent_search.js b/node_modules/ldapjs/lib/persistent_search.js new file mode 100644 index 0000000..ecfdc75 --- /dev/null +++ b/node_modules/ldapjs/lib/persistent_search.js @@ -0,0 +1,109 @@ +/// --- Globals + +// var parseDN = require('./dn').parse + +const EntryChangeNotificationControl = + require('./controls').EntryChangeNotificationControl + +/// --- API + +// Cache used to store connected persistent search clients +function PersistentSearch () { + this.clientList = [] +} + +PersistentSearch.prototype.addClient = function (req, res, callback) { + if (typeof (req) !== 'object') { throw new TypeError('req must be an object') } + if (typeof (res) !== 'object') { throw new TypeError('res must be an object') } + if (callback && typeof (callback) !== 'function') { throw new TypeError('callback must be a function') } + + const log = req.log + + const client = {} + client.req = req + client.res = res + + log.debug('%s storing client', req.logId) + + this.clientList.push(client) + + log.debug('%s stored client', req.logId) + log.debug('%s total number of clients %s', + req.logId, this.clientList.length) + if (callback) { callback(client) } +} + +PersistentSearch.prototype.removeClient = function (req, res, callback) { + if (typeof (req) !== 'object') { throw new TypeError('req must be an object') } + if (typeof (res) !== 'object') { throw new TypeError('res must be an object') } + if (callback && typeof (callback) !== 'function') { throw new TypeError('callback must be a function') } + + const log = req.log + log.debug('%s removing client', req.logId) + const client = {} + client.req = req + client.res = res + + // remove the client if it exists + this.clientList.forEach(function (element, index, array) { + if (element.req === client.req) { + log.debug('%s removing client from list', req.logId) + array.splice(index, 1) + } + }) + + log.debug('%s number of persistent search clients %s', + req.logId, this.clientList.length) + if (callback) { callback(client) } +} + +function getOperationType (requestType) { + switch (requestType) { + case 'AddRequest': + case 'add': + return 1 + case 'DeleteRequest': + case 'delete': + return 2 + case 'ModifyRequest': + case 'modify': + return 4 + case 'ModifyDNRequest': + case 'modrdn': + return 8 + default: + throw new TypeError('requestType %s, is an invalid request type', + requestType) + } +} + +function getEntryChangeNotificationControl (req, obj) { + // if we want to return a ECNC + if (req.persistentSearch.value.returnECs) { + const attrs = obj.attributes + const value = {} + value.changeType = getOperationType(attrs.changetype) + // if it's a modDN request, fill in the previous DN + if (value.changeType === 8 && attrs.previousDN) { + value.previousDN = attrs.previousDN + } + + value.changeNumber = attrs.changenumber + return new EntryChangeNotificationControl({ value }) + } else { + return false + } +} + +function checkChangeType (req, requestType) { + return (req.persistentSearch.value.changeTypes & + getOperationType(requestType)) +} + +/// --- Exports + +module.exports = { + PersistentSearchCache: PersistentSearch, + checkChangeType, + getEntryChangeNotificationControl +} diff --git a/node_modules/ldapjs/lib/server.js b/node_modules/ldapjs/lib/server.js new file mode 100644 index 0000000..059de94 --- /dev/null +++ b/node_modules/ldapjs/lib/server.js @@ -0,0 +1,917 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + +const assert = require('assert') +const EventEmitter = require('events').EventEmitter +const net = require('net') +const tls = require('tls') +const util = require('util') + +// var asn1 = require('@ldapjs/asn1') +const VError = require('verror').VError + +const { DN, RDN } = require('@ldapjs/dn') +const errors = require('./errors') +const Protocol = require('@ldapjs/protocol') + +const messages = require('@ldapjs/messages') + +const Parser = require('./messages').Parser +const LdapResult = messages.LdapResult +const AbandonResponse = messages.AbandonResponse +const AddResponse = messages.AddResponse +const BindResponse = messages.BindResponse +const CompareResponse = messages.CompareResponse +const DeleteResponse = messages.DeleteResponse +const ExtendedResponse = messages.ExtensionResponse +const ModifyResponse = messages.ModifyResponse +const ModifyDnResponse = messages.ModifyDnResponse +const SearchRequest = messages.SearchRequest +const SearchResponse = require('./messages/search_response') + +/// --- Globals + +// var Ber = asn1.Ber +// var BerReader = asn1.BerReader +// const DN = dn.DN + +// var sprintf = util.format + +/// --- Helpers + +function mergeFunctionArgs (argv, start, end) { + assert.ok(argv) + + if (!start) { start = 0 } + if (!end) { end = argv.length } + + const handlers = [] + + for (let i = start; i < end; i++) { + if (Array.isArray(argv[i])) { + const arr = argv[i] + for (let j = 0; j < arr.length; j++) { + if (typeof arr[j] !== 'function') { + throw new TypeError('Invalid argument type: ' + typeof (arr[j])) + } + handlers.push(arr[j]) + } + } else if (typeof argv[i] === 'function') { + handlers.push(argv[i]) + } else { + throw new TypeError('Invalid argument type: ' + typeof (argv[i])) + } + } + + return handlers +} + +function getResponse (req) { + assert.ok(req) + + let Response + + switch (req.protocolOp) { + case Protocol.operations.LDAP_REQ_BIND: + Response = BindResponse + break + case Protocol.operations.LDAP_REQ_ABANDON: + Response = AbandonResponse + break + case Protocol.operations.LDAP_REQ_ADD: + Response = AddResponse + break + case Protocol.operations.LDAP_REQ_COMPARE: + Response = CompareResponse + break + case Protocol.operations.LDAP_REQ_DELETE: + Response = DeleteResponse + break + case Protocol.operations.LDAP_REQ_EXTENSION: + Response = ExtendedResponse + break + case Protocol.operations.LDAP_REQ_MODIFY: + Response = ModifyResponse + break + case Protocol.operations.LDAP_REQ_MODRDN: + Response = ModifyDnResponse + break + case Protocol.operations.LDAP_REQ_SEARCH: + Response = SearchResponse + break + case Protocol.operations.LDAP_REQ_UNBIND: + // TODO: when the server receives an unbind request this made up response object was returned. + // Instead, we need to just terminate the connection. ~ jsumners + Response = class extends LdapResult { + status = 0 + end () { + req.connection.end() + } + } + break + default: + return null + } + assert.ok(Response) + + const res = new Response({ + messageId: req.messageId, + attributes: ((req instanceof SearchRequest) ? req.attributes : undefined) + }) + res.log = req.log + res.connection = req.connection + res.logId = req.logId + + if (typeof res.end !== 'function') { + // This is a hack to re-add the original tight coupling of the message + // objects and the server connection. + // TODO: remove this during server refactoring ~ jsumners 2023-02-16 + switch (res.protocolOp) { + case 0: { + res.end = abandonResponseEnd + break + } + + case Protocol.operations.LDAP_RES_COMPARE: { + res.end = compareResponseEnd + break + } + + default: { + res.end = defaultResponseEnd + break + } + } + } + + return res +} + +/** + * Response connection end handler for most responses. + * + * @param {number} status + */ +function defaultResponseEnd (status) { + if (typeof status === 'number') { this.status = status } + + const ber = this.toBer() + this.log.debug('%s: sending: %j', this.connection.ldap.id, this.pojo) + + try { + this.connection.write(ber.buffer) + } catch (error) { + this.log.warn( + error, + '%s failure to write message %j', + this.connection.ldap.id, + this.pojo + ) + } +} + +/** + * Response connection end handler for ABANDON responses. + */ +function abandonResponseEnd () {} + +/** + * Response connection end handler for COMPARE responses. + * + * @param {number | boolean} status + */ +function compareResponseEnd (status) { + let result = 0x06 + if (typeof status === 'boolean') { + if (status === false) { + result = 0x05 + } + } else { + result = status + } + return defaultResponseEnd.call(this, result) +} + +function defaultHandler (req, res, next) { + assert.ok(req) + assert.ok(res) + assert.ok(next) + + res.matchedDN = req.dn.toString() + res.errorMessage = 'Server method not implemented' + res.end(errors.LDAP_OTHER) + return next() +} + +function defaultNoOpHandler (req, res, next) { + assert.ok(req) + assert.ok(res) + assert.ok(next) + + res.end() + return next() +} + +function noSuffixHandler (req, res, next) { + assert.ok(req) + assert.ok(res) + assert.ok(next) + + res.errorMessage = 'No tree found for: ' + req.dn.toString() + res.end(errors.LDAP_NO_SUCH_OBJECT) + return next() +} + +function noExOpHandler (req, res, next) { + assert.ok(req) + assert.ok(res) + assert.ok(next) + + res.errorMessage = req.requestName + ' not supported' + res.end(errors.LDAP_PROTOCOL_ERROR) + return next() +} + +/// --- API + +/** + * Constructs a new server that you can call .listen() on, in the various + * forms node supports. You need to first assign some handlers to the various + * LDAP operations however. + * + * The options object currently only takes a certificate/private key, and a + * bunyan logger handle. + * + * This object exposes the following events: + * - 'error' + * - 'close' + * + * @param {Object} options (optional) parameterization object. + * @throws {TypeError} on bad input. + */ +function Server (options) { + if (options) { + if (typeof (options) !== 'object') { throw new TypeError('options (object) required') } + if (typeof (options.log) !== 'object') { throw new TypeError('options.log must be an object') } + + if (options.certificate || options.key) { + if (!(options.certificate && options.key) || + (typeof (options.certificate) !== 'string' && + !Buffer.isBuffer(options.certificate)) || + (typeof (options.key) !== 'string' && + !Buffer.isBuffer(options.key))) { + throw new TypeError('options.certificate and options.key ' + + '(string or buffer) are both required for TLS') + } + } + } else { + options = {} + } + const self = this + + EventEmitter.call(this, options) + + this._chain = [] + this.log = options.log + const log = this.log + + function setupConnection (c) { + assert.ok(c) + + if (c.type === 'unix') { + c.remoteAddress = self.server.path + c.remotePort = c.fd + } else if (c.socket) { + // TLS + c.remoteAddress = c.socket.remoteAddress + c.remotePort = c.socket.remotePort + } + + const rdn = new RDN({ cn: 'anonymous' }) + + c.ldap = { + id: c.remoteAddress + ':' + c.remotePort, + config: options, + _bindDN: new DN({ rdns: [rdn] }) + } + c.addListener('timeout', function () { + log.trace('%s timed out', c.ldap.id) + c.destroy() + }) + c.addListener('end', function () { + log.trace('%s shutdown', c.ldap.id) + }) + c.addListener('error', function (err) { + log.warn('%s unexpected connection error', c.ldap.id, err) + self.emit('clientError', err) + c.destroy() + }) + c.addListener('close', function (closeError) { + log.trace('%s close; had_err=%j', c.ldap.id, closeError) + c.end() + }) + + c.ldap.__defineGetter__('bindDN', function () { + return c.ldap._bindDN + }) + c.ldap.__defineSetter__('bindDN', function (val) { + if (Object.prototype.toString.call(val) !== '[object LdapDn]') { + throw new TypeError('DN required') + } + + c.ldap._bindDN = val + return val + }) + return c + } + + self.newConnection = function (conn) { + // TODO: make `newConnection` available on the `Server` prototype + // https://github.com/ldapjs/node-ldapjs/pull/727/files#r636572294 + setupConnection(conn) + log.trace('new connection from %s', conn.ldap.id) + + conn.parser = new Parser({ + log: options.log + }) + conn.parser.on('message', function (req) { + // TODO: this is mutating the `@ldapjs/message` objects. + // We should avoid doing that. ~ jsumners 2023-02-16 + req.connection = conn + req.logId = conn.ldap.id + '::' + req.messageId + req.startTime = new Date().getTime() + + log.debug('%s: message received: req=%j', conn.ldap.id, req.pojo) + + const res = getResponse(req) + if (!res) { + log.warn('Unimplemented server method: %s', req.type) + conn.destroy() + return false + } + + // parse string DNs for routing/etc + try { + switch (req.protocolOp) { + case Protocol.operations.LDAP_REQ_BIND: { + req.name = DN.fromString(req.name) + break + } + + case Protocol.operations.LDAP_REQ_ADD: + case Protocol.operations.LDAP_REQ_COMPARE: + case Protocol.operations.LDAP_REQ_DELETE: { + if (typeof req.entry === 'string') { + req.entry = DN.fromString(req.entry) + } else if (Object.prototype.toString.call(req.entry) !== '[object LdapDn]') { + throw Error('invalid entry object for operation') + } + break + } + + case Protocol.operations.LDAP_REQ_MODIFY: { + req.object = DN.fromString(req.object) + break + } + + case Protocol.operations.LDAP_REQ_MODRDN: { + if (typeof req.entry === 'string') { + req.entry = DN.fromString(req.entry) + } else if (Object.prototype.toString.call(req.entry) !== '[object LdapDn]') { + throw Error('invalid entry object for operation') + } + // TODO: handle newRdn/Superior + break + } + + case Protocol.operations.LDAP_REQ_SEARCH: { + break + } + + default: { + break + } + } + } catch (e) { + return res.end(errors.LDAP_INVALID_DN_SYNTAX) + } + + res.connection = conn + res.logId = req.logId + res.requestDN = req.dn + + const chain = self._getHandlerChain(req, res) + + let i = 0 + return (function messageIIFE (err) { + function sendError (sendErr) { + res.status = sendErr.code || errors.LDAP_OPERATIONS_ERROR + res.matchedDN = req.suffix ? req.suffix.toString() : '' + res.errorMessage = sendErr.message || '' + return res.end() + } + + function after () { + if (!self._postChain || !self._postChain.length) { return } + + function next () {} // stub out next for the post chain + + self._postChain.forEach(function (cb) { + cb.call(self, req, res, next) + }) + } + + if (err) { + log.trace('%s sending error: %s', req.logId, err.stack || err) + self.emit('clientError', err) + sendError(err) + return after() + } + + try { + const next = messageIIFE + if (chain.handlers[i]) { return chain.handlers[i++].call(chain.backend, req, res, next) } + + if (req.protocolOp === Protocol.operations.LDAP_REQ_BIND && res.status === 0) { + // 0 length == anonymous bind + if (req.dn.length === 0 && req.credentials === '') { + conn.ldap.bindDN = new DN({ rdns: [new RDN({ cn: 'anonymous' })] }) + } else { + conn.ldap.bindDN = DN.fromString(req.dn) + } + } + + // unbind clear bindDN for safety + // conn should terminate on unbind (RFC4511 4.3) + if (req.protocolOp === Protocol.operations.LDAP_REQ_UNBIND && res.status === 0) { + conn.ldap.bindDN = new DN({ rdns: [new RDN({ cn: 'anonymous' })] }) + } + + return after() + } catch (e) { + if (!e.stack) { e.stack = e.toString() } + log.error('%s uncaught exception: %s', req.logId, e.stack) + return sendError(new errors.OperationsError(e.message)) + } + }()) + }) + + conn.parser.on('error', function (err, message) { + self.emit('error', new VError(err, 'Parser error for %s', conn.ldap.id)) + + if (!message) { return conn.destroy() } + + const res = getResponse(message) + if (!res) { return conn.destroy() } + + res.status = 0x02 // protocol error + res.errorMessage = err.toString() + return conn.end(res.toBer()) + }) + + conn.on('data', function (data) { + log.trace('data on %s: %s', conn.ldap.id, util.inspect(data)) + + conn.parser.write(data) + }) + } // end newConnection + + this.routes = {} + if ((options.cert || options.certificate) && options.key) { + options.cert = options.cert || options.certificate + this.server = tls.createServer(options, options.connectionRouter ? options.connectionRouter : self.newConnection) + } else { + this.server = net.createServer(options.connectionRouter ? options.connectionRouter : self.newConnection) + } + this.server.log = options.log + this.server.ldap = { + config: options + } + this.server.on('close', function () { + self.emit('close') + }) + this.server.on('error', function (err) { + self.emit('error', err) + }) +} +util.inherits(Server, EventEmitter) +Object.defineProperties(Server.prototype, { + maxConnections: { + get: function getMaxConnections () { + return this.server.maxConnections + }, + set: function setMaxConnections (val) { + this.server.maxConnections = val + }, + configurable: false + }, + connections: { + get: function getConnections () { + return this.server.connections + }, + configurable: false + }, + name: { + get: function getName () { + return 'LDAPServer' + }, + configurable: false + }, + url: { + get: function getURL () { + let str + const addr = this.server.address() + if (!addr) { + return null + } + if (!addr.family) { + str = 'ldapi://' + str += this.host.replace(/\//g, '%2f') + return str + } + if (this.server instanceof tls.Server) { + str = 'ldaps://' + } else { + str = 'ldap://' + } + + let host = this.host + // Node 18 switched family from returning a string to returning a number + // https://nodejs.org/api/net.html#serveraddress + if (addr.family === 'IPv6' || addr.family === 6) { + host = '[' + this.host + ']' + } + + str += host + ':' + this.port + return str + }, + configurable: false + } +}) +module.exports = Server + +/** + * Adds a handler (chain) for the LDAP add method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.add = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_ADD, name, args) +} + +/** + * Adds a handler (chain) for the LDAP bind method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.bind = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_BIND, name, args) +} + +/** + * Adds a handler (chain) for the LDAP compare method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.compare = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_COMPARE, name, args) +} + +/** + * Adds a handler (chain) for the LDAP delete method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.del = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_DELETE, name, args) +} + +/** + * Adds a handler (chain) for the LDAP exop method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name OID to assign this handler chain to. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input. + */ +Server.prototype.exop = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_EXTENSION, name, args, true) +} + +/** + * Adds a handler (chain) for the LDAP modify method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.modify = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_MODIFY, name, args) +} + +/** + * Adds a handler (chain) for the LDAP modifyDN method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.modifyDN = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_MODRDN, name, args) +} + +/** + * Adds a handler (chain) for the LDAP search method. + * + * Note that this is of the form f(name, [function]) where the second...N + * arguments can all either be functions or arrays of functions. + * + * @param {String} name the DN to mount this handler chain at. + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.search = function (name) { + const args = Array.prototype.slice.call(arguments, 1) + return this._mount(Protocol.operations.LDAP_REQ_SEARCH, name, args) +} + +/** + * Adds a handler (chain) for the LDAP unbind method. + * + * This method is different than the others and takes no mount point, as unbind + * is a connection-wide operation, not constrianed to part of the DIT. + * + * @return {Server} this so you can chain calls. + * @throws {TypeError} on bad input + */ +Server.prototype.unbind = function () { + const args = Array.prototype.slice.call(arguments, 0) + return this._mount(Protocol.operations.LDAP_REQ_UNBIND, 'unbind', args, true) +} + +Server.prototype.use = function use () { + const args = Array.prototype.slice.call(arguments) + const chain = mergeFunctionArgs(args, 0, args.length) + const self = this + chain.forEach(function (c) { + self._chain.push(c) + }) +} + +Server.prototype.after = function () { + if (!this._postChain) { this._postChain = [] } + + const self = this + mergeFunctionArgs(arguments).forEach(function (h) { + self._postChain.push(h) + }) +} + +// All these just re-expose the requisite net.Server APIs +Server.prototype.listen = function (port, host, callback) { + if (typeof (port) !== 'number' && typeof (port) !== 'string') { throw new TypeError('port (number or path) required') } + + if (typeof (host) === 'function') { + callback = host + host = '127.0.0.1' + } + if (typeof (port) === 'string' && /^[0-9]+$/.test(port)) { + // Disambiguate between string ports and file paths + port = parseInt(port, 10) + } + const self = this + + function cbListen () { + if (typeof (port) === 'number') { + self.host = self.address().address + self.port = self.address().port + } else { + self.host = port + self.port = self.server.fd + } + + if (typeof (callback) === 'function') { callback() } + } + + if (typeof (port) === 'number') { + return this.server.listen(port, host, cbListen) + } else { + return this.server.listen(port, cbListen) + } +} +Server.prototype.listenFD = function (fd) { + this.host = 'unix-domain-socket' + this.port = fd + return this.server.listenFD(fd) +} +Server.prototype.close = function (callback) { + return this.server.close(callback) +} +Server.prototype.address = function () { + return this.server.address() +} + +Server.prototype.getConnections = function (callback) { + return this.server.getConnections(callback) +} + +Server.prototype._getRoute = function (_dn, backend) { + if (!backend) { backend = this } + + let name + if (Object.prototype.toString.call(_dn) === '[object LdapDn]') { + name = _dn.toString() + } else { + name = _dn + } + + if (!this.routes[name]) { + this.routes[name] = {} + this.routes[name].backend = backend + this.routes[name].dn = _dn + // Force regeneration of the route key cache on next request + this._routeKeyCache = null + } + + return this.routes[name] +} + +Server.prototype._sortedRouteKeys = function _sortedRouteKeys () { + // The filtered/sorted route keys are cached to prevent needlessly + // regenerating the list for every incoming request. + if (!this._routeKeyCache) { + const self = this + const reversedRDNsToKeys = {} + // Generate mapping of reversedRDNs(DN) -> routeKey + Object.keys(this.routes).forEach(function (key) { + const _dn = self.routes[key].dn + // Ignore non-DN routes such as exop or unbind + if (Object.prototype.toString.call(_dn) === '[object LdapDn]') { + const reversed = _dn.clone() + reversed.reverse() + reversedRDNsToKeys[reversed.toString()] = key + } + }) + const output = [] + // Reverse-sort on reversedRDS(DN) in order to output routeKey list. + // This will place more specific DNs in front of their parents: + // 1. dc=test, dc=domain, dc=sub + // 2. dc=test, dc=domain + // 3. dc=other, dc=foobar + Object.keys(reversedRDNsToKeys).sort().reverse().forEach(function (_dn) { + output.push(reversedRDNsToKeys[_dn]) + }) + this._routeKeyCache = output + } + return this._routeKeyCache +} + +Server.prototype._getHandlerChain = function _getHandlerChain (req) { + assert.ok(req) + + const self = this + const routes = this.routes + let route + + // check anonymous bind + if (req.protocolOp === Protocol.operations.LDAP_REQ_BIND && + req.dn.toString() === '' && + req.credentials === '') { + return { + backend: self, + handlers: [defaultNoOpHandler] + } + } + + const op = '0x' + req.protocolOp.toString(16) + + // Special cases are exops, unbinds and abandons. Handle those first. + if (req.protocolOp === Protocol.operations.LDAP_REQ_EXTENSION) { + route = routes[req.requestName] + if (route) { + return { + backend: route.backend, + handlers: (route[op] ? route[op] : [noExOpHandler]) + } + } else { + return { + backend: self, + handlers: [noExOpHandler] + } + } + } else if (req.protocolOp === Protocol.operations.LDAP_REQ_UNBIND) { + route = routes.unbind + if (route) { + return { + backend: route.backend, + handlers: route[op] + } + } else { + return { + backend: self, + handlers: [defaultNoOpHandler] + } + } + } else if (req.protocolOp === Protocol.operations.LDAP_REQ_ABANDON) { + return { + backend: self, + handlers: [defaultNoOpHandler] + } + } + + // Otherwise, match via DN rules + const keys = this._sortedRouteKeys() + let fallbackHandler = [noSuffixHandler] + // invalid DNs in non-strict mode are routed to the default handler + const testDN = (typeof (req.dn) === 'string') ? DN.fromString(req.dn) : req.dn + assert.ok(testDN) + + for (let i = 0; i < keys.length; i++) { + const suffix = keys[i] + route = routes[suffix] + assert.ok(route.dn) + // Match a valid route or the route wildcard ('') + if (route.dn.equals(testDN) || route.dn.parentOf(testDN) || suffix === '') { + if (route[op]) { + // We should be good to go. + req.suffix = route.dn + return { + backend: route.backend, + handlers: route[op] + } + } else { + if (suffix === '') { + break + } else { + // We found a valid suffix but not a valid operation. + // There might be a more generic suffix with a legitimate operation. + fallbackHandler = [defaultHandler] + } + } + } + } + return { + backend: self, + handlers: fallbackHandler + } +} + +Server.prototype._mount = function (op, name, argv, notDN) { + assert.ok(op) + assert.ok(name !== undefined) + assert.ok(argv) + + if (typeof (name) !== 'string') { throw new TypeError('name (string) required') } + if (!argv.length) { throw new Error('at least one handler required') } + + let backend = this + let index = 0 + + if (typeof (argv[0]) === 'object' && !Array.isArray(argv[0])) { + backend = argv[0] + index = 1 + } + const route = this._getRoute(notDN ? name : DN.fromString(name), backend) + + const chain = this._chain.slice() + argv.slice(index).forEach(function (a) { + chain.push(a) + }) + route['0x' + op.toString(16)] = mergeFunctionArgs(chain) + + return this +} diff --git a/node_modules/ldapjs/lib/url.js b/node_modules/ldapjs/lib/url.js new file mode 100644 index 0000000..d9e190c --- /dev/null +++ b/node_modules/ldapjs/lib/url.js @@ -0,0 +1,72 @@ +'use strict' + +const querystring = require('querystring') +const url = require('url') +const { DN } = require('@ldapjs/dn') +const filter = require('@ldapjs/filter') + +module.exports = { + + parse: function (urlStr, parseDN) { + let parsedURL + try { + parsedURL = new url.URL(urlStr) + } catch (error) { + throw new TypeError(urlStr + ' is an invalid LDAP url (scope)') + } + + if (!parsedURL.protocol || !(parsedURL.protocol === 'ldap:' || parsedURL.protocol === 'ldaps:')) { throw new TypeError(urlStr + ' is an invalid LDAP url (protocol)') } + + const u = { + protocol: parsedURL.protocol, + hostname: parsedURL.hostname, + port: parsedURL.port, + pathname: parsedURL.pathname, + search: parsedURL.search, + href: parsedURL.href + } + + u.secure = (u.protocol === 'ldaps:') + + if (!u.hostname) { u.hostname = 'localhost' } + + if (!u.port) { + u.port = (u.secure ? 636 : 389) + } else { + u.port = parseInt(u.port, 10) + } + + if (u.pathname) { + u.pathname = querystring.unescape(u.pathname.substr(1)) + u.DN = parseDN ? DN.fromString(u.pathname) : u.pathname + } + + if (u.search) { + u.attributes = [] + const tmp = u.search.substr(1).split('?') + if (tmp && tmp.length) { + if (tmp[0]) { + tmp[0].split(',').forEach(function (a) { + u.attributes.push(querystring.unescape(a.trim())) + }) + } + } + if (tmp[1]) { + if (tmp[1] !== 'base' && tmp[1] !== 'one' && tmp[1] !== 'sub') { throw new TypeError(urlStr + ' is an invalid LDAP url (scope)') } + u.scope = tmp[1] + } + if (tmp[2]) { + u.filter = querystring.unescape(tmp[2]) + } + if (tmp[3]) { + u.extensions = querystring.unescape(tmp[3]) + } + + if (!u.scope) { u.scope = 'base' } + if (!u.filter) { u.filter = filter.parseString('(objectclass=*)') } else { u.filter = filter.parseString(u.filter) } + } + + return u + } + +} diff --git a/node_modules/ldapjs/package.json b/node_modules/ldapjs/package.json new file mode 100644 index 0000000..e814f0e --- /dev/null +++ b/node_modules/ldapjs/package.json @@ -0,0 +1,59 @@ +{ + "originalAuthor": "Mark Cavage ", + "name": "ldapjs", + "homepage": "http://ldapjs.org", + "description": "LDAP client and server APIs", + "version": "3.0.7", + "license": "MIT", + "repository": { + "type": "git", + "url": "git://github.com/ldapjs/node-ldapjs.git" + }, + "main": "lib/index.js", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/messages": "^1.3.0", + "@ldapjs/protocol": "^1.2.1", + "abstract-logging": "^2.0.1", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "once": "^1.4.0", + "vasync": "^2.2.1", + "verror": "^1.10.1" + }, + "devDependencies": { + "@fastify/pre-commit": "^2.0.2", + "eslint": "^8.44.0", + "eslint-config-standard": "^17.0.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-n": "^16.0.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "6.1.1", + "front-matter": "^4.0.2", + "get-port": "^5.1.1", + "highlight.js": "^11.7.0", + "marked": "^4.2.12", + "tap": "^16.3.7" + }, + "scripts": { + "test": "tap --no-cov -R terse", + "test:ci": "tap --coverage-report=lcovonly -R terse", + "test:cov": "tap -R terse", + "test:cov:html": "tap --coverage-report=html -R terse", + "test:watch": "tap -n -w --no-coverage-report -R terse", + "test:integration": "tap --no-cov -R terse 'test-integration/**/*.test.js'", + "test:integration:local": "docker-compose up -d --wait && npm run test:integration ; docker-compose down", + "lint": "eslint . --fix", + "lint:ci": "eslint .", + "docs": "node scripts/build-docs.js" + }, + "pre-commit": [ + "lint:ci", + "test" + ] +} diff --git a/node_modules/ldapjs/scripts/build-docs.js b/node_modules/ldapjs/scripts/build-docs.js new file mode 100644 index 0000000..fb43400 --- /dev/null +++ b/node_modules/ldapjs/scripts/build-docs.js @@ -0,0 +1,131 @@ +const fs = require('fs/promises') +const path = require('path') +const { marked } = require('marked') +const fm = require('front-matter') +const { highlight } = require('highlight.js') + +marked.use({ + highlight: (code, lang) => { + if (lang) { + return highlight(code, { language: lang }).value + } + + return code + } +}) + +function tocHTML (toc) { + let html = '
    \n' + for (const li of toc) { + html += '
  • \n' + html += `\n` + if (li.children && li.children.length > 0) { + html += tocHTML(li.children) + } + html += '
  • \n' + } + html += '
\n' + + return html +} + +function markdownTOC (markdown) { + const tokens = marked.lexer(markdown) + const slugger = new marked.Slugger() + const toc = [] + let currentHeading + let ignoreFirst = true + for (const token of tokens) { + if (token.type === 'heading') { + if (token.depth === 1) { + if (ignoreFirst) { + ignoreFirst = false + continue + } + currentHeading = { + text: token.text, + slug: slugger.slug(token.text), + children: [] + } + toc.push(currentHeading) + } else if (token.depth === 2) { + if (!currentHeading) { + continue + } + currentHeading.children.push({ + text: token.text, + slug: slugger.slug(token.text) + }) + } + } + } + + return { + toc: tocHTML(toc), + html: marked.parser(tokens) + } +} + +function createHTML (template, text) { + const { attributes, body } = fm(text) + + const { toc, html } = markdownTOC(body) + attributes.toc_html = toc + attributes.content = html + + for (const prop in attributes) { + template = template.replace(new RegExp(`%\\(${prop}\\)s`, 'ig'), attributes[prop]) + } + + return template +} + +async function copyRecursive (src, dest) { + const stats = await fs.stat(src) + const isDirectory = stats.isDirectory() + if (isDirectory) { + await fs.mkdir(dest) + const files = await fs.readdir(src) + for (const file of files) { + await copyRecursive(path.join(src, file), path.join(dest, file)) + } + } else { + await fs.copyFile(src, dest) + } +} + +async function createDocs () { + const docs = path.resolve(__dirname, '..', 'docs') + const dist = path.resolve(__dirname, '..', 'public') + const branding = path.join(docs, 'branding') + const src = path.join(branding, 'public') + + try { + await fs.rm(dist, { recursive: true }) + } catch (ex) { + if (ex.code !== 'ENOENT') { + throw ex + } + } + await copyRecursive(src, dist) + + const highlightjsStyles = path.resolve(__dirname, '..', 'node_modules', 'highlight.js', 'styles') + await fs.copyFile(path.join(highlightjsStyles, 'default.css'), path.join(dist, 'media', 'css', 'highlight.css')) + + const template = await fs.readFile(path.join(branding, 'template.html'), { encoding: 'utf8' }) + const files = await fs.readdir(docs) + for (const file of files) { + if (!file.endsWith('.md')) { + continue + } + const text = await fs.readFile(path.join(docs, file), { encoding: 'utf8' }) + const html = createHTML(template, text) + + await fs.writeFile(path.join(dist, file.replace(/md$/, 'html')), html) + } +} + +createDocs().catch(ex => { + console.error(ex) + process.exitCode = 1 +}) diff --git a/node_modules/ldapjs/test-integration/.eslintrc.js b/node_modules/ldapjs/test-integration/.eslintrc.js new file mode 100644 index 0000000..6d4700e --- /dev/null +++ b/node_modules/ldapjs/test-integration/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + rules: { + 'no-shadow': 'off' + } +} diff --git a/node_modules/ldapjs/test-integration/client/connect.test.js b/node_modules/ldapjs/test-integration/client/connect.test.js new file mode 100644 index 0000000..1a82339 --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/connect.test.js @@ -0,0 +1,21 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 + +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +tap.test('connects to a server', t => { + t.plan(2) + + const client = ldapjs.createClient({ url: baseURL }) + client.bind('cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com', 'fry', (err) => { + t.error(err) + t.pass() + client.unbind() + }) +}) diff --git a/node_modules/ldapjs/test-integration/client/issue-860.test.js b/node_modules/ldapjs/test-integration/client/issue-860.test.js new file mode 100644 index 0000000..e7e6e05 --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issue-860.test.js @@ -0,0 +1,95 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') +const parseDN = ldapjs.parseDN + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +const client = ldapjs.createClient({ url: baseURL }) + +tap.before(() => { + return new Promise((resolve, reject) => { + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + if (err) { + return reject(err) + } + resolve() + }) + }) +}) + +tap.teardown(() => { + client.unbind() +}) + +tap.test('can search OUs with Japanese characters', t => { + t.plan(2) + + const opts = { + filter: '(&(objectClass=person))', + scope: 'sub', + paged: true, + sizeLimit: 100, + attributes: ['cn', 'employeeID'] + } + + const baseDN = parseDN('ou=テスト,dc=planetexpress,dc=com') + + client.search(baseDN.toString(), opts, (err, res) => { + t.error(err, 'search error') + res.on('searchEntry', (entry) => { + t.match(entry.pojo, { + type: 'SearchResultEntry', + objectName: 'cn=jdoe,ou=\\e3\\83\\86\\e3\\82\\b9\\e3\\83\\88,dc=planetexpress,dc=com', + attributes: [{ + type: 'cn', + values: ['John', 'jdoe'] + }] + }) + }) + res.on('error', (err) => { + t.error(err, 'search entry error') + }) + res.on('end', () => { + t.end() + }) + }) +}) + +tap.test('can search with non-ascii chars in filter', t => { + t.plan(3) + + const opts = { + filter: '(&(sn=Rodríguez))', + scope: 'sub', + attributes: ['dn', 'sn', 'cn'], + type: 'user' + } + + let searchEntryCount = 0 + client.search('dc=planetexpress,dc=com', opts, (err, res) => { + t.error(err, 'search error') + res.on('searchEntry', (entry) => { + searchEntryCount += 1 + t.match(entry.pojo, { + type: 'SearchResultEntry', + objectName: 'cn=Bender Bending Rodr\\c3\\adguez,ou=people,dc=planetexpress,dc=com', + attributes: [{ + type: 'cn', + values: ['Bender Bending Rodríguez'] + }] + }) + }) + res.on('error', (err) => { + t.error(err, 'search entry error') + }) + res.on('end', () => { + t.equal(searchEntryCount, 1, 'should have found 1 entry') + t.end() + }) + }) +}) diff --git a/node_modules/ldapjs/test-integration/client/issue-883.test.js b/node_modules/ldapjs/test-integration/client/issue-883.test.js new file mode 100644 index 0000000..c633c01 --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issue-883.test.js @@ -0,0 +1,56 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +const client = ldapjs.createClient({ url: baseURL }) + +tap.test('adds entries with Korean characters', t => { + t.plan(4) + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + t.error(err, 'bind error') + }) + + const nm = '홍길동' + const dn = `cn=${nm},ou=people,dc=planetexpress,dc=com` + const entry = { + objectclass: 'person', + sn: 'korean test' + } + + client.add(dn, entry, err => { + t.error(err, 'add entry error') + + const searchOpts = { + filter: '(sn=korean test)', + scope: 'subtree', + attributes: ['cn', 'sn'], + sizeLimit: 10, + timeLimit: 0 + } + client.search('ou=people,dc=planetexpress,dc=com', searchOpts, (err, res) => { + t.error(err, 'search error') + + res.on('searchEntry', (entry) => { + t.equal( + entry.attributes.filter(a => a.type === 'cn').pop().values.pop(), + nm + ) + }) + + res.on('error', (err) => { + t.error(err, 'search entry error') + }) + + res.on('end', () => { + client.unbind(t.end) + }) + }) + }) +}) diff --git a/node_modules/ldapjs/test-integration/client/issue-885.test.js b/node_modules/ldapjs/test-integration/client/issue-885.test.js new file mode 100644 index 0000000..56b77cc --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issue-885.test.js @@ -0,0 +1,55 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') +const parseDN = ldapjs.parseDN + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +const client = ldapjs.createClient({ url: baseURL }) + +const searchOpts = { + filter: '(&(objectClass=person))', + scope: 'sub', + paged: true, + sizeLimit: 0, + attributes: ['cn', 'employeeID'] +} + +const baseDN = parseDN('ou=large_ou,dc=planetexpress,dc=com') + +tap.test('paged search option returns pages', t => { + t.plan(4) + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + t.error(err, 'bind error') + }) + + client.search(baseDN.toString(), searchOpts, (err, res) => { + t.error(err, 'search error') + + let pages = 0 + const results = [] + res.on('searchEntry', (entry) => { + results.push(entry) + }) + + res.on('page', () => { + pages += 1 + }) + + res.on('error', (err) => { + t.error(err, 'search entry error') + }) + + res.on('end', () => { + t.equal(results.length, 2000) + t.equal(pages, 20) + + client.unbind(t.end) + }) + }) +}) diff --git a/node_modules/ldapjs/test-integration/client/issue-923.test.js b/node_modules/ldapjs/test-integration/client/issue-923.test.js new file mode 100644 index 0000000..7dde9ec --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issue-923.test.js @@ -0,0 +1,91 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') +const { DN } = require('@ldapjs/dn') +const Change = require('@ldapjs/change') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +const client = ldapjs.createClient({ url: baseURL }) + +tap.teardown(() => { + client.unbind() +}) + +tap.test('modifies entry specified by dn string', t => { + t.plan(4) + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + t.error(err, 'bind error') + }) + + const dn = 'cn=large10,ou=large_ou,dc=planetexpress,dc=com' + const change = new Change({ + operation: 'replace', + modification: { + type: 'givenName', + values: ['test'] + } + }) + + client.modify(dn, change, (err) => { + t.error(err, 'modify error') + validateChange({ t, expected: 'test', client }) + }) +}) + +tap.test('modifies entry specified by dn object', t => { + t.plan(4) + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + t.error(err, 'bind error') + }) + + const dn = DN.fromString('cn=large10,ou=large_ou,dc=planetexpress,dc=com') + const change = new Change({ + operation: 'replace', + modification: { + type: 'givenName', + values: ['test2'] + } + }) + + client.modify(dn, change, (err) => { + t.error(err, 'modify error') + validateChange({ t, expected: 'test2', client }) + }) +}) + +function validateChange ({ t, expected, client }) { + const searchBase = 'ou=large_ou,dc=planetexpress,dc=com' + const searchOpts = { + filter: '(cn=large10)', + scope: 'subtree', + attributes: ['givenName'], + sizeLimit: 10, + timeLimit: 0 + } + + client.search(searchBase, searchOpts, (err, res) => { + t.error(err, 'search error') + + res.on('searchEntry', entry => { + t.equal( + entry.attributes.filter(a => a.type === 'givenName').pop().values.pop(), + expected + ) + }) + + res.on('error', err => { + t.error(err, 'search entry error') + }) + + res.on('end', () => { + t.end() + }) + }) +} diff --git a/node_modules/ldapjs/test-integration/client/issue-940.test.js b/node_modules/ldapjs/test-integration/client/issue-940.test.js new file mode 100644 index 0000000..9c96f40 --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issue-940.test.js @@ -0,0 +1,81 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') +const Change = require('@ldapjs/change') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +const client = ldapjs.createClient({ url: baseURL }) + +tap.before(() => { + return new Promise((resolve, reject) => { + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err) => { + if (err) { + return reject(err) + } + resolve() + }) + }) +}) + +tap.teardown(() => { + client.unbind() +}) + +tap.test('can modify entries with non-ascii chars in RDN', t => { + t.plan(6) + + const dn = 'cn=Mendonça,ou=people,dc=planetexpress,dc=com' + const entry = { + objectclass: 'person', + sn: 'change me' + } + + client.add(dn, entry, error => { + t.error(error, 'add should not error') + doSearch('change me', doModify) + }) + + function doModify () { + const change = new Change({ + operation: 'replace', + modification: { + type: 'sn', + values: ['changed'] + } + }) + + client.modify(dn, change, (error) => { + t.error(error, 'modify should not error') + doSearch('changed', t.end.bind(t)) + }) + } + + function doSearch (expected, callback) { + const searchOpts = { + filter: '(&(objectclass=person)(cn=Mendonça))', + scope: 'subtree', + attributes: ['sn'] + } + client.search('ou=people,dc=planetexpress,dc=com', searchOpts, (error, res) => { + t.error(error, 'search should not error') + + res.on('searchEntry', entry => { + const found = entry.attributes.filter(a => a.type === 'sn').pop().values.pop() + t.equal(found, expected, `expected '${expected}' and got '${found}'`) + }) + + res.on('error', error => { + t.error(error, 'search result processing should not error') + }) + + res.on('end', () => { + callback() + }) + }) + } +}) diff --git a/node_modules/ldapjs/test-integration/client/issue-946.test.js b/node_modules/ldapjs/test-integration/client/issue-946.test.js new file mode 100644 index 0000000..230c0d6 --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issue-946.test.js @@ -0,0 +1,87 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +tap.test('can use password policy response', t => { + const client = ldapjs.createClient({ url: baseURL }) + const targetDN = 'cn=Bender Bending Rodríguez,ou=people,dc=planetexpress,dc=com' + + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', (err, res) => { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + + const newPassword = 'bender2' + changePassword(client, newPassword, () => { + client.unbind() + bindNewClient(newPassword, { error: 2 }, (client) => { + const newPassword = 'bender' + changePassword(client, newPassword, () => { + client.unbind() + bindNewClient(newPassword, { timeBeforeExpiration: 1000 }, (client) => { + client.unbind(t.end) + }) + }) + }) + }) + }) + + function bindNewClient (pwd, expected, callback) { + const client = ldapjs.createClient({ url: baseURL }) + const control = new ldapjs.PasswordPolicyControl() + + client.bind(targetDN, pwd, control, (err, res) => { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + + let error = null + let timeBeforeExpiration = null + let graceAuthNsRemaining = null + + res.controls.forEach(control => { + if (control.type === ldapjs.PasswordPolicyControl.OID) { + error = control.value.error ?? error + timeBeforeExpiration = control.value.timeBeforeExpiration ?? timeBeforeExpiration + graceAuthNsRemaining = control.value.graceAuthNsRemaining ?? graceAuthNsRemaining + } + }) + + if (expected.error !== undefined) { + t.equal(error, expected.error) + } + if (expected.timeBeforeExpiration !== undefined) { + t.equal(timeBeforeExpiration, expected.timeBeforeExpiration) + } + if (expected.graceAuthNsRemaining !== undefined) { + t.equal(graceAuthNsRemaining, expected.graceAuthNsRemaining) + } + + callback(client) + }) + } + + function changePassword (client, newPwd, callback) { + const change = new ldapjs.Change({ + operation: 'replace', + modification: new ldapjs.Attribute({ + type: 'userPassword', + values: newPwd + }) + }) + + client.modify(targetDN, change, (err, res) => { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + + callback() + }) + } +}) diff --git a/node_modules/ldapjs/test-integration/client/issues.test.js b/node_modules/ldapjs/test-integration/client/issues.test.js new file mode 100644 index 0000000..ab10d11 --- /dev/null +++ b/node_modules/ldapjs/test-integration/client/issues.test.js @@ -0,0 +1,98 @@ +'use strict' + +const tap = require('tap') +const ldapjs = require('../../lib') + +const SCHEME = process.env.SCHEME || 'ldap' +const HOST = process.env.HOST || '127.0.0.1' +const PORT = process.env.PORT || 389 + +const baseURL = `${SCHEME}://${HOST}:${PORT}` + +tap.test('modifyDN with long name (issue #480)', t => { + // 2023-08-15: disabling this 265 character string until a bug can be + // fixed in OpenLDAP. See https://github.com/ldapjs/docker-test-openldap/blob/d48bc2fb001b4ed9a152715ced4a2cb120439ec4/bootstrap/slapd-init.sh#L19-L31. + // const longStr = 'a292979f2c86d513d48bbb9786b564b3c5228146e5ba46f404724e322544a7304a2b1049168803a5485e2d57a544c6a0d860af91330acb77e5907a9e601ad1227e80e0dc50abe963b47a004f2c90f570450d0e920d15436fdc771e3bdac0487a9735473ed3a79361d1778d7e53a7fb0e5f01f97a75ef05837d1d5496fc86968ff47fcb64' + + // 2023-08-15: this 140 character string satisfies the original issue + // (https://github.com/ldapjs/node-ldapjs/issues/480) and avoids a bug + // in OpenLDAP 2.5. + const longStr = '292979f2c86d513d48bbb9786b564b3c5228146e5ba46f404724e322544a7304a2b1049168803a5485e2d57a544c6a0d860af91330acb77e5907a9e601ad1227e80e0dc50ab' + const targetDN = 'cn=Turanga Leela,ou=people,dc=planetexpress,dc=com' + const client = ldapjs.createClient({ url: baseURL }) + client.bind('cn=admin,dc=planetexpress,dc=com', 'GoodNewsEveryone', bindHandler) + + function bindHandler (err) { + t.error(err) + client.modifyDN( + targetDN, + `cn=${longStr},ou=people,dc=planetexpress,dc=com`, + modifyHandler + ) + } + + function modifyHandler (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + + client.modifyDN( + `cn=${longStr},ou=people,dc=planetexpress,dc=com`, + targetDN, + (err) => { + t.error(err) + client.unbind(t.end) + } + ) + } +}) + +tap.test('whois works correctly (issue #370)', t => { + const client = ldapjs.createClient({ url: baseURL }) + client.bind('cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com', 'fry', (err) => { + t.error(err) + + client.exop('1.3.6.1.4.1.4203.1.11.3', (err, value, res) => { + t.error(err) + t.ok(value) + t.equal(value, 'dn:cn=Philip J. Fry,ou=people,dc=planetexpress,dc=com') + t.ok(res) + t.equal(res.status, 0) + + client.unbind(t.end) + }) + }) +}) + +tap.test('can access large groups (issue #582)', t => { + const client = ldapjs.createClient({ url: baseURL }) + client.bind('cn=admin,dc=planetexpress,dc=com ', 'GoodNewsEveryone', (err) => { + t.error(err) + const searchOpts = { + scope: 'sub', + filter: '(&(objectClass=group)(cn=large_group))' + } + client.search('ou=large_ou,dc=planetexpress,dc=com', searchOpts, (err, response) => { + t.error(err) + + const results = [] + response.on('searchEntry', (entry) => { + results.push(entry) + }) + response.on('error', t.error) + response.on('end', (result) => { + t.equal(result.status, 0) + t.equal(results.length === 1, true) + t.ok(results[0].attributes) + + const memberAttr = results[0].attributes.find(a => a.type === 'member') + t.ok(memberAttr) + t.ok(memberAttr.values) + t.type(memberAttr.values, Array) + t.equal(memberAttr.values.length, 2000) + + client.unbind(t.end) + }) + }) + }) +}) diff --git a/node_modules/ldapjs/test/.eslintrc.js b/node_modules/ldapjs/test/.eslintrc.js new file mode 100644 index 0000000..2fb41ee --- /dev/null +++ b/node_modules/ldapjs/test/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + parserOptions: { + ecmaVersion: 'latest' + }, + + rules: { + 'no-shadow': 'off' + } +} diff --git a/node_modules/ldapjs/test/client.test.js b/node_modules/ldapjs/test/client.test.js new file mode 100644 index 0000000..7066398 --- /dev/null +++ b/node_modules/ldapjs/test/client.test.js @@ -0,0 +1,1789 @@ +'use strict' + +const util = require('util') +const assert = require('assert') +const tap = require('tap') +const vasync = require('vasync') +const getPort = require('get-port') +const { getSock, uuid } = require('./utils') +const Attribute = require('@ldapjs/attribute') +const Change = require('@ldapjs/change') +const messages = require('@ldapjs/messages') +const controls = require('@ldapjs/controls') +const dn = require('@ldapjs/dn') +const ldap = require('../lib') + +const { + SearchRequest, + SearchResultEntry, + SearchResultReference, + SearchResultDone +} = messages + +const SUFFIX = 'dc=test' +const LDAP_CONNECT_TIMEOUT = process.env.LDAP_CONNECT_TIMEOUT || 0 +const BIND_DN = 'cn=root' +const BIND_PW = 'secret' + +tap.beforeEach((t) => { + return new Promise(resolve => { + t.context.socketPath = getSock() + t.context.server = ldap.createServer() + + const server = t.context.server + server.bind(BIND_DN, function (req, res, next) { + if (req.credentials !== BIND_PW) { return next(new ldap.InvalidCredentialsError('Invalid password')) } + + res.end() + return next() + }) + + server.add(SUFFIX, function (req, res, next) { + res.end() + return next() + }) + + server.compare(SUFFIX, function (req, res, next) { + res.end(req.value === 'test') + return next() + }) + + server.del(SUFFIX, function (req, res, next) { + res.end() + return next() + }) + + // LDAP whoami + server.exop('1.3.6.1.4.1.4203.1.11.3', function (req, res, next) { + res.responseValue = 'u:xxyyz@EXAMPLE.NET' + res.end() + return next() + }) + + server.modify(SUFFIX, function (req, res, next) { + res.end() + return next() + }) + + server.modifyDN(SUFFIX, function (req, res, next) { + res.end() + return next() + }) + + server.modifyDN('cn=issue-480', function (req, res, next) { + assert(req.newRdn.toString().length > 132) + res.end() + return next() + }) + + server.search('dc=slow', function (req, res, next) { + res.send({ + dn: 'dc=slow', + attributes: { + you: 'wish', + this: 'was', + faster: '.' + } + }) + setTimeout(function () { + res.end() + next() + }, 250) + }) + + server.search('dc=timeout', function () { + // Cause the client to timeout by not sending a response. + }) + + server.search(SUFFIX, function (req, res, next) { + if (req.dn.equals('cn=ref,' + SUFFIX)) { + res.send(res.createSearchReference('ldap://localhost')) + } else if (req.dn.equals('cn=bin,' + SUFFIX)) { + const attributes = [] + attributes.push(new Attribute({ type: 'foo;binary', values: ['wr0gKyDCvCA9IMK+'] })) + attributes.push(new Attribute({ type: 'gb18030', values: [Buffer.from([0xB5, 0xE7, 0xCA, 0xD3, 0xBB, 0xFA])] })) + attributes.push(new Attribute({ type: 'objectclass', values: ['binary'] })) + res.send(res.createSearchEntry({ + objectName: req.dn, + attributes + })) + } else { + const attributes = [] + attributes.push(new Attribute({ type: 'cn', values: ['unit', 'test'] })) + attributes.push(new Attribute({ type: 'SN', values: ['testy'] })) + const e = res.createSearchEntry({ + objectName: req.dn, + attributes + }) + res.send(e) + res.send(e) + } + + res.end() + return next() + }) + + server.search('cn=sizelimit', function (req, res, next) { + const sizeLimit = 200 + for (let i = 0; i < 1000; i++) { + if (req.sizeLimit > 0 && i >= req.sizeLimit) { + break + } else if (i > sizeLimit) { + res.end(ldap.LDAP_SIZE_LIMIT_EXCEEDED) + return next() + } + res.send({ + dn: util.format('o=%d, cn=sizelimit', i), + attributes: { + o: [i], + objectclass: ['pagedResult'] + } + }) + } + res.end() + return next() + }) + + server.search('cn=paged', function (req, res, next) { + const min = 0 + const max = 1000 + + function sendResults (start, end) { + start = (start < min) ? min : start + end = (end > max || end < min) ? max : end + let i + for (i = start; i < end; i++) { + res.send(new SearchResultEntry({ + messageId: res.id, + entry: `o=${i},cn=paged`, + attributes: Attribute.fromObject({ + o: [i], + objectclass: ['pagedResult'] + }) + })) + } + return i + } + + let cookie = null + let pageSize = 0 + req.controls.forEach(function (control) { + if (control.type === controls.PagedResultsControl.OID) { + pageSize = control.value.size + cookie = control.value.cookie + } + }) + + if (!cookie || Buffer.isBuffer(cookie) === false) { + // don't allow non-paged searches for this test endpoint + next(Error('unwilling to perform')) + } + + // Do simple paging + let first = min + if (cookie.length !== 0) { + first = parseInt(cookie.toString(), 10) + } + const last = sendResults(first, first + pageSize) + + let resultCookie + if (last < max) { + resultCookie = Buffer.from(last.toString()) + } else { + resultCookie = Buffer.from('') + } + res.addControl(new controls.PagedResultsControl({ + value: { + size: pageSize, // correctness not required here + cookie: resultCookie + } + })) + res.end() + next() + }) + + server.search('cn=sssvlv', function (req, res, next) { + const min = 0 + const max = 100 + const results = [] + let o = 'aa' + for (let i = min; i < max; i++) { + results.push({ + dn: util.format('o=%s, cn=sssvlv', o), + attributes: { + o: [o], + objectclass: ['sssvlvResult'] + } + }) + o = ((parseInt(o, 36) + 1).toString(36)).replace(/0/g, 'a') + } + function sendResults (start, end, sortBy, sortDesc) { + start = (start < min) ? min : start + end = (end > max || end < min) ? max : end + const sorted = results.sort((a, b) => { + if (a.attributes[sortBy][0] < b.attributes[sortBy][0]) { + return sortDesc ? 1 : -1 + } else if (a.attributes[sortBy][0] > b.attributes[sortBy][0]) { + return sortDesc ? -1 : 1 + } + return 0 + }) + for (let i = start; i < end; i++) { + res.send(sorted[i]) + } + } + let sortBy = null + let sortDesc = null + let afterCount = null + let targetOffset = null + req.controls.forEach(function (control) { + if (control.type === ldap.ServerSideSortingRequestControl.OID) { + sortBy = control.value[0].attributeType + sortDesc = control.value[0].reverseOrder + } + if (control.type === ldap.VirtualListViewRequestControl.OID) { + afterCount = control.value.afterCount + targetOffset = control.value.targetOffset + } + }) + if (sortBy) { + if (afterCount && targetOffset) { + sendResults(targetOffset - 1, (targetOffset + afterCount), sortBy, sortDesc) + } else { + sendResults(min, max, sortBy, sortDesc) + } + res.end() + next() + } else { + next(new ldap.UnwillingToPerformError()) + } + }) + + server.search('cn=pagederr', function (req, res, next) { + let cookie = null + req.controls.forEach(function (control) { + if (control.type === ldap.PagedResultsControl.OID) { + cookie = control.value.cookie + } + }) + if (cookie && Buffer.isBuffer(cookie) && cookie.length === 0) { + // send first "page" + res.send({ + dn: util.format('o=result, cn=pagederr'), + attributes: { + o: 'result', + objectclass: ['pagedResult'] + } + }) + res.controls.push(new ldap.PagedResultsControl({ + value: { + size: 2, + cookie: Buffer.from('a') + } + })) + res.end() + return next() + } else { + // send error instead of second page + res.end(ldap.LDAP_SIZE_LIMIT_EXCEEDED) + return next() + } + }) + + server.search('dc=empty', function (req, res, next) { + res.send({ + dn: 'dc=empty', + attributes: { + member: [], + 'member;range=0-1': ['cn=user1, dc=empty', 'cn=user2, dc=empty'] + } + }) + res.end() + return next() + }) + + server.search('cn=busy', function (req, res, next) { + next(new ldap.BusyError('too much to do')) + }) + + server.search('', function (req, res, next) { + if (req.dn.toString() === '') { + res.send({ + dn: '', + attributes: { + objectclass: ['RootDSE', 'top'] + } + }) + res.end() + } else { + // Turn away any other requests (since '' is the fallthrough route) + res.errorMessage = 'No tree found for: ' + req.dn.toString() + res.end(ldap.LDAP_NO_SUCH_OBJECT) + } + return next() + }) + + server.unbind(function (req, res, next) { + res.end() + return next() + }) + + server.listen(t.context.socketPath, function () { + const client = ldap.createClient({ + connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10), + socketPath: t.context.socketPath + }) + t.context.client = client + client.on('connect', () => resolve()) + }) + }) +}) + +tap.afterEach((t) => { + return new Promise(resolve => { + t.context.client.unbind((err) => { + t.error(err) + t.context.server.close(() => resolve()) + }) + }) +}) + +tap.test('createClient', t => { + t.test('requires an options object', async t => { + const match = /options.+required/ + t.throws(() => ldap.createClient(), match) + t.throws(() => ldap.createClient([]), match) + t.throws(() => ldap.createClient(''), match) + t.throws(() => ldap.createClient(42), match) + }) + + t.test('url must be a string or array', async t => { + const match = /options\.url \(string\|array\) required/ + t.throws(() => ldap.createClient({ url: {} }), match) + t.throws(() => ldap.createClient({ url: 42 }), match) + }) + + t.test('socketPath must be a string', async t => { + const match = /options\.socketPath must be a string/ + t.throws(() => ldap.createClient({ socketPath: {} }), match) + t.throws(() => ldap.createClient({ socketPath: [] }), match) + t.throws(() => ldap.createClient({ socketPath: 42 }), match) + }) + + t.test('cannot supply both url and socketPath', async t => { + t.throws( + () => ldap.createClient({ url: 'foo', socketPath: 'bar' }), + /options\.url \^ options\.socketPath \(String\) required/ + ) + }) + + t.test('must supply at least url or socketPath', async t => { + t.throws( + () => ldap.createClient({}), + /options\.url \^ options\.socketPath \(String\) required/ + ) + }) + + t.test('exception from bad createClient parameter (issue #418)', t => { + try { + // This port number is totally invalid. It will cause the URL parser + // to throw an exception that should be caught. + ldap.createClient({ url: 'ldap://127.0.0.1:13891389' }) + } catch (error) { + t.ok(error) + t.end() + } + }) + + t.test('url array is correctly assigned', async t => { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: [ + `ldap://127.0.0.1:${unusedPortNumber}`, + `ldap://127.0.0.2:${unusedPortNumber}` + ], + connectTimeout: 1 + }) + client.on('connectTimeout', () => {}) + client.on('connectError', () => {}) + client.on('connectRefused', () => {}) + + t.equal(client.urls.length, 2) + }) + }) + + // TODO: this test is really flaky. It would be better if we could validate + // the options _withouth_ having to connect to a server. + // t.test('attaches a child function to logger', async t => { + // /* eslint-disable-next-line */ + // let client + // const logger = Object.create(require('abstract-logging')) + // const socketPath = getSock() + // const server = ldap.createServer() + // server.listen(socketPath, () => {}) + // t.teardown(() => { + // client.unbind(() => server.close()) + // }) + + // client = ldap.createClient({ socketPath, log: logger }) + // t.ok(logger.child) + // t.ok(typeof client.log.child === 'function') + // }) + + t.end() +}) + +tap.test('simple bind failure', function (t) { + t.context.client.bind(BIND_DN, uuid(), function (err, res) { + t.ok(err) + t.notOk(res) + + t.ok(err instanceof ldap.InvalidCredentialsError) + t.ok(err instanceof Error) + t.ok(err.dn) + t.ok(err.message) + t.ok(err.stack) + + t.end() + }) +}) + +tap.test('simple bind success', function (t) { + t.context.client.bind(BIND_DN, BIND_PW, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('simple anonymous bind (empty credentials)', function (t) { + t.context.client.bind('', '', function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('auto-bind bad credentials', function (t) { + const clt = ldap.createClient({ + socketPath: t.context.socketPath, + bindDN: BIND_DN, + bindCredentials: 'totallybogus' + }) + clt.once('error', function (err) { + t.equal(err.code, ldap.LDAP_INVALID_CREDENTIALS) + t.ok(clt._socket.destroyed, 'expect socket to be destroyed') + clt.destroy() + t.end() + }) +}) + +tap.test('auto-bind success', function (t) { + const clt = ldap.createClient({ + socketPath: t.context.socketPath, + bindDN: BIND_DN, + bindCredentials: BIND_PW + }) + clt.once('connect', function () { + t.ok(clt) + clt.destroy() + t.end() + }) +}) + +tap.test('add success', function (t) { + const attrs = [ + new Attribute({ + type: 'cn', + values: ['test'] + }) + ] + t.context.client.add('cn=add, ' + SUFFIX, attrs, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('add success with object', function (t) { + const entry = { + cn: ['unit', 'add'], + sn: 'test' + } + t.context.client.add('cn=add, ' + SUFFIX, entry, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('add buffer', function (t) { + const { BerReader } = require('@ldapjs/asn1') + const dn = `cn=add,${SUFFIX}` + const attribute = 'thumbnailPhoto' + const binary = 0xa5 + const entry = { + [attribute]: Buffer.from([binary]) + } + const write = t.context.client._socket.write + t.context.client._socket.write = (data, encoding, cb) => { + const reader = new BerReader(data) + t.equal(data.byteLength, 48) + t.ok(reader.readSequence()) + t.equal(reader.readInt(), 0x1) + t.equal(reader.readSequence(), 0x68) + t.equal(reader.readString(), dn) + t.ok(reader.readSequence()) + t.ok(reader.readSequence()) + t.equal(reader.readString(), attribute) + t.equal(reader.readSequence(), 0x31) + t.equal(reader.readByte(), 0x4) + t.equal(reader.readByte(), 1) + t.equal(reader.readByte(), binary) + t.context.client._socket.write = write + t.context.client._socket.write(data, encoding, cb) + } + t.context.client.add(dn, entry, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('compare success', function (t) { + t.context.client.compare('cn=compare, ' + SUFFIX, 'cn', 'test', function (err, matched, res) { + t.error(err) + t.ok(matched) + t.ok(res) + t.end() + }) +}) + +tap.test('compare false', function (t) { + t.context.client.compare('cn=compare, ' + SUFFIX, 'cn', 'foo', function (err, matched, res) { + t.error(err) + t.notOk(matched) + t.ok(res) + t.end() + }) +}) + +tap.test('compare bad suffix', function (t) { + t.context.client.compare('cn=' + uuid(), 'cn', 'foo', function (err, matched, res) { + t.ok(err) + t.ok(err instanceof ldap.NoSuchObjectError) + t.notOk(matched) + t.notOk(res) + t.end() + }) +}) + +tap.test('delete success', function (t) { + t.context.client.del('cn=delete, ' + SUFFIX, function (err, res) { + t.error(err) + t.ok(res) + t.end() + }) +}) + +tap.test('delete with control (GH-212)', function (t) { + const control = new ldap.Control({ + type: '1.2.3.4', + criticality: false + }) + t.context.client.del('cn=delete, ' + SUFFIX, control, function (err, res) { + t.error(err) + t.ok(res) + t.end() + }) +}) + +tap.test('exop success', function (t) { + t.context.client.exop('1.3.6.1.4.1.4203.1.11.3', function (err, value, res) { + t.error(err) + t.ok(value) + t.ok(res) + t.equal(value, 'u:xxyyz@EXAMPLE.NET') + t.end() + }) +}) + +tap.test('exop invalid', function (t) { + t.context.client.exop('1.2.3.4', function (err, res) { + t.ok(err) + t.ok(err instanceof ldap.ProtocolError) + t.notOk(res) + t.end() + }) +}) + +tap.test('bogus exop (GH-17)', function (t) { + t.context.client.exop('cn=root', function (err) { + t.ok(err) + t.end() + }) +}) + +tap.test('modify success', function (t) { + const change = new Change({ + type: 'Replace', + modification: new Attribute({ + type: 'cn', + values: ['test'] + }) + }) + t.context.client.modify('cn=modify, ' + SUFFIX, change, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +// https://github.com/ldapjs/node-ldapjs/pull/435 +tap.test('can delete attributes', function (t) { + const change = new Change({ + type: 'Delete', + modification: new Attribute({ type: 'cn', values: [null] }) + }) + t.context.client.modify('cn=modify,' + SUFFIX, change, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('modify array success', function (t) { + const changes = [ + new Change({ + operation: 'Replace', + modification: new Attribute({ + type: 'cn', + values: ['test'] + }) + }), + new Change({ + operation: 'Delete', + modification: new Attribute({ + type: 'sn' + }) + }) + ] + t.context.client.modify('cn=modify, ' + SUFFIX, changes, function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('modify DN new RDN only', function (t) { + t.context.client.modifyDN('cn=old, ' + SUFFIX, 'cn=new', function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('modify DN new superior', function (t) { + t.context.client.modifyDN('cn=old, ' + SUFFIX, 'cn=new, dc=foo', function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('modify DN excessive length (GH-480)', function (t) { + t.context.client.modifyDN('cn=issue-480', 'cn=a292979f2c86d513d48bbb9786b564b3c5228146e5ba46f404724e322544a7304a2b1049168803a5485e2d57a544c6a0d860af91330acb77e5907a9e601ad1227e80e0dc50abe963b47a004f2c90f570450d0e920d15436fdc771e3bdac0487a9735473ed3a79361d1778d7e53a7fb0e5f01f97a75ef05837d1d5496fc86968ff47fcb64', function (err, res) { + t.error(err) + t.ok(res) + t.equal(res.status, 0) + t.end() + }) +}) + +tap.test('modify DN excessive superior length', function (t) { + const { ModifyDnRequest } = messages + const entry = 'cn=Test User,ou=A Long OU ,ou=Another Long OU ,ou=Another Long OU ,dc=acompany,DC=io' + const newSuperior = 'ou=A New Long OU , ou=Another New Long OU , ou=An OU , dc=acompany, dc=io' + const newRdn = entry.replace(/(.*?),.*/, '$1') + const deleteOldRdn = true + + const req = new ModifyDnRequest({ + entry, + deleteOldRdn, + newRdn, + newSuperior + }) + + t.equal(req.entry.toString(), 'cn=Test User,ou=A Long OU,ou=Another Long OU,ou=Another Long OU,dc=acompany,DC=io') + t.equal(req.newRdn.toString(), 'cn=Test User') + t.equal(req.deleteOldRdn, true) + t.equal(req.newSuperior.toString(), 'ou=A New Long OU,ou=Another New Long OU,ou=An OU,dc=acompany,dc=io') + + t.end() +}) + +tap.test('search basic', function (t) { + const { SearchResultEntry, SearchResultDone } = messages + + t.context.client.search('cn=test, ' + SUFFIX, '(objectclass=*)', function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + res.on('searchEntry', function (entry) { + t.ok(entry) + t.ok(entry instanceof SearchResultEntry) + t.equal(entry.dn.toString(), 'cn=test,' + SUFFIX) + t.ok(entry.attributes) + t.ok(entry.attributes.length) + t.equal(entry.attributes[0].type, 'cn') + t.equal(entry.attributes[1].type, 'SN') + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 2) + t.end() + }) + }) +}) + +tap.test('search basic with DN', function (t) { + const { SearchResultEntry, SearchResultDone } = messages + + t.context.client.search(dn.DN.fromString('cn=test, ' + SUFFIX, '(objectclass=*)'), function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + res.on('searchEntry', function (entry) { + t.ok(entry) + t.ok(entry instanceof SearchResultEntry) + t.equal(entry.dn.toString(), 'cn=test,' + SUFFIX) + t.ok(entry.attributes) + t.ok(entry.attributes.length) + t.equal(entry.attributes[0].type, 'cn') + t.equal(entry.attributes[1].type, 'SN') + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 2) + t.end() + }) + }) +}) + +tap.test('GH-602 search basic with delayed event listener binding', function (t) { + t.context.client.search('cn=test, ' + SUFFIX, '(objectclass=*)', function (err, res) { + t.error(err) + setTimeout(() => { + let gotEntry = 0 + res.on('searchEntry', function () { + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function () { + t.equal(gotEntry, 2) + t.end() + }) + }, 100) + }) +}) + +tap.test('search sizeLimit', function (t) { + t.test('over limit', function (t2) { + t.context.client.search('cn=sizelimit', {}, function (err, res) { + t2.error(err) + res.on('error', function (error) { + t2.equal(error.name, 'SizeLimitExceededError') + t2.end() + }) + }) + }) + + t.test('under limit', function (t2) { + const limit = 100 + t.context.client.search('cn=sizelimit', { sizeLimit: limit }, function (err, res) { + t2.error(err) + let count = 0 + res.on('searchEntry', function () { + count++ + }) + res.on('end', function () { + t2.pass() + t2.equal(count, limit) + t2.end() + }) + res.on('error', t2.error.bind(t)) + }) + }) + + t.end() +}) + +tap.test('search paged', { timeout: 10000 }, function (t) { + t.test('paged - no pauses', function (t2) { + let countEntries = 0 + let countPages = 0 + let currentSearchRequest = null + t.context.client.search('cn=paged', { paged: { pageSize: 100 } }, function (err, res) { + t2.error(err) + res.on('searchEntry', entryListener) + res.on('searchRequest', (searchRequest) => { + t2.ok(searchRequest instanceof SearchRequest) + if (currentSearchRequest === null) { + t2.equal(countPages, 0) + } + currentSearchRequest = searchRequest + }) + res.on('page', pageListener) + res.on('error', (err) => t2.error(err)) + res.on('end', function (result) { + t2.equal(countEntries, 1000) + t2.equal(countPages, 10) + t2.equal(result.messageId, currentSearchRequest.messageId) + t2.end() + }) + + t2.teardown(() => { + res.removeListener('searchEntry', entryListener) + res.removeListener('page', pageListener) + }) + + function entryListener () { + countEntries += 1 + } + + function pageListener (result) { + countPages += 1 + if (countPages < 10) { + t2.equal(result.messageId, currentSearchRequest.messageId) + } + } + }) + }) + + t.test('paged - pauses', function (t2) { + let countPages = 0 + t.context.client.search('cn=paged', { + paged: { + pageSize: 100, + pagePause: true + } + }, function (err, res) { + t2.error(err) + res.on('page', pageListener) + res.on('error', (err) => t2.error(err)) + res.on('end', function () { + t2.equal(countPages, 9) + t2.end() + }) + + function pageListener (result, cb) { + countPages++ + // cancel after 9 to verify callback usage + if (countPages === 9) { + // another page should never be encountered + res.removeListener('page', pageListener) + .on('page', t2.fail.bind(null, 'unexpected page')) + return cb(new Error()) + } + return cb() + } + }) + }) + + t.test('paged - no support (err handled)', function (t2) { + t.context.client.search(SUFFIX, { + paged: { pageSize: 100 } + }, function (err, res) { + t2.error(err) + res.on('pageError', t2.ok.bind(t2)) + res.on('end', function () { + t2.pass() + t2.end() + }) + }) + }) + + t.test('paged - no support (err not handled)', function (t2) { + t.context.client.search(SUFFIX, { + paged: { pageSize: 100 } + }, function (err, res) { + t2.error(err) + res.on('end', t2.fail.bind(t2)) + res.on('error', function (error) { + t2.ok(error) + t2.end() + }) + }) + }) + + t.test('paged - redundant control', function (t2) { + try { + t.context.client.search(SUFFIX, { + paged: { pageSize: 100 } + }, new ldap.PagedResultsControl(), + function (err) { + t.error(err) + t2.fail() + }) + } catch (e) { + t2.ok(e) + t2.end() + } + }) + + t.test('paged - handle later error', function (t2) { + let countEntries = 0 + let countPages = 0 + t.context.client.search('cn=pagederr', { + paged: { pageSize: 1 } + }, function (err, res) { + t2.error(err) + res.on('searchEntry', function () { + t2.ok(++countEntries) + }) + res.on('page', function () { + t2.ok(++countPages) + }) + res.on('error', function (error) { + t2.ok(error) + t2.equal(countEntries, 1) + t2.equal(countPages, 1) + t2.end() + }) + res.on('end', function () { + t2.fail('should not be reached') + }) + }) + }) + + tap.test('paged - search with delayed event listener binding', function (t) { + t.context.client.search('cn=paged', { filter: '(objectclass=*)', paged: true }, function (err, res) { + t.error(err) + setTimeout(() => { + let gotEntry = 0 + res.on('searchEntry', function () { + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function () { + t.equal(gotEntry, 1000) + t.end() + }) + }, 100) + }) + }) + + t.end() +}) + +// We are skipping the ServerSideSorting test because we have skipped +// properly implementing the controls in order to get v3 shipped. These +// tests should be re-enabled once we have addressed this issue. +// ~ jsumners 2023-02-19 +// TODO: re-enable after adding back SSSR support +tap.test('search - sssvlv', { timeout: 10000, skip: true }, function (t) { + t.test('ssv - asc', function (t2) { + let preventry = null + const sssrcontrol = new ldap.ServerSideSortingRequestControl( + { + value: { + attributeType: 'o', + orderingRule: 'caseIgnoreOrderingMatch', + reverseOrder: false + } + } + ) + t.context.client.search('cn=sssvlv', {}, sssrcontrol, function (err, res) { + t2.error(err) + res.on('searchEntry', function (entry) { + t2.ok(entry) + t2.ok(entry instanceof ldap.SearchEntry) + t2.ok(entry.attributes) + t2.ok(entry.attributes.length) + if (preventry != null) { + t2.ok(entry.attributes[0]._vals[0] >= preventry.attributes[0]._vals[0]) + } + preventry = entry + }) + res.on('error', (err) => t2.error(err)) + res.on('end', function () { + t2.end() + }) + }) + }) + + t.test('ssv - desc', function (t2) { + let preventry = null + const sssrcontrol = new ldap.ServerSideSortingRequestControl( + { + value: { + attributeType: 'o', + orderingRule: 'caseIgnoreOrderingMatch', + reverseOrder: true + } + } + ) + t.context.client.search('cn=sssvlv', {}, sssrcontrol, function (err, res) { + t2.error(err) + res.on('searchEntry', function (entry) { + t2.ok(entry) + t2.ok(entry instanceof ldap.SearchEntry) + t2.ok(entry.attributes) + t2.ok(entry.attributes.length) + if (preventry != null) { + t2.ok(entry.attributes[0]._vals[0] <= preventry.attributes[0]._vals[0]) + } + preventry = entry + }) + res.on('error', (err) => t2.error(err)) + res.on('end', function () { + t2.end() + }) + }) + }) + + t.test('vlv - first page', { skip: true }, function (t2) { + // This test is disabled. + // See https://github.com/ldapjs/node-ldapjs/pull/797#issuecomment-1094132289 + const sssrcontrol = new ldap.ServerSideSortingRequestControl( + { + value: { + attributeType: 'o', + orderingRule: 'caseIgnoreOrderingMatch', + reverseOrder: false + } + } + ) + const vlvrcontrol = new ldap.VirtualListViewRequestControl( + { + value: { + beforeCount: 0, + afterCount: 9, + targetOffset: 1, + contentCount: 0 + } + } + ) + let count = 0 + let preventry = null + t.context.client.search('cn=sssvlv', {}, [sssrcontrol, vlvrcontrol], function (err, res) { + t2.error(err) + res.on('searchEntry', function (entry) { + t2.ok(entry) + t2.ok(entry instanceof ldap.SearchEntry) + t2.ok(entry.attributes) + t2.ok(entry.attributes.length) + if (preventry != null) { + t2.ok(entry.attributes[0]._vals[0] >= preventry.attributes[0]._vals[0]) + } + preventry = entry + count++ + }) + res.on('error', (err) => t2.error(err)) + res.on('end', function () { + t2.equal(count, 10) + t2.end() + }) + }) + }) + + t.test('vlv - last page', { skip: true }, function (t2) { + // This test is disabled. + // See https://github.com/ldapjs/node-ldapjs/pull/797#issuecomment-1094132289 + const sssrcontrol = new ldap.ServerSideSortingRequestControl( + { + value: { + attributeType: 'o', + orderingRule: 'caseIgnoreOrderingMatch', + reverseOrder: false + } + } + ) + const vlvrcontrol = new ldap.VirtualListViewRequestControl( + { + value: { + beforeCount: 0, + afterCount: 9, + targetOffset: 91, + contentCount: 0 + } + } + ) + let count = 0 + let preventry = null + t.context.client.search('cn=sssvlv', {}, [sssrcontrol, vlvrcontrol], function (err, res) { + t2.error(err) + res.on('searchEntry', function (entry) { + t2.ok(entry) + t2.ok(entry instanceof ldap.SearchEntry) + t2.ok(entry.attributes) + t2.ok(entry.attributes.length) + if (preventry != null) { + t2.ok(entry.attributes[0]._vals[0] >= preventry.attributes[0]._vals[0]) + } + preventry = entry + count++ + }) + res.on('error', (err) => t2.error(err)) + res.on('end', function () { + t2.equal(count, 10) + t2.end() + }) + }) + }) + + t.end() +}) + +tap.test('search referral', function (t) { + t.context.client.search('cn=ref, ' + SUFFIX, '(objectclass=*)', function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + let gotReferral = false + res.on('searchEntry', function () { + gotEntry++ + }) + res.on('searchReference', function (referral) { + gotReferral = true + t.ok(referral) + t.ok(referral instanceof SearchResultReference) + t.ok(referral.uris) + t.ok(referral.uris.length) + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 0) + t.ok(gotReferral) + t.end() + }) + }) +}) + +tap.test('search rootDSE', function (t) { + t.context.client.search('', '(objectclass=*)', function (err, res) { + t.error(err) + t.ok(res) + res.on('searchEntry', function (entry) { + t.ok(entry) + t.equal(entry.dn.toString(), '') + t.ok(entry.attributes) + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.end() + }) + }) +}) + +tap.test('search empty attribute', function (t) { + t.context.client.search('dc=empty', '(objectclass=*)', function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + res.on('searchEntry', function (entry) { + const obj = entry.pojo + t.equal('dc=empty', obj.objectName) + + const member = entry.attributes[0] + t.ok(member) + t.equal(member.values.length, 0) + + const rangedMember = entry.attributes[1] + t.equal(rangedMember.type, 'member;range=0-1') + t.equal(rangedMember.values.length, 2) + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 1) + t.end() + }) + }) +}) + +tap.test('GH-21 binary attributes', function (t) { + t.context.client.search('cn=bin, ' + SUFFIX, '(objectclass=*)', function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + const expect = Buffer.from('\u00bd + \u00bc = \u00be', 'utf8') + const expect2 = Buffer.from([0xB5, 0xE7, 0xCA, 0xD3, 0xBB, 0xFA]) + res.on('searchEntry', function (entry) { + t.ok(entry) + t.ok(entry instanceof SearchResultEntry) + t.equal(entry.dn.toString(), 'cn=bin,' + SUFFIX) + t.ok(entry.attributes) + t.ok(entry.attributes.length) + t.equal(entry.attributes[0].type, 'foo;binary') + t.equal(entry.attributes[0].values[0], expect.toString('base64')) + t.equal(entry.attributes[0].buffers[0].toString('base64'), + expect.toString('base64')) + + t.ok(entry.attributes[1].type, 'gb18030') + t.equal(entry.attributes[1].buffers.length, 1) + t.equal(expect2.length, entry.attributes[1].buffers[0].length) + for (let i = 0; i < expect2.length; i++) { t.equal(expect2[i], entry.attributes[1].buffers[0][i]) } + + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 1) + t.end() + }) + }) +}) + +tap.test('GH-23 case insensitive attribute filtering', function (t) { + const opts = { + filter: '(objectclass=*)', + attributes: ['Cn'] + } + t.context.client.search('cn=test, ' + SUFFIX, opts, function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + res.on('searchEntry', function (entry) { + t.ok(entry) + t.ok(entry instanceof SearchResultEntry) + t.equal(entry.dn.toString(), 'cn=test,' + SUFFIX) + t.ok(entry.attributes) + t.ok(entry.attributes.length) + t.equal(entry.attributes[0].type, 'cn') + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 2) + t.end() + }) + }) +}) + +tap.test('GH-24 attribute selection of *', function (t) { + const opts = { + filter: '(objectclass=*)', + attributes: ['*'] + } + t.context.client.search('cn=test, ' + SUFFIX, opts, function (err, res) { + t.error(err) + t.ok(res) + let gotEntry = 0 + res.on('searchEntry', function (entry) { + t.ok(entry) + t.ok(entry instanceof SearchResultEntry) + t.equal(entry.dn.toString(), 'cn=test,' + SUFFIX) + t.ok(entry.attributes) + t.ok(entry.attributes.length) + t.equal(entry.attributes[0].type, 'cn') + t.equal(entry.attributes[1].type, 'SN') + gotEntry++ + }) + res.on('error', function (err) { + t.fail(err) + }) + res.on('end', function (res) { + t.ok(res) + t.ok(res instanceof SearchResultDone) + t.equal(res.status, 0) + t.equal(gotEntry, 2) + t.end() + }) + }) +}) + +tap.test('idle timeout', function (t) { + t.context.client.idleTimeout = 250 + function premature () { + t.error(true) + } + t.context.client.on('idle', premature) + t.context.client.search('dc=slow', 'objectclass=*', function (err, res) { + t.error(err) + res.on('searchEntry', function (res) { + t.ok(res) + }) + res.on('error', function (err) { + t.error(err) + }) + res.on('end', function () { + const late = setTimeout(function () { + t.fail('too late') + }, 500) + // It's ok to go idle now + t.context.client.removeListener('idle', premature) + t.context.client.on('idle', function () { + clearTimeout(late) + t.context.client.removeAllListeners('idle') + t.context.client.idleTimeout = 0 + t.end() + }) + }) + }) +}) + +tap.test('setup action', function (t) { + const setupClient = ldap.createClient({ + connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10), + socketPath: t.context.socketPath + }) + setupClient.on('setup', function (clt, cb) { + clt.bind(BIND_DN, BIND_PW, function (err) { + t.error(err) + cb(err) + }) + }) + setupClient.search(SUFFIX, { scope: 'base' }, function (err, res) { + t.error(err) + t.ok(res) + res.on('end', function () { + setupClient.destroy() + t.end() + }) + }) +}) + +tap.test('setup reconnect', function (t) { + const rClient = ldap.createClient({ + connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10), + socketPath: t.context.socketPath, + reconnect: true + }) + rClient.on('setup', function (clt, cb) { + clt.bind(BIND_DN, BIND_PW, function (err) { + t.error(err) + cb(err) + }) + }) + + function doSearch (_, cb) { + rClient.search(SUFFIX, { scope: 'base' }, function (err, res) { + t.error(err) + res.on('end', function () { + cb() + }) + }) + } + + vasync.pipeline({ + funcs: [ + doSearch, + function cleanDisconnect (_, cb) { + t.ok(rClient.connected) + rClient.once('close', function (err) { + t.error(err) + t.equal(rClient.connected, false) + cb() + }) + rClient.unbind() + }, + doSearch, + function simulateError (_, cb) { + const msg = 'fake socket error' + rClient.once('error', function (err) { + t.equal(err.message, msg) + t.ok(err) + }) + rClient.once('close', function () { + // can't test had_err because the socket error is being faked + cb() + }) + rClient._socket.emit('error', new Error(msg)) + }, + doSearch + ] + }, function (err) { + t.error(err) + rClient.destroy() + t.end() + }) +}) + +tap.test('setup abort', function (t) { + const setupClient = ldap.createClient({ + connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10), + socketPath: t.context.socketPath, + reconnect: true + }) + const message = "It's a trap!" + setupClient.on('setup', function (clt, cb) { + // simulate failure + t.ok(clt) + cb(new Error(message)) + }) + setupClient.on('setupError', function (err) { + t.ok(true) + t.equal(err.message, message) + setupClient.destroy() + t.end() + }) +}) + +tap.test('abort reconnect', function (t) { + const abortClient = ldap.createClient({ + connectTimeout: parseInt(LDAP_CONNECT_TIMEOUT, 10), + socketPath: 'an invalid path', + reconnect: true + }) + let retryCount = 0 + abortClient.on('connectError', function () { + ++retryCount + }) + abortClient.once('connectError', function () { + t.ok(true) + abortClient.once('destroy', function () { + t.ok(retryCount < 3) + t.end() + }) + abortClient.destroy() + }) +}) + +tap.test('reconnect max retries', function (t) { + const RETRIES = 5 + const rClient = ldap.createClient({ + connectTimeout: 100, + socketPath: 'an invalid path', + reconnect: { + failAfter: RETRIES, + // Keep the test duration low + initialDelay: 10, + maxDelay: 100 + } + }) + let count = 0 + rClient.on('connectError', function () { + count++ + }) + rClient.on('error', function (err) { + t.ok(err) + t.equal(count, RETRIES) + rClient.destroy() + t.end() + }) +}) + +tap.test('reconnect on server close', function (t) { + const clt = ldap.createClient({ + socketPath: t.context.socketPath, + reconnect: true + }) + clt.on('setup', function (sclt, cb) { + sclt.bind(BIND_DN, BIND_PW, function (err) { + t.error(err) + cb(err) + }) + }) + clt.once('connect', function () { + t.ok(clt._socket) + clt.once('connect', function () { + t.ok(true, 'successful reconnect') + clt.destroy() + t.end() + }) + + // Simulate server-side close + clt._socket.destroy() + }) +}) + +tap.test('no auto-reconnect on unbind', function (t) { + const clt = ldap.createClient({ + socketPath: t.context.socketPath, + reconnect: true + }) + clt.on('setup', function (sclt, cb) { + sclt.bind(BIND_DN, BIND_PW, function (err) { + t.error(err) + cb(err) + }) + }) + clt.once('connect', function () { + clt.once('connect', function () { + t.error(new Error('client should not reconnect')) + }) + clt.once('close', function () { + t.ok(true, 'initial close') + setImmediate(function () { + t.ok(!clt.connected, 'should not be connected') + t.ok(!clt.connecting, 'should not be connecting') + clt.destroy() + t.end() + }) + }) + + clt.unbind() + }) +}) + +tap.test('abandon (GH-27)', function (t) { + // FIXME: test abandoning a real request + t.context.client.abandon(401876543, function (err) { + t.error(err) + t.end() + }) +}) + +tap.test('search timeout (GH-51)', function (t) { + t.context.client.timeout = 250 + t.context.client.search('dc=timeout', 'objectclass=*', function (err, res) { + t.error(err) + res.on('error', function () { + t.end() + }) + }) +}) + +tap.test('resultError handling', function (t) { + const client = t.context.client + vasync.pipeline({ funcs: [errSearch, cleanSearch] }, function (err) { + t.error(err) + client.removeListener('resultError', error1) + client.removeListener('resultError', error2) + t.end() + }) + + function errSearch (_, cb) { + client.once('resultError', error1) + client.search('cn=busy', {}, function (err, res) { + t.error(err) + res.once('error', function (error) { + t.equal(error.name, 'BusyError') + cb() + }) + }) + } + + function cleanSearch (_, cb) { + client.on('resultError', error2) + client.search(SUFFIX, {}, function (err, res) { + t.error(err) + res.once('end', function () { + t.pass() + cb() + }) + }) + } + + function error1 (error) { + t.equal(error.name, 'BusyError') + } + + function error2 () { + t.fail('should not get error') + } +}) + +tap.test('connection refused', function (t) { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: `ldap://0.0.0.0:${unusedPortNumber}` + }) + + client.on('connectRefused', () => {}) + + client.bind('cn=root', 'secret', function (err, res) { + t.ok(err) + t.type(err, Error) + t.equal(err.code, 'ECONNREFUSED') + t.notOk(res) + t.end() + }) + }) +}) + +tap.test('connection timeout', function (t) { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: `ldap://example.org:${unusedPortNumber}`, + connectTimeout: 1, + timeout: 1 + }) + + client.on('connectTimeout', () => {}) + + let done = false + + setTimeout(function () { + if (!done) { + throw new Error('LDAPJS waited for the server for too long') + } + }, 2000) + + client.bind('cn=root', 'secret', function (err, res) { + t.ok(err) + t.type(err, Error) + t.equal(err.message, 'connection timeout') + done = true + t.notOk(res) + t.end() + }) + }) +}) + +tap.test('emitError', function (t) { + t.test('connectTimeout', function (t) { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: `ldap://example.org:${unusedPortNumber}`, + connectTimeout: 1, + timeout: 1 + }) + + const timeout = setTimeout(function () { + throw new Error('LDAPJS waited for the server for too long') + }, 2000) + + client.on('error', (err) => { + t.fail(err) + }) + client.on('connectTimeout', (err) => { + t.ok(err) + t.type(err, Error) + t.equal(err.message, 'connection timeout') + clearTimeout(timeout) + t.end() + }) + + client.bind('cn=root', 'secret', () => {}) + }) + }) + + t.test('connectTimeout to error', function (t) { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: `ldap://example.org:${unusedPortNumber}`, + connectTimeout: 1, + timeout: 1 + }) + + const timeout = setTimeout(function () { + throw new Error('LDAPJS waited for the server for too long') + }, 2000) + + client.on('error', (err) => { + t.ok(err) + t.type(err, Error) + t.equal(err.message, 'connectTimeout: connection timeout') + clearTimeout(timeout) + t.end() + }) + + client.bind('cn=root', 'secret', () => {}) + }) + }) + + t.test('connectRefused', function (t) { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: `ldap://0.0.0.0:${unusedPortNumber}` + }) + + client.on('error', (err) => { + t.fail(err) + }) + client.on('connectRefused', (err) => { + t.ok(err) + t.type(err, Error) + t.equal(err.message, `connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`) + t.equal(err.code, 'ECONNREFUSED') + t.end() + }) + + client.bind('cn=root', 'secret', () => {}) + }) + }) + + t.test('connectRefused to error', function (t) { + getPort().then(function (unusedPortNumber) { + const client = ldap.createClient({ + url: `ldap://0.0.0.0:${unusedPortNumber}` + }) + + client.on('error', (err) => { + t.ok(err) + t.type(err, Error) + t.equal(err.message, `connectRefused: connect ECONNREFUSED 0.0.0.0:${unusedPortNumber}`) + t.equal(err.code, 'ECONNREFUSED') + t.end() + }) + + client.bind('cn=root', 'secret', () => {}) + }) + }) + + t.end() +}) + +tap.test('socket destroy', function (t) { + const clt = ldap.createClient({ + socketPath: t.context.socketPath, + bindDN: BIND_DN, + bindCredentials: BIND_PW + }) + + clt.once('connect', function () { + t.ok(clt) + clt._socket.once('close', function () { + t.ok(!clt.connected) + t.end() + }) + clt.destroy() + }) + + clt.once('destroy', function () { + t.ok(clt.destroyed) + }) +}) diff --git a/node_modules/ldapjs/test/controls/control.test.js b/node_modules/ldapjs/test/controls/control.test.js new file mode 100644 index 0000000..71f4112 --- /dev/null +++ b/node_modules/ldapjs/test/controls/control.test.js @@ -0,0 +1,53 @@ +'use strict' + +const { test } = require('tap') +const { BerReader, BerWriter } = require('@ldapjs/asn1') +const { Control, getControl } = require('../../lib') + +test('new no args', function (t) { + t.ok(new Control()) + t.end() +}) + +test('new with args', function (t) { + const c = new Control({ + type: '2.16.840.1.113730.3.4.2', + criticality: true + }) + t.ok(c) + t.equal(c.type, '2.16.840.1.113730.3.4.2') + t.ok(c.criticality) + t.end() +}) + +test('parse', function (t) { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('2.16.840.1.113730.3.4.2') + ber.writeBoolean(true) + ber.writeString('foo') + ber.endSequence() + + const c = getControl(new BerReader(ber.buffer)) + + t.ok(c) + t.equal(c.type, '2.16.840.1.113730.3.4.2') + t.ok(c.criticality) + t.equal(c.value.toString('utf8'), 'foo') + t.end() +}) + +test('parse no value', function (t) { + const ber = new BerWriter() + ber.startSequence() + ber.writeString('2.16.840.1.113730.3.4.2') + ber.endSequence() + + const c = getControl(new BerReader(ber.buffer)) + + t.ok(c) + t.equal(c.type, '2.16.840.1.113730.3.4.2') + t.equal(c.criticality, false) + t.notOk(c.value, null) + t.end() +}) diff --git a/node_modules/ldapjs/test/corked_emitter.test.js b/node_modules/ldapjs/test/corked_emitter.test.js new file mode 100644 index 0000000..5edecd0 --- /dev/null +++ b/node_modules/ldapjs/test/corked_emitter.test.js @@ -0,0 +1,104 @@ +'use strict' + +const { test } = require('tap') +const CorkedEmitter = require('../lib/corked_emitter') + +function gatherEventSequence (expectedNumber) { + const gatheredEvents = [] + let callback + const finished = new Promise(function (resolve) { + callback = function (...args) { + gatheredEvents.push(...args) + if (gatheredEvents.length >= expectedNumber) { + // Prevent result mutation after our promise is resolved: + resolve(gatheredEvents.slice()) + } + } + }) + return { + finished, + callback + } +} + +test('normal emit flow', function (t) { + const emitter = new CorkedEmitter() + const expectedSequence = [ + ['searchEntry', { data: 'a' }], + ['searchEntry', { data: 'b' }], + ['end'] + ] + const gatherer = gatherEventSequence(3) + emitter.on('searchEntry', function (...args) { + gatherer.callback(['searchEntry', ...args]) + }) + emitter.on('end', function (...args) { + gatherer.callback(['end', ...args]) + }) + emitter.emit('searchEntry', { data: 'a' }) + emitter.emit('searchEntry', { data: 'b' }) + emitter.emit('end') + gatherer.finished.then(function (gatheredEvents) { + expectedSequence.forEach(function (expectedEvent, i) { + t.equal(JSON.stringify(expectedEvent), JSON.stringify(gatheredEvents[i])) + }) + t.end() + }) +}) + +test('reversed listener registration', function (t) { + const emitter = new CorkedEmitter() + const expectedSequence = [ + ['searchEntry', { data: 'a' }], + ['searchEntry', { data: 'b' }], + ['end'] + ] + const gatherer = gatherEventSequence(3) + // This time, we swap the event listener registrations. + // The order of emits should remain unchanged. + emitter.on('end', function (...args) { + gatherer.callback(['end', ...args]) + }) + emitter.on('searchEntry', function (...args) { + gatherer.callback(['searchEntry', ...args]) + }) + emitter.emit('searchEntry', { data: 'a' }) + emitter.emit('searchEntry', { data: 'b' }) + emitter.emit('end') + gatherer.finished.then(function (gatheredEvents) { + expectedSequence.forEach(function (expectedEvent, i) { + t.equal(JSON.stringify(expectedEvent), JSON.stringify(gatheredEvents[i])) + }) + t.end() + }) +}) + +test('delayed listener registration', function (t) { + const emitter = new CorkedEmitter() + const expectedSequence = [ + ['searchEntry', { data: 'a' }], + ['searchEntry', { data: 'b' }], + ['end'] + ] + const gatherer = gatherEventSequence(3) + emitter.emit('searchEntry', { data: 'a' }) + emitter.emit('searchEntry', { data: 'b' }) + emitter.emit('end') + // The listeners only appear after a brief delay - this simulates + // the situation described in https://github.com/ldapjs/node-ldapjs/issues/602 + // and in https://github.com/ifroz/node-ldapjs/commit/5239f6c68827f2c25b4589089c199d15bb882412 + setTimeout(function () { + emitter.on('end', function (...args) { + gatherer.callback(['end', ...args]) + }) + emitter.on('searchEntry', function (...args) { + gatherer.callback(['searchEntry', ...args]) + }) + }, 50) + gatherer.finished.then(function (gatheredEvents) { + expectedSequence.forEach(function (expectedEvent, i) { + t.equal(JSON.stringify(expectedEvent), JSON.stringify(gatheredEvents[i])) + }) + t.end() + }) +}) diff --git a/node_modules/ldapjs/test/errors.test.js b/node_modules/ldapjs/test/errors.test.js new file mode 100644 index 0000000..6b66a8a --- /dev/null +++ b/node_modules/ldapjs/test/errors.test.js @@ -0,0 +1,53 @@ +'use strict' + +const { test } = require('tap') +const { + LDAPError, + ConnectionError, + AbandonedError, + TimeoutError, + ConstraintViolationError, + LDAP_OTHER +} = require('../lib') + +test('basic error', function (t) { + const msg = 'mymsg' + const err = new LDAPError(msg, null, null) + t.ok(err) + t.equal(err.name, 'LDAPError') + t.equal(err.code, LDAP_OTHER) + t.equal(err.dn, '') + t.equal(err.message, msg) + t.end() +}) + +test('exports ConstraintViolationError', function (t) { + const msg = 'mymsg' + const err = new ConstraintViolationError(msg, null, null) + t.ok(err) + t.equal(err.name, 'ConstraintViolationError') + t.equal(err.code, 19) + t.equal(err.dn, '') + t.equal(err.message, msg) + t.end() +}) + +test('"custom" errors', function (t) { + const errors = [ + { name: 'ConnectionError', Func: ConnectionError }, + { name: 'AbandonedError', Func: AbandonedError }, + { name: 'TimeoutError', Func: TimeoutError } + ] + + errors.forEach(function (entry) { + const msg = entry.name + 'msg' + const err = new entry.Func(msg) + t.ok(err) + t.equal(err.name, entry.name) + t.equal(err.code, LDAP_OTHER) + t.equal(err.dn, '') + t.equal(err.message, msg) + }) + + t.end() +}) diff --git a/node_modules/ldapjs/test/imgs/test.jpg b/node_modules/ldapjs/test/imgs/test.jpg new file mode 100644 index 0000000..97ce548 Binary files /dev/null and b/node_modules/ldapjs/test/imgs/test.jpg differ diff --git a/node_modules/ldapjs/test/issue-845.test.js b/node_modules/ldapjs/test/issue-845.test.js new file mode 100644 index 0000000..6b32b9d --- /dev/null +++ b/node_modules/ldapjs/test/issue-845.test.js @@ -0,0 +1,116 @@ +'use strict' + +const tap = require('tap') +const { SearchResultEntry, SearchRequest } = require('@ldapjs/messages') +const ldapjs = require('../') + +const server = ldapjs.createServer() + +const SUFFIX = '' +const directory = { + 'dc=example,dc=com': { + objectclass: 'example', + dc: 'example', + cn: 'example' + } +} + +server.bind(SUFFIX, (req, res, done) => { + res.end() + return done() +}) + +server.search(SUFFIX, (req, res, done) => { + const dn = req.dn.toString().toLowerCase() + + if (Object.hasOwn(directory, dn) === false) { + return done(Error('not in directory')) + } + + switch (req.scope) { + case SearchRequest.SCOPE_BASE: + case SearchRequest.SCOPE_SUBTREE: { + res.send(new SearchResultEntry({ objectName: `dc=${req.scopeName}` })) + break + } + } + + res.end() + done() +}) + +tap.beforeEach(t => { + return new Promise((resolve, reject) => { + server.listen(0, '127.0.0.1', (err) => { + if (err) return reject(err) + t.context.url = server.url + + t.context.client = ldapjs.createClient({ url: [server.url] }) + t.context.searchOpts = { + filter: '(&(objectClass=*))', + scope: 'sub', + attributes: ['dn', 'cn'] + } + + resolve() + }) + }) +}) + +tap.afterEach(t => { + return new Promise((resolve, reject) => { + t.context.client.destroy() + server.close((err) => { + if (err) return reject(err) + resolve() + }) + }) +}) + +tap.test('rejects if search not in directory', t => { + const { client, searchOpts } = t.context + + client.search('dc=nope', searchOpts, (err, res) => { + t.error(err) + res.on('error', err => { + // TODO: plain error messages should not be lost + // This should be fixed in a revamp of the server code. + // ~ jsumners 2023-03-08 + t.equal(err.lde_message, 'Operations Error') + t.end() + }) + }) +}) + +tap.test('base scope matches', t => { + const { client, searchOpts } = t.context + searchOpts.scope = 'base' + + client.search('dc=example,dc=com', searchOpts, (err, res) => { + t.error(err) + res.on('error', (err) => { + t.error(err) + t.end() + }) + res.on('searchEntry', entry => { + t.equal(entry.objectName.toString(), 'dc=base') + t.end() + }) + }) +}) + +tap.test('sub scope matches', t => { + const { client, searchOpts } = t.context + + client.search('dc=example,dc=com', searchOpts, (err, res) => { + t.error(err) + res.on('error', (err) => { + t.error(err) + t.end() + }) + res.on('searchEntry', entry => { + t.equal(entry.objectName.toString(), 'dc=subtree') + t.end() + }) + }) +}) diff --git a/node_modules/ldapjs/test/issue-890.test.js b/node_modules/ldapjs/test/issue-890.test.js new file mode 100644 index 0000000..e0f8ba1 --- /dev/null +++ b/node_modules/ldapjs/test/issue-890.test.js @@ -0,0 +1,103 @@ +'use strict' + +// This test is complicated. It must simulate a server sending an unsolicited, +// or a mismatched, message in order to force the client's internal message +// tracker to try and find a corresponding sent message that does not exist. +// In order to do that, we need to set a high test timeout and wait for the +// error message to be logged. + +const tap = require('tap') +const ldapjs = require('../') +const { SearchResultEntry } = require('@ldapjs/messages') +const server = ldapjs.createServer() +const SUFFIX = '' + +tap.timeout = 10000 + +server.bind(SUFFIX, (res, done) => { + res.end() + return done() +}) + +server.search(SUFFIX, (req, res, done) => { + const result = new SearchResultEntry({ + objectName: `dc=${req.scopeName}` + }) + + // Respond to the search request with a matched response. + res.send(result) + res.end() + + // After a short delay, send ANOTHER response to the client that will not + // be matched by the client's internal tracker. + setTimeout( + () => { + res.send(result) + res.end() + done() + }, + 100 + ) +}) + +tap.beforeEach(t => { + return new Promise((resolve, reject) => { + server.listen(0, '127.0.0.1', (err) => { + if (err) return reject(err) + + t.context.logMessages = [] + t.context.logger = { + child () { return this }, + debug () {}, + error (...args) { + t.context.logMessages.push(args) + }, + trace () {} + } + + t.context.url = server.url + t.context.client = ldapjs.createClient({ + url: [server.url], + timeout: 5, + log: t.context.logger + }) + + resolve() + }) + }) +}) + +tap.afterEach(t => { + return new Promise((resolve, reject) => { + t.context.client.destroy() + server.close((err) => { + if (err) return reject(err) + resolve() + }) + }) +}) + +tap.test('handle null messages', t => { + const { client, logMessages } = t.context + + // There's no way to get an error from the client when it has received an + // unmatched response from the server. So we need to poll our logger instance + // and detect when the corresponding error message has been logged. + const timer = setInterval( + () => { + if (logMessages.length > 0) { + t.equal( + logMessages.some(msg => msg[1] === 'unmatched server message received'), + true + ) + clearInterval(timer) + t.end() + } + }, + 100 + ) + + client.search('dc=test', (error) => { + t.error(error) + }) +}) diff --git a/node_modules/ldapjs/test/laundry.test.js b/node_modules/ldapjs/test/laundry.test.js new file mode 100644 index 0000000..909bc9d --- /dev/null +++ b/node_modules/ldapjs/test/laundry.test.js @@ -0,0 +1,143 @@ +'use strict' + +const tap = require('tap') +const { getSock, uuid } = require('./utils') +const { SearchResultEntry } = require('@ldapjs/messages') +const Attribute = require('@ldapjs/attribute') +const ldap = require('../lib') + +function search (t, options, callback) { + t.context.client.search(t.context.suffix, options, function (err, res) { + t.error(err) + t.ok(res) + let found = false + res.on('searchEntry', function (entry) { + t.ok(entry) + found = true + }) + res.on('end', function () { + t.ok(found) + if (callback) return callback() + return t.end() + }) + }) +} + +tap.beforeEach((t) => { + return new Promise((resolve, reject) => { + const suffix = `dc=${uuid()}` + const server = ldap.createServer() + + t.context.server = server + t.context.socketPath = getSock() + t.context.suffix = suffix + + server.on('error', err => { + server.close(() => reject(err)) + }) + + server.bind('cn=root', function (req, res, next) { + res.end() + return next() + }) + + server.search(suffix, function (req, res) { + const entry = new SearchResultEntry({ + entry: 'cn=foo,' + suffix, + attributes: Attribute.fromObject({ + objectclass: ['person', 'top'], + cn: 'Pogo Stick', + sn: 'Stick', + givenname: 'ogo', + mail: uuid() + '@pogostick.org' + }) + }) + + if (req.filter.matches(entry.attributes)) { + res.send(entry) + } + + res.end() + }) + + server.listen(t.context.socketPath, function () { + t.context.client = ldap.createClient({ + socketPath: t.context.socketPath + }) + + t.context.client.on('error', (err) => { + t.context.server.close(() => reject(err)) + }) + t.context.client.on('connectError', (err) => { + t.context.server.close(() => reject(err)) + }) + t.context.client.on('connect', (socket) => { + t.context.socket = socket + resolve() + }) + }) + }) +}) + +tap.afterEach((t) => { + return new Promise((resolve, reject) => { + if (!t.context.client) return resolve() + t.context.client.unbind(() => { + t.context.server.close((err) => { + if (err) return reject(err) + resolve() + }) + }) + }) +}) + +tap.test('Evolution search filter (GH-3)', function (t) { + // This is what Evolution sends, when searching for a contact 'ogo'. Wow. + const filter = + '(|(cn=ogo*)(givenname=ogo*)(sn=ogo*)(mail=ogo*)(member=ogo*)' + + '(primaryphone=ogo*)(telephonenumber=ogo*)(homephone=ogo*)(mobile=ogo*)' + + '(carphone=ogo*)(facsimiletelephonenumber=ogo*)' + + '(homefacsimiletelephonenumber=ogo*)(otherphone=ogo*)' + + '(otherfacsimiletelephonenumber=ogo*)(internationalisdnnumber=ogo*)' + + '(pager=ogo*)(radio=ogo*)(telex=ogo*)(assistantphone=ogo*)' + + '(companyphone=ogo*)(callbackphone=ogo*)(tty=ogo*)(o=ogo*)(ou=ogo*)' + + '(roomnumber=ogo*)(title=ogo*)(businessrole=ogo*)(managername=ogo*)' + + '(assistantname=ogo*)(postaladdress=ogo*)(l=ogo*)(st=ogo*)' + + '(postofficebox=ogo*)(postalcode=ogo*)(c=ogo*)(homepostaladdress=ogo*)' + + '(mozillahomelocalityname=ogo*)(mozillahomestate=ogo*)' + + '(mozillahomepostalcode=ogo*)(mozillahomecountryname=ogo*)' + + '(otherpostaladdress=ogo*)(jpegphoto=ogo*)(usercertificate=ogo*)' + + '(labeleduri=ogo*)(displayname=ogo*)(spousename=ogo*)(note=ogo*)' + + '(anniversary=ogo*)(birthdate=ogo*)(mailer=ogo*)(fileas=ogo*)' + + '(category=ogo*)(calcaluri=ogo*)(calfburl=ogo*)(icscalendar=ogo*))' + + return search(t, filter) +}) + +tap.test('GH-49 Client errors on bad attributes', function (t) { + const searchOpts = { + filter: 'cn=*ogo*', + scope: 'one', + attributes: 'dn' + } + return search(t, searchOpts) +}) + +tap.test('GH-55 Client emits connect multiple times', function (t) { + const c = ldap.createClient({ + socketPath: t.context.socketPath + }) + + let count = 0 + c.on('connect', function (socket) { + t.ok(socket) + count++ + c.bind('cn=root', 'secret', function (err) { + t.error(err) + c.unbind(function () { + t.equal(count, 1) + t.end() + }) + }) + }) +}) diff --git a/node_modules/ldapjs/test/lib/client/message-tracker/ge-window.test.js b/node_modules/ldapjs/test/lib/client/message-tracker/ge-window.test.js new file mode 100644 index 0000000..9cafe04 --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/message-tracker/ge-window.test.js @@ -0,0 +1,47 @@ +'use strict' + +const { test } = require('tap') +const { MAX_MSGID } = require('../../../../lib/client/constants') +const geWindow = require('../../../../lib/client/message-tracker/ge-window') + +test('comp > (ref in upper window) => true', async t => { + const ref = Math.floor(MAX_MSGID / 2) + 10 + const comp = ref + 10 + const result = geWindow(ref, comp) + t.equal(result, true) +}) + +test('comp < (ref in upper window) => false', async t => { + const ref = Math.floor(MAX_MSGID / 2) + 10 + const comp = ref - 5 + const result = geWindow(ref, comp) + t.equal(result, false) +}) + +test('comp > (ref in lower window) => true', async t => { + const ref = Math.floor(MAX_MSGID / 2) - 10 + const comp = ref + 20 + const result = geWindow(ref, comp) + t.equal(result, true) +}) + +test('comp < (ref in lower window) => false', async t => { + const ref = Math.floor(MAX_MSGID / 2) - 10 + const comp = ref - 5 + const result = geWindow(ref, comp) + t.equal(result, false) +}) + +test('(max === MAX_MSGID) && (comp > ref) => true', async t => { + const ref = MAX_MSGID - Math.floor(MAX_MSGID / 2) + const comp = ref + 1 + const result = geWindow(ref, comp) + t.equal(result, true) +}) + +test('(max === MAX_MSGID) && (comp < ref) => false', async t => { + const ref = MAX_MSGID - Math.floor(MAX_MSGID / 2) + const comp = ref - 1 + const result = geWindow(ref, comp) + t.equal(result, false) +}) diff --git a/node_modules/ldapjs/test/lib/client/message-tracker/id-generator.test.js b/node_modules/ldapjs/test/lib/client/message-tracker/id-generator.test.js new file mode 100644 index 0000000..2344730 --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/message-tracker/id-generator.test.js @@ -0,0 +1,21 @@ +'use strict' + +const { test } = require('tap') +const { MAX_MSGID } = require('../../../../lib/client/constants') +const idGeneratorFactory = require('../../../../lib/client/message-tracker/id-generator') + +test('starts at 0', async t => { + const nextID = idGeneratorFactory() + const currentID = nextID() + t.equal(currentID, 1) +}) + +test('handles wrapping around', async t => { + const nextID = idGeneratorFactory(MAX_MSGID - 2) + + let currentID = nextID() + t.equal(currentID, MAX_MSGID - 1) + + currentID = nextID() + t.equal(currentID, 1) +}) diff --git a/node_modules/ldapjs/test/lib/client/message-tracker/index.test.js b/node_modules/ldapjs/test/lib/client/message-tracker/index.test.js new file mode 100644 index 0000000..0aa4de2 --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/message-tracker/index.test.js @@ -0,0 +1,201 @@ +'use strict' + +const tap = require('tap') +const messageTrackerFactory = require('../../../../lib/client/message-tracker/') + +tap.test('options', t => { + t.test('requires an options object', async t => { + try { + messageTrackerFactory() + } catch (error) { + t.match(error, /options object is required/) + } + + try { + messageTrackerFactory([]) + } catch (error) { + t.match(error, /options object is required/) + } + + try { + messageTrackerFactory('') + } catch (error) { + t.match(error, /options object is required/) + } + + try { + messageTrackerFactory(42) + } catch (error) { + t.match(error, /options object is required/) + } + }) + + t.test('requires id to be a string', async t => { + try { + messageTrackerFactory({ id: {} }) + } catch (error) { + t.match(error, /options\.id string is required/) + } + + try { + messageTrackerFactory({ id: [] }) + } catch (error) { + t.match(error, /options\.id string is required/) + } + + try { + messageTrackerFactory({ id: 42 }) + } catch (error) { + t.match(error, /options\.id string is required/) + } + }) + + t.test('requires parser to be an object', async t => { + try { + messageTrackerFactory({ id: 'foo', parser: 'bar' }) + } catch (error) { + t.match(error, /options\.parser object is required/) + } + + try { + messageTrackerFactory({ id: 'foo', parser: 42 }) + } catch (error) { + t.match(error, /options\.parser object is required/) + } + + try { + messageTrackerFactory({ id: 'foo', parser: [] }) + } catch (error) { + t.match(error, /options\.parser object is required/) + } + }) + + t.end() +}) + +tap.test('.pending', t => { + t.test('returns 0 for no messages', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + t.equal(tracker.pending, 0) + }) + + t.test('returns 1 for 1 message', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, () => {}) + t.equal(tracker.pending, 1) + }) + + t.end() +}) + +tap.test('#abandon', t => { + t.test('returns false if message does not exist', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + const result = tracker.abandon(1) + t.equal(result, false) + }) + + t.test('returns true if message is abandoned', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, {}) + const result = tracker.abandon(1) + t.equal(result, true) + }) + + t.end() +}) + +tap.test('#fetch', t => { + t.test('returns handler for fetched message', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, handler) + const { callback: fetched } = tracker.fetch(1) + t.equal(fetched, handler) + + function handler () {} + }) + + t.test('returns handler for fetched abandoned message', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, handler) + tracker.track({ abandon: 'message' }, () => {}) + tracker.abandon(1) + const { callback: fetched } = tracker.fetch(1) + t.equal(fetched, handler) + + function handler () {} + }) + + t.test('returns null when message does not exist', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + const fetched = tracker.fetch(1) + t.equal(fetched, null) + }) + + t.end() +}) + +tap.test('#purge', t => { + t.test('invokes cb for each tracked message', async t => { + t.plan(4) + let count = 0 + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, handler1) + tracker.track({}, handler2) + tracker.purge(cb) + + function cb (msgID, handler) { + if (count === 0) { + t.equal(msgID, 1) + t.equal(handler, handler1) + count += 1 + return + } + t.equal(msgID, 2) + t.equal(handler, handler2) + } + + function handler1 () {} + function handler2 () {} + }) + + t.end() +}) + +tap.test('#remove', t => { + t.test('removes from the current track', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, () => {}) + tracker.remove(1) + t.equal(tracker.pending, 0) + }) + + // Not a great test. It exercises the desired code path, but we probably + // should expose some insight into the abandoned track. + t.test('removes from the abandoned track', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + tracker.track({}, () => {}) + tracker.track({ abandon: 'message' }, () => {}) + tracker.abandon(1) + tracker.remove(1) + t.equal(tracker.pending, 1) + }) + + t.end() +}) + +tap.test('#track', t => { + t.test('add messageId and tracks message', async t => { + const tracker = messageTrackerFactory({ id: 'foo', parser: {} }) + const msg = {} + tracker.track(msg, handler) + + t.same(msg, { messageId: 1 }) + const { callback: cb } = tracker.fetch(1) + t.equal(cb, handler) + + function handler () {} + }) + + t.end() +}) diff --git a/node_modules/ldapjs/test/lib/client/message-tracker/purge-abandoned.test.js b/node_modules/ldapjs/test/lib/client/message-tracker/purge-abandoned.test.js new file mode 100644 index 0000000..8a11d29 --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/message-tracker/purge-abandoned.test.js @@ -0,0 +1,64 @@ +'use strict' + +const { test } = require('tap') +const { MAX_MSGID } = require('../../../../lib/client/constants') +const purgeAbandoned = require('../../../../lib/client/message-tracker/purge-abandoned') + +test('clears queue if only one message present', async t => { + t.plan(3) + const abandoned = new Map() + abandoned.set(1, { age: 2, cb }) + + purgeAbandoned(2, abandoned) + t.equal(abandoned.size, 0) + + function cb (err) { + t.equal(err.name, 'AbandonedError') + t.equal(err.message, 'client request abandoned') + } +}) + +test('clears queue if multiple messages present', async t => { + t.plan(5) + const abandoned = new Map() + abandoned.set(1, { age: 2, cb }) + abandoned.set(2, { age: 3, cb }) + + purgeAbandoned(4, abandoned) + t.equal(abandoned.size, 0) + + function cb (err) { + t.equal(err.name, 'AbandonedError') + t.equal(err.message, 'client request abandoned') + } +}) + +test('message id has wrappred around', async t => { + t.plan(3) + const abandoned = new Map() + abandoned.set(MAX_MSGID - 1, { age: MAX_MSGID, cb }) + + // The "abandon" message was sent with an id of "MAX_MSGID". So the message + // that is triggering the purge was the "first" message in the new sequence + // of message identifiers. + purgeAbandoned(1, abandoned) + t.equal(abandoned.size, 0) + + function cb (err) { + t.equal(err.name, 'AbandonedError') + t.equal(err.message, 'client request abandoned') + } +}) + +test('does not clear if window not met', async t => { + t.plan(1) + const abandoned = new Map() + abandoned.set(1, { age: 2, cb }) + + purgeAbandoned(1, abandoned) + t.equal(abandoned.size, 1) + + function cb () { + t.fail('should not be invoked') + } +}) diff --git a/node_modules/ldapjs/test/lib/client/request-queue/enqueue.test.js b/node_modules/ldapjs/test/lib/client/request-queue/enqueue.test.js new file mode 100644 index 0000000..8db44ec --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/request-queue/enqueue.test.js @@ -0,0 +1,82 @@ +'use strict' + +const { test } = require('tap') +const enqueue = require('../../../../lib/client/request-queue/enqueue') + +test('rejects new requests if size is exceeded', async t => { + const q = { _queue: { size: 5 }, size: 5 } + const result = enqueue.call(q, 'foo', 'bar', {}, {}) + t.notOk(result) +}) + +test('rejects new requests if queue is frozen', async t => { + const q = { _queue: { size: 0 }, size: 5, _frozen: true } + const result = enqueue.call(q, 'foo', 'bar', {}, {}) + t.notOk(result) +}) + +test('adds a request and returns if no timeout', async t => { + const q = { + _queue: { + size: 0, + add (obj) { + t.same(obj, { + message: 'foo', + expect: 'bar', + emitter: 'baz', + cb: 'bif' + }) + } + }, + _frozen: false, + timeout: 0 + } + const result = enqueue.call(q, 'foo', 'bar', 'baz', 'bif') + t.ok(result) +}) + +test('adds a request and returns timer not set', async t => { + const q = { + _queue: { + size: 0, + add (obj) { + t.same(obj, { + message: 'foo', + expect: 'bar', + emitter: 'baz', + cb: 'bif' + }) + } + }, + _frozen: false, + timeout: 100, + _timer: null + } + const result = enqueue.call(q, 'foo', 'bar', 'baz', 'bif') + t.ok(result) +}) + +test('adds a request, returns true, and clears queue', t => { + // Must not be an async test due to an internal `setTimeout` + t.plan(4) + const q = { + _queue: { + size: 0, + add (obj) { + t.same(obj, { + message: 'foo', + expect: 'bar', + emitter: 'baz', + cb: 'bif' + }) + } + }, + _frozen: false, + timeout: 5, + _timer: 123, + freeze () { t.pass() }, + purge () { t.pass() } + } + const result = enqueue.call(q, 'foo', 'bar', 'baz', 'bif') + t.ok(result) +}) diff --git a/node_modules/ldapjs/test/lib/client/request-queue/flush.test.js b/node_modules/ldapjs/test/lib/client/request-queue/flush.test.js new file mode 100644 index 0000000..a999e08 --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/request-queue/flush.test.js @@ -0,0 +1,51 @@ +'use strict' + +const { test } = require('tap') +const flush = require('../../../../lib/client/request-queue/flush') + +test('clears timer', async t => { + t.plan(2) + const q = { + _timer: 123, + _queue: { + values () { + return [] + }, + clear () { + t.pass() + } + } + } + flush.call(q) + t.equal(q._timer, null) +}) + +test('invokes callback with parameters', async t => { + t.plan(6) + const req = { + message: 'foo', + expect: 'bar', + emitter: 'baz', + cb: theCB + } + const q = { + _timer: 123, + _queue: { + values () { + return [req] + }, + clear () { + t.pass() + } + } + } + flush.call(q, (message, expect, emitter, cb) => { + t.equal(message, 'foo') + t.equal(expect, 'bar') + t.equal(emitter, 'baz') + t.equal(cb, theCB) + }) + t.equal(q._timer, null) + + function theCB () {} +}) diff --git a/node_modules/ldapjs/test/lib/client/request-queue/purge.test.js b/node_modules/ldapjs/test/lib/client/request-queue/purge.test.js new file mode 100644 index 0000000..c0d2c9c --- /dev/null +++ b/node_modules/ldapjs/test/lib/client/request-queue/purge.test.js @@ -0,0 +1,18 @@ +'use strict' + +const { test } = require('tap') +const purge = require('../../../../lib/client/request-queue/purge') + +test('flushes the queue with timeout errors', async t => { + t.plan(3) + const q = { + flush (func) { + func('a', 'b', 'c', (err) => { + t.ok(err) + t.equal(err.name, 'TimeoutError') + t.equal(err.message, 'request queue timeout') + }) + } + } + purge.call(q) +}) diff --git a/node_modules/ldapjs/test/messages/parser.test.js b/node_modules/ldapjs/test/messages/parser.test.js new file mode 100644 index 0000000..d844952 --- /dev/null +++ b/node_modules/ldapjs/test/messages/parser.test.js @@ -0,0 +1,16 @@ +'use strict' + +const { test } = require('tap') +const { Parser } = require('../../lib') + +test('wrong protocol error', function (t) { + const p = new Parser() + + p.once('error', function (err) { + t.ok(err) + t.end() + }) + + // Send some bogus data to incur an error + p.write(Buffer.from([16, 1, 4])) +}) diff --git a/node_modules/ldapjs/test/server.test.js b/node_modules/ldapjs/test/server.test.js new file mode 100644 index 0000000..35c8230 --- /dev/null +++ b/node_modules/ldapjs/test/server.test.js @@ -0,0 +1,471 @@ +'use strict' + +const net = require('net') +const tap = require('tap') +const vasync = require('vasync') +const vm = require('node:vm') +const { getSock } = require('./utils') +const ldap = require('../lib') + +const SERVER_PORT = process.env.SERVER_PORT || 1389 +const SUFFIX = 'dc=test' + +tap.beforeEach(function (t) { + // We do not need a `.afterEach` to clean up the sock files because that + // is done when the server is destroyed. + t.context.sock = getSock() +}) + +tap.test('basic create', function (t) { + const server = ldap.createServer() + t.ok(server) + t.end() +}) + +tap.test('connection count', function (t) { + const server = ldap.createServer() + t.ok(server) + server.listen(0, '127.0.0.1', function () { + t.ok(true, 'server listening on ' + server.url) + + server.getConnections(function (err, count) { + t.error(err) + t.equal(count, 0) + + const client = ldap.createClient({ url: server.url }) + client.on('connect', function () { + t.ok(true, 'client connected') + server.getConnections(function (err, count) { + t.error(err) + t.equal(count, 1) + client.unbind() + server.close(() => t.end()) + }) + }) + }) + }) +}) + +tap.test('properties', function (t) { + const server = ldap.createServer() + t.equal(server.name, 'LDAPServer') + + // TODO: better test + server.maxConnections = 10 + t.equal(server.maxConnections, 10) + + t.equal(server.url, null, 'url empty before bind') + // listen on a random port so we have a url + server.listen(0, '127.0.0.1', function () { + t.ok(server.url) + + server.close(() => t.end()) + }) +}) + +tap.test('IPv6 URL is formatted correctly', function (t) { + const server = ldap.createServer() + t.equal(server.url, null, 'url empty before bind') + server.listen(0, '::1', function () { + t.ok(server.url) + t.equal(server.url, 'ldap://[::1]:' + server.port) + + server.close(() => t.end()) + }) +}) + +tap.test('listen on unix/named socket', function (t) { + const server = ldap.createServer() + server.listen(t.context.sock, function () { + t.ok(server.url) + t.equal(server.url.split(':')[0], 'ldapi') + server.close(() => t.end()) + }) +}) + +tap.test('listen on static port', function (t) { + const server = ldap.createServer() + server.listen(SERVER_PORT, '127.0.0.1', function () { + const addr = server.address() + t.equal(addr.port, parseInt(SERVER_PORT, 10)) + t.equal(server.url, `ldap://127.0.0.1:${SERVER_PORT}`) + server.close(() => t.end()) + }) +}) + +tap.test('listen on ephemeral port', function (t) { + const server = ldap.createServer() + server.listen(0, '127.0.0.1', function () { + const addr = server.address() + t.ok(addr.port > 0) + t.ok(addr.port < 65535) + server.close(() => t.end()) + }) +}) + +tap.test('route order', function (t) { + function generateHandler (response) { + const func = function handler (req, res, next) { + res.send({ + dn: response, + attributes: { } + }) + res.end() + return next() + } + return func + } + + const server = ldap.createServer() + const sock = t.context.sock + const dnShort = SUFFIX + const dnMed = 'dc=sub,' + SUFFIX + const dnLong = 'dc=long,dc=sub,' + SUFFIX + + // Mount routes out of order + server.search(dnMed, generateHandler(dnMed)) + server.search(dnShort, generateHandler(dnShort)) + server.search(dnLong, generateHandler(dnLong)) + server.listen(sock, function () { + t.ok(true, 'server listen') + const client = ldap.createClient({ socketPath: sock }) + client.on('connect', () => { + vasync.forEachParallel({ + func: runSearch, + inputs: [dnShort, dnMed, dnLong] + }, function (err) { + t.error(err) + client.unbind() + server.close(() => t.end()) + }) + }) + + function runSearch (value, cb) { + client.search(value, '(objectclass=*)', function (err, res) { + t.error(err) + t.ok(res) + res.on('searchEntry', function (entry) { + t.equal(entry.dn.toString(), value) + }) + res.on('end', function () { + cb() + }) + }) + } + }) +}) + +tap.test('route absent', function (t) { + const server = ldap.createServer() + const DN_ROUTE = 'dc=base' + const DN_MISSING = 'dc=absent' + + server.bind(DN_ROUTE, function (req, res, next) { + res.end() + return next() + }) + + server.listen(t.context.sock, function () { + t.ok(true, 'server startup') + vasync.parallel({ + funcs: [ + function presentBind (cb) { + const clt = ldap.createClient({ socketPath: t.context.sock }) + clt.bind(DN_ROUTE, '', function (err) { + t.notOk(err) + clt.unbind() + cb() + }) + }, + function absentBind (cb) { + const clt = ldap.createClient({ socketPath: t.context.sock }) + clt.bind(DN_MISSING, '', function (err) { + t.ok(err) + t.equal(err.code, ldap.LDAP_NO_SUCH_OBJECT) + clt.unbind() + cb() + }) + } + ] + }, function (err) { + t.notOk(err) + server.close(() => t.end()) + }) + }) +}) + +tap.test('route unbind', function (t) { + const server = ldap.createServer() + + server.unbind(function (req, res, next) { + t.ok(true, 'server unbind successful') + res.end() + return next() + }) + + server.listen(t.context.sock, function () { + t.ok(true, 'server startup') + const client = ldap.createClient({ socketPath: t.context.sock }) + client.bind('', '', function (err) { + t.error(err, 'client bind error') + client.unbind(function (err) { + t.error(err, 'client unbind error') + server.close(() => t.end()) + }) + }) + }) +}) + +tap.test('bind/unbind identity anonymous', function (t) { + const server = ldap.createServer({ + connectionRouter: function (c) { + server.newConnection(c) + server.emit('testconnection', c) + } + }) + + server.unbind(function (req, res, next) { + t.ok(true, 'server unbind successful') + res.end() + return next() + }) + + server.bind('', function (req, res, next) { + t.ok(true, 'server bind successful') + res.end() + return next() + }) + + const anonDN = ldap.parseDN('cn=anonymous') + + server.listen(t.context.sock, function () { + t.ok(true, 'server startup') + + const client = ldap.createClient({ socketPath: t.context.sock }) + server.once('testconnection', (c) => { + t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct') + client.bind('', '', function (err) { + t.error(err, 'client anon bind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'anon bind dn is correct') + client.unbind(function (err) { + t.error(err, 'client anon unbind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'anon unbind dn is correct') + server.close(() => t.end()) + }) + }) + }) + }) +}) + +tap.test('does not crash on empty DN values', function (t) { + const server = ldap.createServer({ + connectionRouter: function (c) { + server.newConnection(c) + server.emit('testconnection', c) + } + }) + + server.listen(t.context.sock, function () { + const client = ldap.createClient({ socketPath: t.context.sock }) + server.once('testconnection', () => { + client.bind('', 'pw', function (err) { + t.ok(err, 'blank bind dn throws error') + client.unbind(function () { + server.close(() => t.end()) + }) + }) + }) + }) +}) + +tap.test('bind/unbind identity user', function (t) { + const server = ldap.createServer({ + connectionRouter: function (c) { + server.newConnection(c) + server.emit('testconnection', c) + } + }) + + server.unbind(function (req, res, next) { + t.ok(true, 'server unbind successful') + res.end() + return next() + }) + + server.bind('', function (req, res, next) { + t.ok(true, 'server bind successful') + res.end() + return next() + }) + + const anonDN = ldap.parseDN('cn=anonymous') + const testDN = ldap.parseDN('cn=anotheruser') + + server.listen(t.context.sock, function () { + t.ok(true, 'server startup') + + const client = ldap.createClient({ socketPath: t.context.sock }) + server.once('testconnection', (c) => { + t.ok(anonDN.equals(c.ldap.bindDN), 'pre bind dn is correct') + client.bind(testDN.toString(), 'somesecret', function (err) { + t.error(err, 'user bind error') + t.ok(testDN.equals(c.ldap.bindDN), 'user bind dn is correct') + // check rebinds too + client.bind('', '', function (err) { + t.error(err, 'client anon bind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'anon bind dn is correct') + // user rebind + client.bind(testDN.toString(), 'somesecret', function (err) { + t.error(err, 'user bind error') + t.ok(testDN.equals(c.ldap.bindDN), 'user rebind dn is correct') + client.unbind(function (err) { + t.error(err, 'user unbind error') + t.ok(anonDN.equals(c.ldap.bindDN), 'user unbind dn is correct') + server.close(() => t.end()) + }) + }) + }) + }) + }) + }) +}) + +tap.test('strict routing', function (t) { + const testDN = 'cn=valid' + let clt + let server + const sock = t.context.sock + vasync.pipeline({ + funcs: [ + function setup (_, cb) { + server = ldap.createServer({}) + // invalid DNs would go to default handler + server.search('', function (req, res, next) { + t.ok(req.dn) + t.equal(typeof (req.dn), 'object') + t.equal(req.dn.toString(), testDN) + res.end() + next() + }) + server.listen(sock, function () { + t.ok(true, 'server startup') + clt = ldap.createClient({ + socketPath: sock + }) + cb() + }) + }, + function testGood (_, cb) { + clt.search(testDN, { scope: 'base' }, function (err, res) { + t.error(err) + res.once('error', function (err2) { + t.error(err2) + cb(err2) + }) + res.once('end', function (result) { + t.ok(result, 'accepted invalid dn') + cb() + }) + }) + } + ] + }, function (err) { + t.error(err) + if (clt) { + clt.destroy() + } + server.close(() => t.end()) + }) +}) + +tap.test('close accept a callback', function (t) { + const server = ldap.createServer() + // callback is called when the server is closed + server.listen(0, function (err) { + t.error(err) + server.close(function (err) { + t.error(err) + t.end() + }) + }) +}) + +tap.test('close without error calls callback', function (t) { + const server = ldap.createServer() + // when the server is closed without error, the callback parameter is undefined + server.listen(1389, '127.0.0.1', function (err) { + t.error(err) + server.close(function (err) { + t.error(err) + t.end() + }) + }) +}) + +tap.test('close passes error to callback', function (t) { + const server = ldap.createServer() + // when the server is closed with an error, the error is the first parameter of the callback + server.close(function (err) { + t.ok(err) + t.end() + }) +}) + +tap.test('multithreading support via external server', function (t) { + const serverOptions = { } + const server = ldap.createServer(serverOptions) + const fauxServer = net.createServer(serverOptions, (connection) => { + server.newConnection(connection) + }) + fauxServer.log = serverOptions.log + fauxServer.ldap = { + config: serverOptions + } + t.ok(server) + fauxServer.listen(5555, '127.0.0.1', function () { + t.ok(true, 'server listening on ' + server.url) + + t.ok(fauxServer) + const client = ldap.createClient({ url: 'ldap://127.0.0.1:5555' }) + client.on('connect', function () { + t.ok(client) + client.unbind() + fauxServer.close(() => t.end()) + }) + }) +}) + +tap.test('multithreading support via hook', function (t) { + const serverOptions = { + connectionRouter: (connection) => { + server.newConnection(connection) + } + } + const server = ldap.createServer(serverOptions) + const fauxServer = ldap.createServer(serverOptions) + t.ok(server) + fauxServer.listen(0, '127.0.0.1', function () { + t.ok(true, 'server listening on ' + server.url) + + t.ok(fauxServer) + const client = ldap.createClient({ url: fauxServer.url }) + client.on('connect', function () { + t.ok(client) + client.unbind() + fauxServer.close(() => t.end()) + }) + }) +}) + +tap.test('cross-realm type checks', function (t) { + const server = ldap.createServer() + const ctx = vm.createContext({}) + vm.runInContext( + 'globalThis.search=function(){};\n' + + 'globalThis.searches=[function(){}];' + , ctx) + server.search('', ctx.search) + server.search('', ctx.searches) + t.ok(server) + t.end() +}) diff --git a/node_modules/ldapjs/test/url.test.js b/node_modules/ldapjs/test/url.test.js new file mode 100644 index 0000000..3b5e91e --- /dev/null +++ b/node_modules/ldapjs/test/url.test.js @@ -0,0 +1,58 @@ +'use strict' + +const { test } = require('tap') +const { parseURL } = require('../lib') + +test('parse empty', function (t) { + const u = parseURL('ldap:///') + t.equal(u.hostname, 'localhost') + t.equal(u.port, 389) + t.ok(!u.DN) + t.ok(!u.attributes) + t.equal(u.secure, false) + t.end() +}) + +test('parse hostname', function (t) { + const u = parseURL('ldap://example.com/') + t.equal(u.hostname, 'example.com') + t.equal(u.port, 389) + t.ok(!u.DN) + t.ok(!u.attributes) + t.equal(u.secure, false) + t.end() +}) + +test('parse host and port', function (t) { + const u = parseURL('ldap://example.com:1389/') + t.equal(u.hostname, 'example.com') + t.equal(u.port, 1389) + t.ok(!u.DN) + t.ok(!u.attributes) + t.equal(u.secure, false) + t.end() +}) + +test('parse full', function (t) { + const u = parseURL('ldaps://ldap.example.com:1389/dc=example%20,dc=com' + + '?cn,sn?sub?(cn=Babs%20Jensen)') + + t.equal(u.secure, true) + t.equal(u.hostname, 'ldap.example.com') + t.equal(u.port, 1389) + t.equal(u.DN, 'dc=example ,dc=com') + t.ok(u.attributes) + t.equal(u.attributes.length, 2) + t.equal(u.attributes[0], 'cn') + t.equal(u.attributes[1], 'sn') + t.equal(u.scope, 'sub') + t.equal(u.filter.toString(), '(cn=Babs Jensen)') + + t.end() +}) + +test('supports href', function (t) { + const u = parseURL('ldaps://ldap.example.com:1389/dc=example%20,dc=com?cn,sn?sub?(cn=Babs%20Jensen)') + t.equal(u.href, 'ldaps://ldap.example.com:1389/dc=example%20,dc=com?cn,sn?sub?(cn=Babs%20Jensen)') + t.end() +}) diff --git a/node_modules/ldapjs/test/utils.js b/node_modules/ldapjs/test/utils.js new file mode 100644 index 0000000..aea3ea4 --- /dev/null +++ b/node_modules/ldapjs/test/utils.js @@ -0,0 +1,22 @@ +'use strict' + +const os = require('os') +const path = require('path') +const crypto = require('crypto') + +function uuid () { + return crypto.randomBytes(16).toString('hex') +} + +function getSock () { + if (process.platform === 'win32') { + return '\\\\.\\pipe\\' + uuid() + } else { + return path.join(os.tmpdir(), uuid()) + } +} + +module.exports = { + getSock, + uuid +} diff --git a/node_modules/math-intrinsics/.eslintrc b/node_modules/math-intrinsics/.eslintrc new file mode 100644 index 0000000..d90a1bc --- /dev/null +++ b/node_modules/math-intrinsics/.eslintrc @@ -0,0 +1,16 @@ +{ + "root": true, + + "extends": "@ljharb", + + "rules": { + "eqeqeq": ["error", "allow-null"], + "id-length": "off", + "new-cap": ["error", { + "capIsNewExceptions": [ + "RequireObjectCoercible", + "ToObject", + ], + }], + }, +} diff --git a/node_modules/math-intrinsics/.github/FUNDING.yml b/node_modules/math-intrinsics/.github/FUNDING.yml new file mode 100644 index 0000000..868f4ff --- /dev/null +++ b/node_modules/math-intrinsics/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: [ljharb] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: npm/math-intrinsics +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with a single custom sponsorship URL diff --git a/node_modules/math-intrinsics/CHANGELOG.md b/node_modules/math-intrinsics/CHANGELOG.md new file mode 100644 index 0000000..9cf48f5 --- /dev/null +++ b/node_modules/math-intrinsics/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [v1.1.0](https://github.com/es-shims/math-intrinsics/compare/v1.0.0...v1.1.0) - 2024-12-18 + +### Commits + +- [New] add `round` [`7cfb044`](https://github.com/es-shims/math-intrinsics/commit/7cfb04460c0fbdf1ca101eecbac3f59d11994130) +- [Tests] add attw [`e96be8f`](https://github.com/es-shims/math-intrinsics/commit/e96be8fbf58449eafe976446a0470e6ea561ad8d) +- [Dev Deps] update `@types/tape` [`30d0023`](https://github.com/es-shims/math-intrinsics/commit/30d00234ce8a3fa0094a61cd55d6686eb91e36ec) + +## v1.0.0 - 2024-12-11 + +### Commits + +- Initial implementation, tests, readme, types [`b898caa`](https://github.com/es-shims/math-intrinsics/commit/b898caae94e9994a94a42b8740f7bbcfd0a868fe) +- Initial commit [`02745b0`](https://github.com/es-shims/math-intrinsics/commit/02745b03a62255af8a332771987b55d127538d9c) +- [New] add `constants/maxArrayLength`, `mod` [`b978178`](https://github.com/es-shims/math-intrinsics/commit/b978178a57685bd23ed1c7efe2137f3784f5fcc5) +- npm init [`a39fc57`](https://github.com/es-shims/math-intrinsics/commit/a39fc57e5639a645d0bd52a0dc56202480223be2) +- Only apps should have lockfiles [`9451580`](https://github.com/es-shims/math-intrinsics/commit/94515800fb34db4f3cc7e99290042d45609ac7bd) diff --git a/node_modules/math-intrinsics/LICENSE b/node_modules/math-intrinsics/LICENSE new file mode 100644 index 0000000..34995e7 --- /dev/null +++ b/node_modules/math-intrinsics/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ECMAScript Shims + +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. diff --git a/node_modules/math-intrinsics/README.md b/node_modules/math-intrinsics/README.md new file mode 100644 index 0000000..4a66dcf --- /dev/null +++ b/node_modules/math-intrinsics/README.md @@ -0,0 +1,50 @@ +# math-intrinsics [![Version Badge][npm-version-svg]][package-url] + +[![github actions][actions-image]][actions-url] +[![coverage][codecov-image]][codecov-url] +[![License][license-image]][license-url] +[![Downloads][downloads-image]][downloads-url] + +[![npm badge][npm-badge-png]][package-url] + +ES Math-related intrinsics and helpers, robustly cached. + + - `abs` + - `floor` + - `isFinite` + - `isInteger` + - `isNaN` + - `isNegativeZero` + - `max` + - `min` + - `mod` + - `pow` + - `round` + - `sign` + - `constants/maxArrayLength` + - `constants/maxSafeInteger` + - `constants/maxValue` + + +## Tests +Simply clone the repo, `npm install`, and run `npm test` + +## Security + +Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report. + +[package-url]: https://npmjs.org/package/math-intrinsics +[npm-version-svg]: https://versionbadg.es/es-shims/math-intrinsics.svg +[deps-svg]: https://david-dm.org/es-shims/math-intrinsics.svg +[deps-url]: https://david-dm.org/es-shims/math-intrinsics +[dev-deps-svg]: https://david-dm.org/es-shims/math-intrinsics/dev-status.svg +[dev-deps-url]: https://david-dm.org/es-shims/math-intrinsics#info=devDependencies +[npm-badge-png]: https://nodei.co/npm/math-intrinsics.png?downloads=true&stars=true +[license-image]: https://img.shields.io/npm/l/math-intrinsics.svg +[license-url]: LICENSE +[downloads-image]: https://img.shields.io/npm/dm/es-object.svg +[downloads-url]: https://npm-stat.com/charts.html?package=math-intrinsics +[codecov-image]: https://codecov.io/gh/es-shims/math-intrinsics/branch/main/graphs/badge.svg +[codecov-url]: https://app.codecov.io/gh/es-shims/math-intrinsics/ +[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/es-shims/math-intrinsics +[actions-url]: https://github.com/es-shims/math-intrinsics/actions diff --git a/node_modules/math-intrinsics/abs.d.ts b/node_modules/math-intrinsics/abs.d.ts new file mode 100644 index 0000000..14ad9c6 --- /dev/null +++ b/node_modules/math-intrinsics/abs.d.ts @@ -0,0 +1 @@ +export = Math.abs; \ No newline at end of file diff --git a/node_modules/math-intrinsics/abs.js b/node_modules/math-intrinsics/abs.js new file mode 100644 index 0000000..a751424 --- /dev/null +++ b/node_modules/math-intrinsics/abs.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./abs')} */ +module.exports = Math.abs; diff --git a/node_modules/math-intrinsics/constants/maxArrayLength.d.ts b/node_modules/math-intrinsics/constants/maxArrayLength.d.ts new file mode 100644 index 0000000..b92d46b --- /dev/null +++ b/node_modules/math-intrinsics/constants/maxArrayLength.d.ts @@ -0,0 +1,3 @@ +declare const MAX_ARRAY_LENGTH: 4294967295; + +export = MAX_ARRAY_LENGTH; \ No newline at end of file diff --git a/node_modules/math-intrinsics/constants/maxArrayLength.js b/node_modules/math-intrinsics/constants/maxArrayLength.js new file mode 100644 index 0000000..cfc6aff --- /dev/null +++ b/node_modules/math-intrinsics/constants/maxArrayLength.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./maxArrayLength')} */ +module.exports = 4294967295; // Math.pow(2, 32) - 1; diff --git a/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts b/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts new file mode 100644 index 0000000..fee3f62 --- /dev/null +++ b/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts @@ -0,0 +1,3 @@ +declare const MAX_SAFE_INTEGER: 9007199254740991; + +export = MAX_SAFE_INTEGER; \ No newline at end of file diff --git a/node_modules/math-intrinsics/constants/maxSafeInteger.js b/node_modules/math-intrinsics/constants/maxSafeInteger.js new file mode 100644 index 0000000..b568ad3 --- /dev/null +++ b/node_modules/math-intrinsics/constants/maxSafeInteger.js @@ -0,0 +1,5 @@ +'use strict'; + +/** @type {import('./maxSafeInteger')} */ +// eslint-disable-next-line no-extra-parens +module.exports = /** @type {import('./maxSafeInteger')} */ (Number.MAX_SAFE_INTEGER) || 9007199254740991; // Math.pow(2, 53) - 1; diff --git a/node_modules/math-intrinsics/constants/maxValue.d.ts b/node_modules/math-intrinsics/constants/maxValue.d.ts new file mode 100644 index 0000000..292cb82 --- /dev/null +++ b/node_modules/math-intrinsics/constants/maxValue.d.ts @@ -0,0 +1,3 @@ +declare const MAX_VALUE: 1.7976931348623157e+308; + +export = MAX_VALUE; diff --git a/node_modules/math-intrinsics/constants/maxValue.js b/node_modules/math-intrinsics/constants/maxValue.js new file mode 100644 index 0000000..a2202dc --- /dev/null +++ b/node_modules/math-intrinsics/constants/maxValue.js @@ -0,0 +1,5 @@ +'use strict'; + +/** @type {import('./maxValue')} */ +// eslint-disable-next-line no-extra-parens +module.exports = /** @type {import('./maxValue')} */ (Number.MAX_VALUE) || 1.7976931348623157e+308; diff --git a/node_modules/math-intrinsics/floor.d.ts b/node_modules/math-intrinsics/floor.d.ts new file mode 100644 index 0000000..9265236 --- /dev/null +++ b/node_modules/math-intrinsics/floor.d.ts @@ -0,0 +1 @@ +export = Math.floor; \ No newline at end of file diff --git a/node_modules/math-intrinsics/floor.js b/node_modules/math-intrinsics/floor.js new file mode 100644 index 0000000..ab0e5d7 --- /dev/null +++ b/node_modules/math-intrinsics/floor.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./floor')} */ +module.exports = Math.floor; diff --git a/node_modules/math-intrinsics/isFinite.d.ts b/node_modules/math-intrinsics/isFinite.d.ts new file mode 100644 index 0000000..6daae33 --- /dev/null +++ b/node_modules/math-intrinsics/isFinite.d.ts @@ -0,0 +1,3 @@ +declare function isFinite(x: unknown): x is number | bigint; + +export = isFinite; \ No newline at end of file diff --git a/node_modules/math-intrinsics/isFinite.js b/node_modules/math-intrinsics/isFinite.js new file mode 100644 index 0000000..b201a5a --- /dev/null +++ b/node_modules/math-intrinsics/isFinite.js @@ -0,0 +1,12 @@ +'use strict'; + +var $isNaN = require('./isNaN'); + +/** @type {import('./isFinite')} */ +module.exports = function isFinite(x) { + return (typeof x === 'number' || typeof x === 'bigint') + && !$isNaN(x) + && x !== Infinity + && x !== -Infinity; +}; + diff --git a/node_modules/math-intrinsics/isInteger.d.ts b/node_modules/math-intrinsics/isInteger.d.ts new file mode 100644 index 0000000..13935a8 --- /dev/null +++ b/node_modules/math-intrinsics/isInteger.d.ts @@ -0,0 +1,3 @@ +declare function isInteger(argument: unknown): argument is number; + +export = isInteger; \ No newline at end of file diff --git a/node_modules/math-intrinsics/isInteger.js b/node_modules/math-intrinsics/isInteger.js new file mode 100644 index 0000000..4b1b9a5 --- /dev/null +++ b/node_modules/math-intrinsics/isInteger.js @@ -0,0 +1,16 @@ +'use strict'; + +var $abs = require('./abs'); +var $floor = require('./floor'); + +var $isNaN = require('./isNaN'); +var $isFinite = require('./isFinite'); + +/** @type {import('./isInteger')} */ +module.exports = function isInteger(argument) { + if (typeof argument !== 'number' || $isNaN(argument) || !$isFinite(argument)) { + return false; + } + var absValue = $abs(argument); + return $floor(absValue) === absValue; +}; diff --git a/node_modules/math-intrinsics/isNaN.d.ts b/node_modules/math-intrinsics/isNaN.d.ts new file mode 100644 index 0000000..c1d4c55 --- /dev/null +++ b/node_modules/math-intrinsics/isNaN.d.ts @@ -0,0 +1 @@ +export = Number.isNaN; \ No newline at end of file diff --git a/node_modules/math-intrinsics/isNaN.js b/node_modules/math-intrinsics/isNaN.js new file mode 100644 index 0000000..e36475c --- /dev/null +++ b/node_modules/math-intrinsics/isNaN.js @@ -0,0 +1,6 @@ +'use strict'; + +/** @type {import('./isNaN')} */ +module.exports = Number.isNaN || function isNaN(a) { + return a !== a; +}; diff --git a/node_modules/math-intrinsics/isNegativeZero.d.ts b/node_modules/math-intrinsics/isNegativeZero.d.ts new file mode 100644 index 0000000..7ad8819 --- /dev/null +++ b/node_modules/math-intrinsics/isNegativeZero.d.ts @@ -0,0 +1,3 @@ +declare function isNegativeZero(x: unknown): boolean; + +export = isNegativeZero; \ No newline at end of file diff --git a/node_modules/math-intrinsics/isNegativeZero.js b/node_modules/math-intrinsics/isNegativeZero.js new file mode 100644 index 0000000..b69adcc --- /dev/null +++ b/node_modules/math-intrinsics/isNegativeZero.js @@ -0,0 +1,6 @@ +'use strict'; + +/** @type {import('./isNegativeZero')} */ +module.exports = function isNegativeZero(x) { + return x === 0 && 1 / x === 1 / -0; +}; diff --git a/node_modules/math-intrinsics/max.d.ts b/node_modules/math-intrinsics/max.d.ts new file mode 100644 index 0000000..ad6f43e --- /dev/null +++ b/node_modules/math-intrinsics/max.d.ts @@ -0,0 +1 @@ +export = Math.max; \ No newline at end of file diff --git a/node_modules/math-intrinsics/max.js b/node_modules/math-intrinsics/max.js new file mode 100644 index 0000000..edb55df --- /dev/null +++ b/node_modules/math-intrinsics/max.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./max')} */ +module.exports = Math.max; diff --git a/node_modules/math-intrinsics/min.d.ts b/node_modules/math-intrinsics/min.d.ts new file mode 100644 index 0000000..fd90f2d --- /dev/null +++ b/node_modules/math-intrinsics/min.d.ts @@ -0,0 +1 @@ +export = Math.min; \ No newline at end of file diff --git a/node_modules/math-intrinsics/min.js b/node_modules/math-intrinsics/min.js new file mode 100644 index 0000000..5a4a7c7 --- /dev/null +++ b/node_modules/math-intrinsics/min.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./min')} */ +module.exports = Math.min; diff --git a/node_modules/math-intrinsics/mod.d.ts b/node_modules/math-intrinsics/mod.d.ts new file mode 100644 index 0000000..549dbd4 --- /dev/null +++ b/node_modules/math-intrinsics/mod.d.ts @@ -0,0 +1,3 @@ +declare function mod(number: number, modulo: number): number; + +export = mod; \ No newline at end of file diff --git a/node_modules/math-intrinsics/mod.js b/node_modules/math-intrinsics/mod.js new file mode 100644 index 0000000..4a98362 --- /dev/null +++ b/node_modules/math-intrinsics/mod.js @@ -0,0 +1,9 @@ +'use strict'; + +var $floor = require('./floor'); + +/** @type {import('./mod')} */ +module.exports = function mod(number, modulo) { + var remain = number % modulo; + return $floor(remain >= 0 ? remain : remain + modulo); +}; diff --git a/node_modules/math-intrinsics/package.json b/node_modules/math-intrinsics/package.json new file mode 100644 index 0000000..0676273 --- /dev/null +++ b/node_modules/math-intrinsics/package.json @@ -0,0 +1,86 @@ +{ + "name": "math-intrinsics", + "version": "1.1.0", + "description": "ES Math-related intrinsics and helpers, robustly cached.", + "main": false, + "exports": { + "./abs": "./abs.js", + "./floor": "./floor.js", + "./isFinite": "./isFinite.js", + "./isInteger": "./isInteger.js", + "./isNaN": "./isNaN.js", + "./isNegativeZero": "./isNegativeZero.js", + "./max": "./max.js", + "./min": "./min.js", + "./mod": "./mod.js", + "./pow": "./pow.js", + "./sign": "./sign.js", + "./round": "./round.js", + "./constants/maxArrayLength": "./constants/maxArrayLength.js", + "./constants/maxSafeInteger": "./constants/maxSafeInteger.js", + "./constants/maxValue": "./constants/maxValue.js", + "./package.json": "./package.json" + }, + "sideEffects": false, + "scripts": { + "prepack": "npmignore --auto --commentLines=autogenerated", + "prepublishOnly": "safe-publish-latest", + "prepublish": "not-in-publish || npm run prepublishOnly", + "pretest": "npm run lint", + "test": "npm run tests-only", + "tests-only": "nyc tape 'test/**/*.js'", + "posttest": "npx npm@'>= 10.2' audit --production", + "prelint": "evalmd README.md && eclint check $(git ls-files | xargs find 2> /dev/null | grep -vE 'node_modules|\\.git' | grep -v dist/)", + "lint": "eslint --ext=js,mjs .", + "postlint": "tsc && attw -P", + "version": "auto-changelog && git add CHANGELOG.md", + "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/es-shims/math-intrinsics.git" + }, + "author": "Jordan Harband ", + "license": "MIT", + "bugs": { + "url": "https://github.com/es-shims/math-intrinsics/issues" + }, + "homepage": "https://github.com/es-shims/math-intrinsics#readme", + "devDependencies": { + "@arethetypeswrong/cli": "^0.17.1", + "@ljharb/eslint-config": "^21.1.1", + "@ljharb/tsconfig": "^0.2.2", + "@types/for-each": "^0.3.3", + "@types/object-inspect": "^1.13.0", + "@types/tape": "^5.8.0", + "auto-changelog": "^2.5.0", + "eclint": "^2.8.1", + "es-value-fixtures": "^1.5.0", + "eslint": "^8.8.0", + "evalmd": "^0.0.19", + "for-each": "^0.3.3", + "in-publish": "^2.0.1", + "npmignore": "^0.3.1", + "nyc": "^10.3.2", + "object-inspect": "^1.13.3", + "safe-publish-latest": "^2.0.0", + "tape": "^5.9.0", + "typescript": "next" + }, + "auto-changelog": { + "output": "CHANGELOG.md", + "template": "keepachangelog", + "unreleased": false, + "commitLimit": false, + "backfillLimit": false, + "hideCredit": true + }, + "publishConfig": { + "ignore": [ + ".github/workflows" + ] + }, + "engines": { + "node": ">= 0.4" + } +} diff --git a/node_modules/math-intrinsics/pow.d.ts b/node_modules/math-intrinsics/pow.d.ts new file mode 100644 index 0000000..5873c44 --- /dev/null +++ b/node_modules/math-intrinsics/pow.d.ts @@ -0,0 +1 @@ +export = Math.pow; \ No newline at end of file diff --git a/node_modules/math-intrinsics/pow.js b/node_modules/math-intrinsics/pow.js new file mode 100644 index 0000000..c0a4103 --- /dev/null +++ b/node_modules/math-intrinsics/pow.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./pow')} */ +module.exports = Math.pow; diff --git a/node_modules/math-intrinsics/round.d.ts b/node_modules/math-intrinsics/round.d.ts new file mode 100644 index 0000000..da1fde3 --- /dev/null +++ b/node_modules/math-intrinsics/round.d.ts @@ -0,0 +1 @@ +export = Math.round; \ No newline at end of file diff --git a/node_modules/math-intrinsics/round.js b/node_modules/math-intrinsics/round.js new file mode 100644 index 0000000..b792156 --- /dev/null +++ b/node_modules/math-intrinsics/round.js @@ -0,0 +1,4 @@ +'use strict'; + +/** @type {import('./round')} */ +module.exports = Math.round; diff --git a/node_modules/math-intrinsics/sign.d.ts b/node_modules/math-intrinsics/sign.d.ts new file mode 100644 index 0000000..c49ceca --- /dev/null +++ b/node_modules/math-intrinsics/sign.d.ts @@ -0,0 +1,3 @@ +declare function sign(x: number): number; + +export = sign; \ No newline at end of file diff --git a/node_modules/math-intrinsics/sign.js b/node_modules/math-intrinsics/sign.js new file mode 100644 index 0000000..9e5173c --- /dev/null +++ b/node_modules/math-intrinsics/sign.js @@ -0,0 +1,11 @@ +'use strict'; + +var $isNaN = require('./isNaN'); + +/** @type {import('./sign')} */ +module.exports = function sign(number) { + if ($isNaN(number) || number === 0) { + return number; + } + return number < 0 ? -1 : +1; +}; diff --git a/node_modules/math-intrinsics/test/index.js b/node_modules/math-intrinsics/test/index.js new file mode 100644 index 0000000..0f90a5d --- /dev/null +++ b/node_modules/math-intrinsics/test/index.js @@ -0,0 +1,192 @@ +'use strict'; + +var test = require('tape'); +var v = require('es-value-fixtures'); +var forEach = require('for-each'); +var inspect = require('object-inspect'); + +var abs = require('../abs'); +var floor = require('../floor'); +var isFinite = require('../isFinite'); +var isInteger = require('../isInteger'); +var isNaN = require('../isNaN'); +var isNegativeZero = require('../isNegativeZero'); +var max = require('../max'); +var min = require('../min'); +var mod = require('../mod'); +var pow = require('../pow'); +var round = require('../round'); +var sign = require('../sign'); + +var maxArrayLength = require('../constants/maxArrayLength'); +var maxSafeInteger = require('../constants/maxSafeInteger'); +var maxValue = require('../constants/maxValue'); + +test('abs', function (t) { + t.equal(abs(-1), 1, 'abs(-1) === 1'); + t.equal(abs(+1), 1, 'abs(+1) === 1'); + t.equal(abs(+0), +0, 'abs(+0) === +0'); + t.equal(abs(-0), +0, 'abs(-0) === +0'); + + t.end(); +}); + +test('floor', function (t) { + t.equal(floor(-1.1), -2, 'floor(-1.1) === -2'); + t.equal(floor(+1.1), 1, 'floor(+1.1) === 1'); + t.equal(floor(+0), +0, 'floor(+0) === +0'); + t.equal(floor(-0), -0, 'floor(-0) === -0'); + t.equal(floor(-Infinity), -Infinity, 'floor(-Infinity) === -Infinity'); + t.equal(floor(Number(Infinity)), Number(Infinity), 'floor(+Infinity) === +Infinity'); + t.equal(floor(NaN), NaN, 'floor(NaN) === NaN'); + t.equal(floor(0), +0, 'floor(0) === +0'); + t.equal(floor(-0), -0, 'floor(-0) === -0'); + t.equal(floor(1), 1, 'floor(1) === 1'); + t.equal(floor(-1), -1, 'floor(-1) === -1'); + t.equal(floor(1.1), 1, 'floor(1.1) === 1'); + t.equal(floor(-1.1), -2, 'floor(-1.1) === -2'); + t.equal(floor(maxValue), maxValue, 'floor(maxValue) === maxValue'); + t.equal(floor(maxSafeInteger), maxSafeInteger, 'floor(maxSafeInteger) === maxSafeInteger'); + + t.end(); +}); + +test('isFinite', function (t) { + t.equal(isFinite(0), true, 'isFinite(+0) === true'); + t.equal(isFinite(-0), true, 'isFinite(-0) === true'); + t.equal(isFinite(1), true, 'isFinite(1) === true'); + t.equal(isFinite(Infinity), false, 'isFinite(Infinity) === false'); + t.equal(isFinite(-Infinity), false, 'isFinite(-Infinity) === false'); + t.equal(isFinite(NaN), false, 'isFinite(NaN) === false'); + + forEach(v.nonNumbers, function (nonNumber) { + t.equal(isFinite(nonNumber), false, 'isFinite(' + inspect(nonNumber) + ') === false'); + }); + + t.end(); +}); + +test('isInteger', function (t) { + forEach([].concat( + // @ts-expect-error TS sucks with concat + v.nonNumbers, + v.nonIntegerNumbers + ), function (nonInteger) { + t.equal(isInteger(nonInteger), false, 'isInteger(' + inspect(nonInteger) + ') === false'); + }); + + t.end(); +}); + +test('isNaN', function (t) { + forEach([].concat( + // @ts-expect-error TS sucks with concat + v.nonNumbers, + v.infinities, + v.zeroes, + v.integerNumbers + ), function (nonNaN) { + t.equal(isNaN(nonNaN), false, 'isNaN(' + inspect(nonNaN) + ') === false'); + }); + + t.equal(isNaN(NaN), true, 'isNaN(NaN) === true'); + + t.end(); +}); + +test('isNegativeZero', function (t) { + t.equal(isNegativeZero(-0), true, 'isNegativeZero(-0) === true'); + t.equal(isNegativeZero(+0), false, 'isNegativeZero(+0) === false'); + t.equal(isNegativeZero(1), false, 'isNegativeZero(1) === false'); + t.equal(isNegativeZero(-1), false, 'isNegativeZero(-1) === false'); + t.equal(isNegativeZero(NaN), false, 'isNegativeZero(NaN) === false'); + t.equal(isNegativeZero(Infinity), false, 'isNegativeZero(Infinity) === false'); + t.equal(isNegativeZero(-Infinity), false, 'isNegativeZero(-Infinity) === false'); + + forEach(v.nonNumbers, function (nonNumber) { + t.equal(isNegativeZero(nonNumber), false, 'isNegativeZero(' + inspect(nonNumber) + ') === false'); + }); + + t.end(); +}); + +test('max', function (t) { + t.equal(max(1, 2), 2, 'max(1, 2) === 2'); + t.equal(max(1, 2, 3), 3, 'max(1, 2, 3) === 3'); + t.equal(max(1, 2, 3, 4), 4, 'max(1, 2, 3, 4) === 4'); + t.equal(max(1, 2, 3, 4, 5), 5, 'max(1, 2, 3, 4, 5) === 5'); + t.equal(max(1, 2, 3, 4, 5, 6), 6, 'max(1, 2, 3, 4, 5, 6) === 6'); + t.equal(max(1, 2, 3, 4, 5, 6, 7), 7, 'max(1, 2, 3, 4, 5, 6, 7) === 7'); + + t.end(); +}); + +test('min', function (t) { + t.equal(min(1, 2), 1, 'min(1, 2) === 1'); + t.equal(min(1, 2, 3), 1, 'min(1, 2, 3) === 1'); + t.equal(min(1, 2, 3, 4), 1, 'min(1, 2, 3, 4) === 1'); + t.equal(min(1, 2, 3, 4, 5), 1, 'min(1, 2, 3, 4, 5) === 1'); + t.equal(min(1, 2, 3, 4, 5, 6), 1, 'min(1, 2, 3, 4, 5, 6) === 1'); + + t.end(); +}); + +test('mod', function (t) { + t.equal(mod(1, 2), 1, 'mod(1, 2) === 1'); + t.equal(mod(2, 2), 0, 'mod(2, 2) === 0'); + t.equal(mod(3, 2), 1, 'mod(3, 2) === 1'); + t.equal(mod(4, 2), 0, 'mod(4, 2) === 0'); + t.equal(mod(5, 2), 1, 'mod(5, 2) === 1'); + t.equal(mod(6, 2), 0, 'mod(6, 2) === 0'); + t.equal(mod(7, 2), 1, 'mod(7, 2) === 1'); + t.equal(mod(8, 2), 0, 'mod(8, 2) === 0'); + t.equal(mod(9, 2), 1, 'mod(9, 2) === 1'); + t.equal(mod(10, 2), 0, 'mod(10, 2) === 0'); + t.equal(mod(11, 2), 1, 'mod(11, 2) === 1'); + + t.end(); +}); + +test('pow', function (t) { + t.equal(pow(2, 2), 4, 'pow(2, 2) === 4'); + t.equal(pow(2, 3), 8, 'pow(2, 3) === 8'); + t.equal(pow(2, 4), 16, 'pow(2, 4) === 16'); + t.equal(pow(2, 5), 32, 'pow(2, 5) === 32'); + t.equal(pow(2, 6), 64, 'pow(2, 6) === 64'); + t.equal(pow(2, 7), 128, 'pow(2, 7) === 128'); + t.equal(pow(2, 8), 256, 'pow(2, 8) === 256'); + t.equal(pow(2, 9), 512, 'pow(2, 9) === 512'); + t.equal(pow(2, 10), 1024, 'pow(2, 10) === 1024'); + + t.end(); +}); + +test('round', function (t) { + t.equal(round(1.1), 1, 'round(1.1) === 1'); + t.equal(round(1.5), 2, 'round(1.5) === 2'); + t.equal(round(1.9), 2, 'round(1.9) === 2'); + + t.end(); +}); + +test('sign', function (t) { + t.equal(sign(-1), -1, 'sign(-1) === -1'); + t.equal(sign(+1), +1, 'sign(+1) === +1'); + t.equal(sign(+0), +0, 'sign(+0) === +0'); + t.equal(sign(-0), -0, 'sign(-0) === -0'); + t.equal(sign(NaN), NaN, 'sign(NaN) === NaN'); + t.equal(sign(Infinity), +1, 'sign(Infinity) === +1'); + t.equal(sign(-Infinity), -1, 'sign(-Infinity) === -1'); + t.equal(sign(maxValue), +1, 'sign(maxValue) === +1'); + t.equal(sign(maxSafeInteger), +1, 'sign(maxSafeInteger) === +1'); + + t.end(); +}); + +test('constants', function (t) { + t.equal(typeof maxArrayLength, 'number', 'typeof maxArrayLength === "number"'); + t.equal(typeof maxSafeInteger, 'number', 'typeof maxSafeInteger === "number"'); + t.equal(typeof maxValue, 'number', 'typeof maxValue === "number"'); + + t.end(); +}); diff --git a/node_modules/math-intrinsics/tsconfig.json b/node_modules/math-intrinsics/tsconfig.json new file mode 100644 index 0000000..b131000 --- /dev/null +++ b/node_modules/math-intrinsics/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "@ljharb/tsconfig", +} diff --git a/node_modules/mime-db/HISTORY.md b/node_modules/mime-db/HISTORY.md new file mode 100644 index 0000000..7436f64 --- /dev/null +++ b/node_modules/mime-db/HISTORY.md @@ -0,0 +1,507 @@ +1.52.0 / 2022-02-21 +=================== + + * Add extensions from IANA for more `image/*` types + * Add extension `.asc` to `application/pgp-keys` + * Add extensions to various XML types + * Add new upstream MIME types + +1.51.0 / 2021-11-08 +=================== + + * Add new upstream MIME types + * Mark `image/vnd.microsoft.icon` as compressible + * Mark `image/vnd.ms-dds` as compressible + +1.50.0 / 2021-09-15 +=================== + + * Add deprecated iWorks mime types and extensions + * Add new upstream MIME types + +1.49.0 / 2021-07-26 +=================== + + * Add extension `.trig` to `application/trig` + * Add new upstream MIME types + +1.48.0 / 2021-05-30 +=================== + + * Add extension `.mvt` to `application/vnd.mapbox-vector-tile` + * Add new upstream MIME types + * Mark `text/yaml` as compressible + +1.47.0 / 2021-04-01 +=================== + + * Add new upstream MIME types + * Remove ambigious extensions from IANA for `application/*+xml` types + * Update primary extension to `.es` for `application/ecmascript` + +1.46.0 / 2021-02-13 +=================== + + * Add extension `.amr` to `audio/amr` + * Add extension `.m4s` to `video/iso.segment` + * Add extension `.opus` to `audio/ogg` + * Add new upstream MIME types + +1.45.0 / 2020-09-22 +=================== + + * Add `application/ubjson` with extension `.ubj` + * Add `image/avif` with extension `.avif` + * Add `image/ktx2` with extension `.ktx2` + * Add extension `.dbf` to `application/vnd.dbf` + * Add extension `.rar` to `application/vnd.rar` + * Add extension `.td` to `application/urc-targetdesc+xml` + * Add new upstream MIME types + * Fix extension of `application/vnd.apple.keynote` to be `.key` + +1.44.0 / 2020-04-22 +=================== + + * Add charsets from IANA + * Add extension `.cjs` to `application/node` + * Add new upstream MIME types + +1.43.0 / 2020-01-05 +=================== + + * Add `application/x-keepass2` with extension `.kdbx` + * Add extension `.mxmf` to `audio/mobile-xmf` + * Add extensions from IANA for `application/*+xml` types + * Add new upstream MIME types + +1.42.0 / 2019-09-25 +=================== + + * Add `image/vnd.ms-dds` with extension `.dds` + * Add new upstream MIME types + * Remove compressible from `multipart/mixed` + +1.41.0 / 2019-08-30 +=================== + + * Add new upstream MIME types + * Add `application/toml` with extension `.toml` + * Mark `font/ttf` as compressible + +1.40.0 / 2019-04-20 +=================== + + * Add extensions from IANA for `model/*` types + * Add `text/mdx` with extension `.mdx` + +1.39.0 / 2019-04-04 +=================== + + * Add extensions `.siv` and `.sieve` to `application/sieve` + * Add new upstream MIME types + +1.38.0 / 2019-02-04 +=================== + + * Add extension `.nq` to `application/n-quads` + * Add extension `.nt` to `application/n-triples` + * Add new upstream MIME types + * Mark `text/less` as compressible + +1.37.0 / 2018-10-19 +=================== + + * Add extensions to HEIC image types + * Add new upstream MIME types + +1.36.0 / 2018-08-20 +=================== + + * Add Apple file extensions from IANA + * Add extensions from IANA for `image/*` types + * Add new upstream MIME types + +1.35.0 / 2018-07-15 +=================== + + * Add extension `.owl` to `application/rdf+xml` + * Add new upstream MIME types + - Removes extension `.woff` from `application/font-woff` + +1.34.0 / 2018-06-03 +=================== + + * Add extension `.csl` to `application/vnd.citationstyles.style+xml` + * Add extension `.es` to `application/ecmascript` + * Add new upstream MIME types + * Add `UTF-8` as default charset for `text/turtle` + * Mark all XML-derived types as compressible + +1.33.0 / 2018-02-15 +=================== + + * Add extensions from IANA for `message/*` types + * Add new upstream MIME types + * Fix some incorrect OOXML types + * Remove `application/font-woff2` + +1.32.0 / 2017-11-29 +=================== + + * Add new upstream MIME types + * Update `text/hjson` to registered `application/hjson` + * Add `text/shex` with extension `.shex` + +1.31.0 / 2017-10-25 +=================== + + * Add `application/raml+yaml` with extension `.raml` + * Add `application/wasm` with extension `.wasm` + * Add new `font` type from IANA + * Add new upstream font extensions + * Add new upstream MIME types + * Add extensions for JPEG-2000 images + +1.30.0 / 2017-08-27 +=================== + + * Add `application/vnd.ms-outlook` + * Add `application/x-arj` + * Add extension `.mjs` to `application/javascript` + * Add glTF types and extensions + * Add new upstream MIME types + * Add `text/x-org` + * Add VirtualBox MIME types + * Fix `source` records for `video/*` types that are IANA + * Update `font/opentype` to registered `font/otf` + +1.29.0 / 2017-07-10 +=================== + + * Add `application/fido.trusted-apps+json` + * Add extension `.wadl` to `application/vnd.sun.wadl+xml` + * Add new upstream MIME types + * Add `UTF-8` as default charset for `text/css` + +1.28.0 / 2017-05-14 +=================== + + * Add new upstream MIME types + * Add extension `.gz` to `application/gzip` + * Update extensions `.md` and `.markdown` to be `text/markdown` + +1.27.0 / 2017-03-16 +=================== + + * Add new upstream MIME types + * Add `image/apng` with extension `.apng` + +1.26.0 / 2017-01-14 +=================== + + * Add new upstream MIME types + * Add extension `.geojson` to `application/geo+json` + +1.25.0 / 2016-11-11 +=================== + + * Add new upstream MIME types + +1.24.0 / 2016-09-18 +=================== + + * Add `audio/mp3` + * Add new upstream MIME types + +1.23.0 / 2016-05-01 +=================== + + * Add new upstream MIME types + * Add extension `.3gpp` to `audio/3gpp` + +1.22.0 / 2016-02-15 +=================== + + * Add `text/slim` + * Add extension `.rng` to `application/xml` + * Add new upstream MIME types + * Fix extension of `application/dash+xml` to be `.mpd` + * Update primary extension to `.m4a` for `audio/mp4` + +1.21.0 / 2016-01-06 +=================== + + * Add Google document types + * Add new upstream MIME types + +1.20.0 / 2015-11-10 +=================== + + * Add `text/x-suse-ymp` + * Add new upstream MIME types + +1.19.0 / 2015-09-17 +=================== + + * Add `application/vnd.apple.pkpass` + * Add new upstream MIME types + +1.18.0 / 2015-09-03 +=================== + + * Add new upstream MIME types + +1.17.0 / 2015-08-13 +=================== + + * Add `application/x-msdos-program` + * Add `audio/g711-0` + * Add `image/vnd.mozilla.apng` + * Add extension `.exe` to `application/x-msdos-program` + +1.16.0 / 2015-07-29 +=================== + + * Add `application/vnd.uri-map` + +1.15.0 / 2015-07-13 +=================== + + * Add `application/x-httpd-php` + +1.14.0 / 2015-06-25 +=================== + + * Add `application/scim+json` + * Add `application/vnd.3gpp.ussd+xml` + * Add `application/vnd.biopax.rdf+xml` + * Add `text/x-processing` + +1.13.0 / 2015-06-07 +=================== + + * Add nginx as a source + * Add `application/x-cocoa` + * Add `application/x-java-archive-diff` + * Add `application/x-makeself` + * Add `application/x-perl` + * Add `application/x-pilot` + * Add `application/x-redhat-package-manager` + * Add `application/x-sea` + * Add `audio/x-m4a` + * Add `audio/x-realaudio` + * Add `image/x-jng` + * Add `text/mathml` + +1.12.0 / 2015-06-05 +=================== + + * Add `application/bdoc` + * Add `application/vnd.hyperdrive+json` + * Add `application/x-bdoc` + * Add extension `.rtf` to `text/rtf` + +1.11.0 / 2015-05-31 +=================== + + * Add `audio/wav` + * Add `audio/wave` + * Add extension `.litcoffee` to `text/coffeescript` + * Add extension `.sfd-hdstx` to `application/vnd.hydrostatix.sof-data` + * Add extension `.n-gage` to `application/vnd.nokia.n-gage.symbian.install` + +1.10.0 / 2015-05-19 +=================== + + * Add `application/vnd.balsamiq.bmpr` + * Add `application/vnd.microsoft.portable-executable` + * Add `application/x-ns-proxy-autoconfig` + +1.9.1 / 2015-04-19 +================== + + * Remove `.json` extension from `application/manifest+json` + - This is causing bugs downstream + +1.9.0 / 2015-04-19 +================== + + * Add `application/manifest+json` + * Add `application/vnd.micro+json` + * Add `image/vnd.zbrush.pcx` + * Add `image/x-ms-bmp` + +1.8.0 / 2015-03-13 +================== + + * Add `application/vnd.citationstyles.style+xml` + * Add `application/vnd.fastcopy-disk-image` + * Add `application/vnd.gov.sk.xmldatacontainer+xml` + * Add extension `.jsonld` to `application/ld+json` + +1.7.0 / 2015-02-08 +================== + + * Add `application/vnd.gerber` + * Add `application/vnd.msa-disk-image` + +1.6.1 / 2015-02-05 +================== + + * Community extensions ownership transferred from `node-mime` + +1.6.0 / 2015-01-29 +================== + + * Add `application/jose` + * Add `application/jose+json` + * Add `application/json-seq` + * Add `application/jwk+json` + * Add `application/jwk-set+json` + * Add `application/jwt` + * Add `application/rdap+json` + * Add `application/vnd.gov.sk.e-form+xml` + * Add `application/vnd.ims.imsccv1p3` + +1.5.0 / 2014-12-30 +================== + + * Add `application/vnd.oracle.resource+json` + * Fix various invalid MIME type entries + - `application/mbox+xml` + - `application/oscp-response` + - `application/vwg-multiplexed` + - `audio/g721` + +1.4.0 / 2014-12-21 +================== + + * Add `application/vnd.ims.imsccv1p2` + * Fix various invalid MIME type entries + - `application/vnd-acucobol` + - `application/vnd-curl` + - `application/vnd-dart` + - `application/vnd-dxr` + - `application/vnd-fdf` + - `application/vnd-mif` + - `application/vnd-sema` + - `application/vnd-wap-wmlc` + - `application/vnd.adobe.flash-movie` + - `application/vnd.dece-zip` + - `application/vnd.dvb_service` + - `application/vnd.micrografx-igx` + - `application/vnd.sealed-doc` + - `application/vnd.sealed-eml` + - `application/vnd.sealed-mht` + - `application/vnd.sealed-ppt` + - `application/vnd.sealed-tiff` + - `application/vnd.sealed-xls` + - `application/vnd.sealedmedia.softseal-html` + - `application/vnd.sealedmedia.softseal-pdf` + - `application/vnd.wap-slc` + - `application/vnd.wap-wbxml` + - `audio/vnd.sealedmedia.softseal-mpeg` + - `image/vnd-djvu` + - `image/vnd-svf` + - `image/vnd-wap-wbmp` + - `image/vnd.sealed-png` + - `image/vnd.sealedmedia.softseal-gif` + - `image/vnd.sealedmedia.softseal-jpg` + - `model/vnd-dwf` + - `model/vnd.parasolid.transmit-binary` + - `model/vnd.parasolid.transmit-text` + - `text/vnd-a` + - `text/vnd-curl` + - `text/vnd.wap-wml` + * Remove example template MIME types + - `application/example` + - `audio/example` + - `image/example` + - `message/example` + - `model/example` + - `multipart/example` + - `text/example` + - `video/example` + +1.3.1 / 2014-12-16 +================== + + * Fix missing extensions + - `application/json5` + - `text/hjson` + +1.3.0 / 2014-12-07 +================== + + * Add `application/a2l` + * Add `application/aml` + * Add `application/atfx` + * Add `application/atxml` + * Add `application/cdfx+xml` + * Add `application/dii` + * Add `application/json5` + * Add `application/lxf` + * Add `application/mf4` + * Add `application/vnd.apache.thrift.compact` + * Add `application/vnd.apache.thrift.json` + * Add `application/vnd.coffeescript` + * Add `application/vnd.enphase.envoy` + * Add `application/vnd.ims.imsccv1p1` + * Add `text/csv-schema` + * Add `text/hjson` + * Add `text/markdown` + * Add `text/yaml` + +1.2.0 / 2014-11-09 +================== + + * Add `application/cea` + * Add `application/dit` + * Add `application/vnd.gov.sk.e-form+zip` + * Add `application/vnd.tmd.mediaflex.api+xml` + * Type `application/epub+zip` is now IANA-registered + +1.1.2 / 2014-10-23 +================== + + * Rebuild database for `application/x-www-form-urlencoded` change + +1.1.1 / 2014-10-20 +================== + + * Mark `application/x-www-form-urlencoded` as compressible. + +1.1.0 / 2014-09-28 +================== + + * Add `application/font-woff2` + +1.0.3 / 2014-09-25 +================== + + * Fix engine requirement in package + +1.0.2 / 2014-09-25 +================== + + * Add `application/coap-group+json` + * Add `application/dcd` + * Add `application/vnd.apache.thrift.binary` + * Add `image/vnd.tencent.tap` + * Mark all JSON-derived types as compressible + * Update `text/vtt` data + +1.0.1 / 2014-08-30 +================== + + * Fix extension ordering + +1.0.0 / 2014-08-30 +================== + + * Add `application/atf` + * Add `application/merge-patch+json` + * Add `multipart/x-mixed-replace` + * Add `source: 'apache'` metadata + * Add `source: 'iana'` metadata + * Remove badly-assumed charset data diff --git a/node_modules/mime-db/LICENSE b/node_modules/mime-db/LICENSE new file mode 100644 index 0000000..0751cb1 --- /dev/null +++ b/node_modules/mime-db/LICENSE @@ -0,0 +1,23 @@ +(The MIT License) + +Copyright (c) 2014 Jonathan Ong +Copyright (c) 2015-2022 Douglas Christopher Wilson + +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. diff --git a/node_modules/mime-db/README.md b/node_modules/mime-db/README.md new file mode 100644 index 0000000..5a8fcfe --- /dev/null +++ b/node_modules/mime-db/README.md @@ -0,0 +1,100 @@ +# mime-db + +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][npm-url] +[![Node.js Version][node-image]][node-url] +[![Build Status][ci-image]][ci-url] +[![Coverage Status][coveralls-image]][coveralls-url] + +This is a large database of mime types and information about them. +It consists of a single, public JSON file and does not include any logic, +allowing it to remain as un-opinionated as possible with an API. +It aggregates data from the following sources: + +- http://www.iana.org/assignments/media-types/media-types.xhtml +- http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types +- http://hg.nginx.org/nginx/raw-file/default/conf/mime.types + +## Installation + +```bash +npm install mime-db +``` + +### Database Download + +If you're crazy enough to use this in the browser, you can just grab the +JSON file using [jsDelivr](https://www.jsdelivr.com/). It is recommended to +replace `master` with [a release tag](https://github.com/jshttp/mime-db/tags) +as the JSON format may change in the future. + +``` +https://cdn.jsdelivr.net/gh/jshttp/mime-db@master/db.json +``` + +## Usage + +```js +var db = require('mime-db') + +// grab data on .js files +var data = db['application/javascript'] +``` + +## Data Structure + +The JSON file is a map lookup for lowercased mime types. +Each mime type has the following properties: + +- `.source` - where the mime type is defined. + If not set, it's probably a custom media type. + - `apache` - [Apache common media types](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types) + - `iana` - [IANA-defined media types](http://www.iana.org/assignments/media-types/media-types.xhtml) + - `nginx` - [nginx media types](http://hg.nginx.org/nginx/raw-file/default/conf/mime.types) +- `.extensions[]` - known extensions associated with this mime type. +- `.compressible` - whether a file of this type can be gzipped. +- `.charset` - the default charset associated with this type, if any. + +If unknown, every property could be `undefined`. + +## Contributing + +To edit the database, only make PRs against `src/custom-types.json` or +`src/custom-suffix.json`. + +The `src/custom-types.json` file is a JSON object with the MIME type as the +keys and the values being an object with the following keys: + +- `compressible` - leave out if you don't know, otherwise `true`/`false` to + indicate whether the data represented by the type is typically compressible. +- `extensions` - include an array of file extensions that are associated with + the type. +- `notes` - human-readable notes about the type, typically what the type is. +- `sources` - include an array of URLs of where the MIME type and the associated + extensions are sourced from. This needs to be a [primary source](https://en.wikipedia.org/wiki/Primary_source); + links to type aggregating sites and Wikipedia are _not acceptable_. + +To update the build, run `npm run build`. + +### Adding Custom Media Types + +The best way to get new media types included in this library is to register +them with the IANA. The community registration procedure is outlined in +[RFC 6838 section 5](http://tools.ietf.org/html/rfc6838#section-5). Types +registered with the IANA are automatically pulled into this library. + +If that is not possible / feasible, they can be added directly here as a +"custom" type. To do this, it is required to have a primary source that +definitively lists the media type. If an extension is going to be listed as +associateed with this media type, the source must definitively link the +media type and extension as well. + +[ci-image]: https://badgen.net/github/checks/jshttp/mime-db/master?label=ci +[ci-url]: https://github.com/jshttp/mime-db/actions?query=workflow%3Aci +[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/mime-db/master +[coveralls-url]: https://coveralls.io/r/jshttp/mime-db?branch=master +[node-image]: https://badgen.net/npm/node/mime-db +[node-url]: https://nodejs.org/en/download +[npm-downloads-image]: https://badgen.net/npm/dm/mime-db +[npm-url]: https://npmjs.org/package/mime-db +[npm-version-image]: https://badgen.net/npm/v/mime-db diff --git a/node_modules/mime-db/db.json b/node_modules/mime-db/db.json new file mode 100644 index 0000000..eb9c42c --- /dev/null +++ b/node_modules/mime-db/db.json @@ -0,0 +1,8519 @@ +{ + "application/1d-interleaved-parityfec": { + "source": "iana" + }, + "application/3gpdash-qoe-report+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/3gpp-ims+xml": { + "source": "iana", + "compressible": true + }, + "application/3gpphal+json": { + "source": "iana", + "compressible": true + }, + "application/3gpphalforms+json": { + "source": "iana", + "compressible": true + }, + "application/a2l": { + "source": "iana" + }, + "application/ace+cbor": { + "source": "iana" + }, + "application/activemessage": { + "source": "iana" + }, + "application/activity+json": { + "source": "iana", + "compressible": true + }, + "application/alto-costmap+json": { + "source": "iana", + "compressible": true + }, + "application/alto-costmapfilter+json": { + "source": "iana", + "compressible": true + }, + "application/alto-directory+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointcost+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointcostparams+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointprop+json": { + "source": "iana", + "compressible": true + }, + "application/alto-endpointpropparams+json": { + "source": "iana", + "compressible": true + }, + "application/alto-error+json": { + "source": "iana", + "compressible": true + }, + "application/alto-networkmap+json": { + "source": "iana", + "compressible": true + }, + "application/alto-networkmapfilter+json": { + "source": "iana", + "compressible": true + }, + "application/alto-updatestreamcontrol+json": { + "source": "iana", + "compressible": true + }, + "application/alto-updatestreamparams+json": { + "source": "iana", + "compressible": true + }, + "application/aml": { + "source": "iana" + }, + "application/andrew-inset": { + "source": "iana", + "extensions": ["ez"] + }, + "application/applefile": { + "source": "iana" + }, + "application/applixware": { + "source": "apache", + "extensions": ["aw"] + }, + "application/at+jwt": { + "source": "iana" + }, + "application/atf": { + "source": "iana" + }, + "application/atfx": { + "source": "iana" + }, + "application/atom+xml": { + "source": "iana", + "compressible": true, + "extensions": ["atom"] + }, + "application/atomcat+xml": { + "source": "iana", + "compressible": true, + "extensions": ["atomcat"] + }, + "application/atomdeleted+xml": { + "source": "iana", + "compressible": true, + "extensions": ["atomdeleted"] + }, + "application/atomicmail": { + "source": "iana" + }, + "application/atomsvc+xml": { + "source": "iana", + "compressible": true, + "extensions": ["atomsvc"] + }, + "application/atsc-dwd+xml": { + "source": "iana", + "compressible": true, + "extensions": ["dwd"] + }, + "application/atsc-dynamic-event-message": { + "source": "iana" + }, + "application/atsc-held+xml": { + "source": "iana", + "compressible": true, + "extensions": ["held"] + }, + "application/atsc-rdt+json": { + "source": "iana", + "compressible": true + }, + "application/atsc-rsat+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rsat"] + }, + "application/atxml": { + "source": "iana" + }, + "application/auth-policy+xml": { + "source": "iana", + "compressible": true + }, + "application/bacnet-xdd+zip": { + "source": "iana", + "compressible": false + }, + "application/batch-smtp": { + "source": "iana" + }, + "application/bdoc": { + "compressible": false, + "extensions": ["bdoc"] + }, + "application/beep+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/calendar+json": { + "source": "iana", + "compressible": true + }, + "application/calendar+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xcs"] + }, + "application/call-completion": { + "source": "iana" + }, + "application/cals-1840": { + "source": "iana" + }, + "application/captive+json": { + "source": "iana", + "compressible": true + }, + "application/cbor": { + "source": "iana" + }, + "application/cbor-seq": { + "source": "iana" + }, + "application/cccex": { + "source": "iana" + }, + "application/ccmp+xml": { + "source": "iana", + "compressible": true + }, + "application/ccxml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["ccxml"] + }, + "application/cdfx+xml": { + "source": "iana", + "compressible": true, + "extensions": ["cdfx"] + }, + "application/cdmi-capability": { + "source": "iana", + "extensions": ["cdmia"] + }, + "application/cdmi-container": { + "source": "iana", + "extensions": ["cdmic"] + }, + "application/cdmi-domain": { + "source": "iana", + "extensions": ["cdmid"] + }, + "application/cdmi-object": { + "source": "iana", + "extensions": ["cdmio"] + }, + "application/cdmi-queue": { + "source": "iana", + "extensions": ["cdmiq"] + }, + "application/cdni": { + "source": "iana" + }, + "application/cea": { + "source": "iana" + }, + "application/cea-2018+xml": { + "source": "iana", + "compressible": true + }, + "application/cellml+xml": { + "source": "iana", + "compressible": true + }, + "application/cfw": { + "source": "iana" + }, + "application/city+json": { + "source": "iana", + "compressible": true + }, + "application/clr": { + "source": "iana" + }, + "application/clue+xml": { + "source": "iana", + "compressible": true + }, + "application/clue_info+xml": { + "source": "iana", + "compressible": true + }, + "application/cms": { + "source": "iana" + }, + "application/cnrp+xml": { + "source": "iana", + "compressible": true + }, + "application/coap-group+json": { + "source": "iana", + "compressible": true + }, + "application/coap-payload": { + "source": "iana" + }, + "application/commonground": { + "source": "iana" + }, + "application/conference-info+xml": { + "source": "iana", + "compressible": true + }, + "application/cose": { + "source": "iana" + }, + "application/cose-key": { + "source": "iana" + }, + "application/cose-key-set": { + "source": "iana" + }, + "application/cpl+xml": { + "source": "iana", + "compressible": true, + "extensions": ["cpl"] + }, + "application/csrattrs": { + "source": "iana" + }, + "application/csta+xml": { + "source": "iana", + "compressible": true + }, + "application/cstadata+xml": { + "source": "iana", + "compressible": true + }, + "application/csvm+json": { + "source": "iana", + "compressible": true + }, + "application/cu-seeme": { + "source": "apache", + "extensions": ["cu"] + }, + "application/cwt": { + "source": "iana" + }, + "application/cybercash": { + "source": "iana" + }, + "application/dart": { + "compressible": true + }, + "application/dash+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mpd"] + }, + "application/dash-patch+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mpp"] + }, + "application/dashdelta": { + "source": "iana" + }, + "application/davmount+xml": { + "source": "iana", + "compressible": true, + "extensions": ["davmount"] + }, + "application/dca-rft": { + "source": "iana" + }, + "application/dcd": { + "source": "iana" + }, + "application/dec-dx": { + "source": "iana" + }, + "application/dialog-info+xml": { + "source": "iana", + "compressible": true + }, + "application/dicom": { + "source": "iana" + }, + "application/dicom+json": { + "source": "iana", + "compressible": true + }, + "application/dicom+xml": { + "source": "iana", + "compressible": true + }, + "application/dii": { + "source": "iana" + }, + "application/dit": { + "source": "iana" + }, + "application/dns": { + "source": "iana" + }, + "application/dns+json": { + "source": "iana", + "compressible": true + }, + "application/dns-message": { + "source": "iana" + }, + "application/docbook+xml": { + "source": "apache", + "compressible": true, + "extensions": ["dbk"] + }, + "application/dots+cbor": { + "source": "iana" + }, + "application/dskpp+xml": { + "source": "iana", + "compressible": true + }, + "application/dssc+der": { + "source": "iana", + "extensions": ["dssc"] + }, + "application/dssc+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xdssc"] + }, + "application/dvcs": { + "source": "iana" + }, + "application/ecmascript": { + "source": "iana", + "compressible": true, + "extensions": ["es","ecma"] + }, + "application/edi-consent": { + "source": "iana" + }, + "application/edi-x12": { + "source": "iana", + "compressible": false + }, + "application/edifact": { + "source": "iana", + "compressible": false + }, + "application/efi": { + "source": "iana" + }, + "application/elm+json": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/elm+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.cap+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/emergencycalldata.comment+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.control+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.deviceinfo+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.ecall.msd": { + "source": "iana" + }, + "application/emergencycalldata.providerinfo+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.serviceinfo+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.subscriberinfo+xml": { + "source": "iana", + "compressible": true + }, + "application/emergencycalldata.veds+xml": { + "source": "iana", + "compressible": true + }, + "application/emma+xml": { + "source": "iana", + "compressible": true, + "extensions": ["emma"] + }, + "application/emotionml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["emotionml"] + }, + "application/encaprtp": { + "source": "iana" + }, + "application/epp+xml": { + "source": "iana", + "compressible": true + }, + "application/epub+zip": { + "source": "iana", + "compressible": false, + "extensions": ["epub"] + }, + "application/eshop": { + "source": "iana" + }, + "application/exi": { + "source": "iana", + "extensions": ["exi"] + }, + "application/expect-ct-report+json": { + "source": "iana", + "compressible": true + }, + "application/express": { + "source": "iana", + "extensions": ["exp"] + }, + "application/fastinfoset": { + "source": "iana" + }, + "application/fastsoap": { + "source": "iana" + }, + "application/fdt+xml": { + "source": "iana", + "compressible": true, + "extensions": ["fdt"] + }, + "application/fhir+json": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/fhir+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/fido.trusted-apps+json": { + "compressible": true + }, + "application/fits": { + "source": "iana" + }, + "application/flexfec": { + "source": "iana" + }, + "application/font-sfnt": { + "source": "iana" + }, + "application/font-tdpfr": { + "source": "iana", + "extensions": ["pfr"] + }, + "application/font-woff": { + "source": "iana", + "compressible": false + }, + "application/framework-attributes+xml": { + "source": "iana", + "compressible": true + }, + "application/geo+json": { + "source": "iana", + "compressible": true, + "extensions": ["geojson"] + }, + "application/geo+json-seq": { + "source": "iana" + }, + "application/geopackage+sqlite3": { + "source": "iana" + }, + "application/geoxacml+xml": { + "source": "iana", + "compressible": true + }, + "application/gltf-buffer": { + "source": "iana" + }, + "application/gml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["gml"] + }, + "application/gpx+xml": { + "source": "apache", + "compressible": true, + "extensions": ["gpx"] + }, + "application/gxf": { + "source": "apache", + "extensions": ["gxf"] + }, + "application/gzip": { + "source": "iana", + "compressible": false, + "extensions": ["gz"] + }, + "application/h224": { + "source": "iana" + }, + "application/held+xml": { + "source": "iana", + "compressible": true + }, + "application/hjson": { + "extensions": ["hjson"] + }, + "application/http": { + "source": "iana" + }, + "application/hyperstudio": { + "source": "iana", + "extensions": ["stk"] + }, + "application/ibe-key-request+xml": { + "source": "iana", + "compressible": true + }, + "application/ibe-pkg-reply+xml": { + "source": "iana", + "compressible": true + }, + "application/ibe-pp-data": { + "source": "iana" + }, + "application/iges": { + "source": "iana" + }, + "application/im-iscomposing+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/index": { + "source": "iana" + }, + "application/index.cmd": { + "source": "iana" + }, + "application/index.obj": { + "source": "iana" + }, + "application/index.response": { + "source": "iana" + }, + "application/index.vnd": { + "source": "iana" + }, + "application/inkml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["ink","inkml"] + }, + "application/iotp": { + "source": "iana" + }, + "application/ipfix": { + "source": "iana", + "extensions": ["ipfix"] + }, + "application/ipp": { + "source": "iana" + }, + "application/isup": { + "source": "iana" + }, + "application/its+xml": { + "source": "iana", + "compressible": true, + "extensions": ["its"] + }, + "application/java-archive": { + "source": "apache", + "compressible": false, + "extensions": ["jar","war","ear"] + }, + "application/java-serialized-object": { + "source": "apache", + "compressible": false, + "extensions": ["ser"] + }, + "application/java-vm": { + "source": "apache", + "compressible": false, + "extensions": ["class"] + }, + "application/javascript": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["js","mjs"] + }, + "application/jf2feed+json": { + "source": "iana", + "compressible": true + }, + "application/jose": { + "source": "iana" + }, + "application/jose+json": { + "source": "iana", + "compressible": true + }, + "application/jrd+json": { + "source": "iana", + "compressible": true + }, + "application/jscalendar+json": { + "source": "iana", + "compressible": true + }, + "application/json": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["json","map"] + }, + "application/json-patch+json": { + "source": "iana", + "compressible": true + }, + "application/json-seq": { + "source": "iana" + }, + "application/json5": { + "extensions": ["json5"] + }, + "application/jsonml+json": { + "source": "apache", + "compressible": true, + "extensions": ["jsonml"] + }, + "application/jwk+json": { + "source": "iana", + "compressible": true + }, + "application/jwk-set+json": { + "source": "iana", + "compressible": true + }, + "application/jwt": { + "source": "iana" + }, + "application/kpml-request+xml": { + "source": "iana", + "compressible": true + }, + "application/kpml-response+xml": { + "source": "iana", + "compressible": true + }, + "application/ld+json": { + "source": "iana", + "compressible": true, + "extensions": ["jsonld"] + }, + "application/lgr+xml": { + "source": "iana", + "compressible": true, + "extensions": ["lgr"] + }, + "application/link-format": { + "source": "iana" + }, + "application/load-control+xml": { + "source": "iana", + "compressible": true + }, + "application/lost+xml": { + "source": "iana", + "compressible": true, + "extensions": ["lostxml"] + }, + "application/lostsync+xml": { + "source": "iana", + "compressible": true + }, + "application/lpf+zip": { + "source": "iana", + "compressible": false + }, + "application/lxf": { + "source": "iana" + }, + "application/mac-binhex40": { + "source": "iana", + "extensions": ["hqx"] + }, + "application/mac-compactpro": { + "source": "apache", + "extensions": ["cpt"] + }, + "application/macwriteii": { + "source": "iana" + }, + "application/mads+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mads"] + }, + "application/manifest+json": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["webmanifest"] + }, + "application/marc": { + "source": "iana", + "extensions": ["mrc"] + }, + "application/marcxml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mrcx"] + }, + "application/mathematica": { + "source": "iana", + "extensions": ["ma","nb","mb"] + }, + "application/mathml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mathml"] + }, + "application/mathml-content+xml": { + "source": "iana", + "compressible": true + }, + "application/mathml-presentation+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-associated-procedure-description+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-deregister+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-envelope+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-msk+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-msk-response+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-protection-description+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-reception-report+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-register+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-register-response+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-schedule+xml": { + "source": "iana", + "compressible": true + }, + "application/mbms-user-service-description+xml": { + "source": "iana", + "compressible": true + }, + "application/mbox": { + "source": "iana", + "extensions": ["mbox"] + }, + "application/media-policy-dataset+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mpf"] + }, + "application/media_control+xml": { + "source": "iana", + "compressible": true + }, + "application/mediaservercontrol+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mscml"] + }, + "application/merge-patch+json": { + "source": "iana", + "compressible": true + }, + "application/metalink+xml": { + "source": "apache", + "compressible": true, + "extensions": ["metalink"] + }, + "application/metalink4+xml": { + "source": "iana", + "compressible": true, + "extensions": ["meta4"] + }, + "application/mets+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mets"] + }, + "application/mf4": { + "source": "iana" + }, + "application/mikey": { + "source": "iana" + }, + "application/mipc": { + "source": "iana" + }, + "application/missing-blocks+cbor-seq": { + "source": "iana" + }, + "application/mmt-aei+xml": { + "source": "iana", + "compressible": true, + "extensions": ["maei"] + }, + "application/mmt-usd+xml": { + "source": "iana", + "compressible": true, + "extensions": ["musd"] + }, + "application/mods+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mods"] + }, + "application/moss-keys": { + "source": "iana" + }, + "application/moss-signature": { + "source": "iana" + }, + "application/mosskey-data": { + "source": "iana" + }, + "application/mosskey-request": { + "source": "iana" + }, + "application/mp21": { + "source": "iana", + "extensions": ["m21","mp21"] + }, + "application/mp4": { + "source": "iana", + "extensions": ["mp4s","m4p"] + }, + "application/mpeg4-generic": { + "source": "iana" + }, + "application/mpeg4-iod": { + "source": "iana" + }, + "application/mpeg4-iod-xmt": { + "source": "iana" + }, + "application/mrb-consumer+xml": { + "source": "iana", + "compressible": true + }, + "application/mrb-publish+xml": { + "source": "iana", + "compressible": true + }, + "application/msc-ivr+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/msc-mixer+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/msword": { + "source": "iana", + "compressible": false, + "extensions": ["doc","dot"] + }, + "application/mud+json": { + "source": "iana", + "compressible": true + }, + "application/multipart-core": { + "source": "iana" + }, + "application/mxf": { + "source": "iana", + "extensions": ["mxf"] + }, + "application/n-quads": { + "source": "iana", + "extensions": ["nq"] + }, + "application/n-triples": { + "source": "iana", + "extensions": ["nt"] + }, + "application/nasdata": { + "source": "iana" + }, + "application/news-checkgroups": { + "source": "iana", + "charset": "US-ASCII" + }, + "application/news-groupinfo": { + "source": "iana", + "charset": "US-ASCII" + }, + "application/news-transmission": { + "source": "iana" + }, + "application/nlsml+xml": { + "source": "iana", + "compressible": true + }, + "application/node": { + "source": "iana", + "extensions": ["cjs"] + }, + "application/nss": { + "source": "iana" + }, + "application/oauth-authz-req+jwt": { + "source": "iana" + }, + "application/oblivious-dns-message": { + "source": "iana" + }, + "application/ocsp-request": { + "source": "iana" + }, + "application/ocsp-response": { + "source": "iana" + }, + "application/octet-stream": { + "source": "iana", + "compressible": false, + "extensions": ["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"] + }, + "application/oda": { + "source": "iana", + "extensions": ["oda"] + }, + "application/odm+xml": { + "source": "iana", + "compressible": true + }, + "application/odx": { + "source": "iana" + }, + "application/oebps-package+xml": { + "source": "iana", + "compressible": true, + "extensions": ["opf"] + }, + "application/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["ogx"] + }, + "application/omdoc+xml": { + "source": "apache", + "compressible": true, + "extensions": ["omdoc"] + }, + "application/onenote": { + "source": "apache", + "extensions": ["onetoc","onetoc2","onetmp","onepkg"] + }, + "application/opc-nodeset+xml": { + "source": "iana", + "compressible": true + }, + "application/oscore": { + "source": "iana" + }, + "application/oxps": { + "source": "iana", + "extensions": ["oxps"] + }, + "application/p21": { + "source": "iana" + }, + "application/p21+zip": { + "source": "iana", + "compressible": false + }, + "application/p2p-overlay+xml": { + "source": "iana", + "compressible": true, + "extensions": ["relo"] + }, + "application/parityfec": { + "source": "iana" + }, + "application/passport": { + "source": "iana" + }, + "application/patch-ops-error+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xer"] + }, + "application/pdf": { + "source": "iana", + "compressible": false, + "extensions": ["pdf"] + }, + "application/pdx": { + "source": "iana" + }, + "application/pem-certificate-chain": { + "source": "iana" + }, + "application/pgp-encrypted": { + "source": "iana", + "compressible": false, + "extensions": ["pgp"] + }, + "application/pgp-keys": { + "source": "iana", + "extensions": ["asc"] + }, + "application/pgp-signature": { + "source": "iana", + "extensions": ["asc","sig"] + }, + "application/pics-rules": { + "source": "apache", + "extensions": ["prf"] + }, + "application/pidf+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/pidf-diff+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/pkcs10": { + "source": "iana", + "extensions": ["p10"] + }, + "application/pkcs12": { + "source": "iana" + }, + "application/pkcs7-mime": { + "source": "iana", + "extensions": ["p7m","p7c"] + }, + "application/pkcs7-signature": { + "source": "iana", + "extensions": ["p7s"] + }, + "application/pkcs8": { + "source": "iana", + "extensions": ["p8"] + }, + "application/pkcs8-encrypted": { + "source": "iana" + }, + "application/pkix-attr-cert": { + "source": "iana", + "extensions": ["ac"] + }, + "application/pkix-cert": { + "source": "iana", + "extensions": ["cer"] + }, + "application/pkix-crl": { + "source": "iana", + "extensions": ["crl"] + }, + "application/pkix-pkipath": { + "source": "iana", + "extensions": ["pkipath"] + }, + "application/pkixcmp": { + "source": "iana", + "extensions": ["pki"] + }, + "application/pls+xml": { + "source": "iana", + "compressible": true, + "extensions": ["pls"] + }, + "application/poc-settings+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/postscript": { + "source": "iana", + "compressible": true, + "extensions": ["ai","eps","ps"] + }, + "application/ppsp-tracker+json": { + "source": "iana", + "compressible": true + }, + "application/problem+json": { + "source": "iana", + "compressible": true + }, + "application/problem+xml": { + "source": "iana", + "compressible": true + }, + "application/provenance+xml": { + "source": "iana", + "compressible": true, + "extensions": ["provx"] + }, + "application/prs.alvestrand.titrax-sheet": { + "source": "iana" + }, + "application/prs.cww": { + "source": "iana", + "extensions": ["cww"] + }, + "application/prs.cyn": { + "source": "iana", + "charset": "7-BIT" + }, + "application/prs.hpub+zip": { + "source": "iana", + "compressible": false + }, + "application/prs.nprend": { + "source": "iana" + }, + "application/prs.plucker": { + "source": "iana" + }, + "application/prs.rdf-xml-crypt": { + "source": "iana" + }, + "application/prs.xsf+xml": { + "source": "iana", + "compressible": true + }, + "application/pskc+xml": { + "source": "iana", + "compressible": true, + "extensions": ["pskcxml"] + }, + "application/pvd+json": { + "source": "iana", + "compressible": true + }, + "application/qsig": { + "source": "iana" + }, + "application/raml+yaml": { + "compressible": true, + "extensions": ["raml"] + }, + "application/raptorfec": { + "source": "iana" + }, + "application/rdap+json": { + "source": "iana", + "compressible": true + }, + "application/rdf+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rdf","owl"] + }, + "application/reginfo+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rif"] + }, + "application/relax-ng-compact-syntax": { + "source": "iana", + "extensions": ["rnc"] + }, + "application/remote-printing": { + "source": "iana" + }, + "application/reputon+json": { + "source": "iana", + "compressible": true + }, + "application/resource-lists+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rl"] + }, + "application/resource-lists-diff+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rld"] + }, + "application/rfc+xml": { + "source": "iana", + "compressible": true + }, + "application/riscos": { + "source": "iana" + }, + "application/rlmi+xml": { + "source": "iana", + "compressible": true + }, + "application/rls-services+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rs"] + }, + "application/route-apd+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rapd"] + }, + "application/route-s-tsid+xml": { + "source": "iana", + "compressible": true, + "extensions": ["sls"] + }, + "application/route-usd+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rusd"] + }, + "application/rpki-ghostbusters": { + "source": "iana", + "extensions": ["gbr"] + }, + "application/rpki-manifest": { + "source": "iana", + "extensions": ["mft"] + }, + "application/rpki-publication": { + "source": "iana" + }, + "application/rpki-roa": { + "source": "iana", + "extensions": ["roa"] + }, + "application/rpki-updown": { + "source": "iana" + }, + "application/rsd+xml": { + "source": "apache", + "compressible": true, + "extensions": ["rsd"] + }, + "application/rss+xml": { + "source": "apache", + "compressible": true, + "extensions": ["rss"] + }, + "application/rtf": { + "source": "iana", + "compressible": true, + "extensions": ["rtf"] + }, + "application/rtploopback": { + "source": "iana" + }, + "application/rtx": { + "source": "iana" + }, + "application/samlassertion+xml": { + "source": "iana", + "compressible": true + }, + "application/samlmetadata+xml": { + "source": "iana", + "compressible": true + }, + "application/sarif+json": { + "source": "iana", + "compressible": true + }, + "application/sarif-external-properties+json": { + "source": "iana", + "compressible": true + }, + "application/sbe": { + "source": "iana" + }, + "application/sbml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["sbml"] + }, + "application/scaip+xml": { + "source": "iana", + "compressible": true + }, + "application/scim+json": { + "source": "iana", + "compressible": true + }, + "application/scvp-cv-request": { + "source": "iana", + "extensions": ["scq"] + }, + "application/scvp-cv-response": { + "source": "iana", + "extensions": ["scs"] + }, + "application/scvp-vp-request": { + "source": "iana", + "extensions": ["spq"] + }, + "application/scvp-vp-response": { + "source": "iana", + "extensions": ["spp"] + }, + "application/sdp": { + "source": "iana", + "extensions": ["sdp"] + }, + "application/secevent+jwt": { + "source": "iana" + }, + "application/senml+cbor": { + "source": "iana" + }, + "application/senml+json": { + "source": "iana", + "compressible": true + }, + "application/senml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["senmlx"] + }, + "application/senml-etch+cbor": { + "source": "iana" + }, + "application/senml-etch+json": { + "source": "iana", + "compressible": true + }, + "application/senml-exi": { + "source": "iana" + }, + "application/sensml+cbor": { + "source": "iana" + }, + "application/sensml+json": { + "source": "iana", + "compressible": true + }, + "application/sensml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["sensmlx"] + }, + "application/sensml-exi": { + "source": "iana" + }, + "application/sep+xml": { + "source": "iana", + "compressible": true + }, + "application/sep-exi": { + "source": "iana" + }, + "application/session-info": { + "source": "iana" + }, + "application/set-payment": { + "source": "iana" + }, + "application/set-payment-initiation": { + "source": "iana", + "extensions": ["setpay"] + }, + "application/set-registration": { + "source": "iana" + }, + "application/set-registration-initiation": { + "source": "iana", + "extensions": ["setreg"] + }, + "application/sgml": { + "source": "iana" + }, + "application/sgml-open-catalog": { + "source": "iana" + }, + "application/shf+xml": { + "source": "iana", + "compressible": true, + "extensions": ["shf"] + }, + "application/sieve": { + "source": "iana", + "extensions": ["siv","sieve"] + }, + "application/simple-filter+xml": { + "source": "iana", + "compressible": true + }, + "application/simple-message-summary": { + "source": "iana" + }, + "application/simplesymbolcontainer": { + "source": "iana" + }, + "application/sipc": { + "source": "iana" + }, + "application/slate": { + "source": "iana" + }, + "application/smil": { + "source": "iana" + }, + "application/smil+xml": { + "source": "iana", + "compressible": true, + "extensions": ["smi","smil"] + }, + "application/smpte336m": { + "source": "iana" + }, + "application/soap+fastinfoset": { + "source": "iana" + }, + "application/soap+xml": { + "source": "iana", + "compressible": true + }, + "application/sparql-query": { + "source": "iana", + "extensions": ["rq"] + }, + "application/sparql-results+xml": { + "source": "iana", + "compressible": true, + "extensions": ["srx"] + }, + "application/spdx+json": { + "source": "iana", + "compressible": true + }, + "application/spirits-event+xml": { + "source": "iana", + "compressible": true + }, + "application/sql": { + "source": "iana" + }, + "application/srgs": { + "source": "iana", + "extensions": ["gram"] + }, + "application/srgs+xml": { + "source": "iana", + "compressible": true, + "extensions": ["grxml"] + }, + "application/sru+xml": { + "source": "iana", + "compressible": true, + "extensions": ["sru"] + }, + "application/ssdl+xml": { + "source": "apache", + "compressible": true, + "extensions": ["ssdl"] + }, + "application/ssml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["ssml"] + }, + "application/stix+json": { + "source": "iana", + "compressible": true + }, + "application/swid+xml": { + "source": "iana", + "compressible": true, + "extensions": ["swidtag"] + }, + "application/tamp-apex-update": { + "source": "iana" + }, + "application/tamp-apex-update-confirm": { + "source": "iana" + }, + "application/tamp-community-update": { + "source": "iana" + }, + "application/tamp-community-update-confirm": { + "source": "iana" + }, + "application/tamp-error": { + "source": "iana" + }, + "application/tamp-sequence-adjust": { + "source": "iana" + }, + "application/tamp-sequence-adjust-confirm": { + "source": "iana" + }, + "application/tamp-status-query": { + "source": "iana" + }, + "application/tamp-status-response": { + "source": "iana" + }, + "application/tamp-update": { + "source": "iana" + }, + "application/tamp-update-confirm": { + "source": "iana" + }, + "application/tar": { + "compressible": true + }, + "application/taxii+json": { + "source": "iana", + "compressible": true + }, + "application/td+json": { + "source": "iana", + "compressible": true + }, + "application/tei+xml": { + "source": "iana", + "compressible": true, + "extensions": ["tei","teicorpus"] + }, + "application/tetra_isi": { + "source": "iana" + }, + "application/thraud+xml": { + "source": "iana", + "compressible": true, + "extensions": ["tfi"] + }, + "application/timestamp-query": { + "source": "iana" + }, + "application/timestamp-reply": { + "source": "iana" + }, + "application/timestamped-data": { + "source": "iana", + "extensions": ["tsd"] + }, + "application/tlsrpt+gzip": { + "source": "iana" + }, + "application/tlsrpt+json": { + "source": "iana", + "compressible": true + }, + "application/tnauthlist": { + "source": "iana" + }, + "application/token-introspection+jwt": { + "source": "iana" + }, + "application/toml": { + "compressible": true, + "extensions": ["toml"] + }, + "application/trickle-ice-sdpfrag": { + "source": "iana" + }, + "application/trig": { + "source": "iana", + "extensions": ["trig"] + }, + "application/ttml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["ttml"] + }, + "application/tve-trigger": { + "source": "iana" + }, + "application/tzif": { + "source": "iana" + }, + "application/tzif-leap": { + "source": "iana" + }, + "application/ubjson": { + "compressible": false, + "extensions": ["ubj"] + }, + "application/ulpfec": { + "source": "iana" + }, + "application/urc-grpsheet+xml": { + "source": "iana", + "compressible": true + }, + "application/urc-ressheet+xml": { + "source": "iana", + "compressible": true, + "extensions": ["rsheet"] + }, + "application/urc-targetdesc+xml": { + "source": "iana", + "compressible": true, + "extensions": ["td"] + }, + "application/urc-uisocketdesc+xml": { + "source": "iana", + "compressible": true + }, + "application/vcard+json": { + "source": "iana", + "compressible": true + }, + "application/vcard+xml": { + "source": "iana", + "compressible": true + }, + "application/vemmi": { + "source": "iana" + }, + "application/vividence.scriptfile": { + "source": "apache" + }, + "application/vnd.1000minds.decision-model+xml": { + "source": "iana", + "compressible": true, + "extensions": ["1km"] + }, + "application/vnd.3gpp-prose+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp-prose-pc3ch+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp-v2x-local-service-information": { + "source": "iana" + }, + "application/vnd.3gpp.5gnas": { + "source": "iana" + }, + "application/vnd.3gpp.access-transfer-events+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.bsf+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.gmop+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.gtpc": { + "source": "iana" + }, + "application/vnd.3gpp.interworking-data": { + "source": "iana" + }, + "application/vnd.3gpp.lpp": { + "source": "iana" + }, + "application/vnd.3gpp.mc-signalling-ear": { + "source": "iana" + }, + "application/vnd.3gpp.mcdata-affiliation-command+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcdata-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcdata-payload": { + "source": "iana" + }, + "application/vnd.3gpp.mcdata-service-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcdata-signalling": { + "source": "iana" + }, + "application/vnd.3gpp.mcdata-ue-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcdata-user-profile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-affiliation-command+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-floor-request+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-location-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-mbms-usage-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-service-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-signed+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-ue-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-ue-init-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcptt-user-profile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-affiliation-command+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-affiliation-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-location-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-mbms-usage-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-service-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-transmission-request+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-ue-config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mcvideo-user-profile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.mid-call+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.ngap": { + "source": "iana" + }, + "application/vnd.3gpp.pfcp": { + "source": "iana" + }, + "application/vnd.3gpp.pic-bw-large": { + "source": "iana", + "extensions": ["plb"] + }, + "application/vnd.3gpp.pic-bw-small": { + "source": "iana", + "extensions": ["psb"] + }, + "application/vnd.3gpp.pic-bw-var": { + "source": "iana", + "extensions": ["pvb"] + }, + "application/vnd.3gpp.s1ap": { + "source": "iana" + }, + "application/vnd.3gpp.sms": { + "source": "iana" + }, + "application/vnd.3gpp.sms+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.srvcc-ext+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.srvcc-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.state-and-event-info+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp.ussd+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp2.bcmcsinfo+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.3gpp2.sms": { + "source": "iana" + }, + "application/vnd.3gpp2.tcap": { + "source": "iana", + "extensions": ["tcap"] + }, + "application/vnd.3lightssoftware.imagescal": { + "source": "iana" + }, + "application/vnd.3m.post-it-notes": { + "source": "iana", + "extensions": ["pwn"] + }, + "application/vnd.accpac.simply.aso": { + "source": "iana", + "extensions": ["aso"] + }, + "application/vnd.accpac.simply.imp": { + "source": "iana", + "extensions": ["imp"] + }, + "application/vnd.acucobol": { + "source": "iana", + "extensions": ["acu"] + }, + "application/vnd.acucorp": { + "source": "iana", + "extensions": ["atc","acutc"] + }, + "application/vnd.adobe.air-application-installer-package+zip": { + "source": "apache", + "compressible": false, + "extensions": ["air"] + }, + "application/vnd.adobe.flash.movie": { + "source": "iana" + }, + "application/vnd.adobe.formscentral.fcdt": { + "source": "iana", + "extensions": ["fcdt"] + }, + "application/vnd.adobe.fxp": { + "source": "iana", + "extensions": ["fxp","fxpl"] + }, + "application/vnd.adobe.partial-upload": { + "source": "iana" + }, + "application/vnd.adobe.xdp+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xdp"] + }, + "application/vnd.adobe.xfdf": { + "source": "iana", + "extensions": ["xfdf"] + }, + "application/vnd.aether.imp": { + "source": "iana" + }, + "application/vnd.afpc.afplinedata": { + "source": "iana" + }, + "application/vnd.afpc.afplinedata-pagedef": { + "source": "iana" + }, + "application/vnd.afpc.cmoca-cmresource": { + "source": "iana" + }, + "application/vnd.afpc.foca-charset": { + "source": "iana" + }, + "application/vnd.afpc.foca-codedfont": { + "source": "iana" + }, + "application/vnd.afpc.foca-codepage": { + "source": "iana" + }, + "application/vnd.afpc.modca": { + "source": "iana" + }, + "application/vnd.afpc.modca-cmtable": { + "source": "iana" + }, + "application/vnd.afpc.modca-formdef": { + "source": "iana" + }, + "application/vnd.afpc.modca-mediummap": { + "source": "iana" + }, + "application/vnd.afpc.modca-objectcontainer": { + "source": "iana" + }, + "application/vnd.afpc.modca-overlay": { + "source": "iana" + }, + "application/vnd.afpc.modca-pagesegment": { + "source": "iana" + }, + "application/vnd.age": { + "source": "iana", + "extensions": ["age"] + }, + "application/vnd.ah-barcode": { + "source": "iana" + }, + "application/vnd.ahead.space": { + "source": "iana", + "extensions": ["ahead"] + }, + "application/vnd.airzip.filesecure.azf": { + "source": "iana", + "extensions": ["azf"] + }, + "application/vnd.airzip.filesecure.azs": { + "source": "iana", + "extensions": ["azs"] + }, + "application/vnd.amadeus+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.amazon.ebook": { + "source": "apache", + "extensions": ["azw"] + }, + "application/vnd.amazon.mobi8-ebook": { + "source": "iana" + }, + "application/vnd.americandynamics.acc": { + "source": "iana", + "extensions": ["acc"] + }, + "application/vnd.amiga.ami": { + "source": "iana", + "extensions": ["ami"] + }, + "application/vnd.amundsen.maze+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.android.ota": { + "source": "iana" + }, + "application/vnd.android.package-archive": { + "source": "apache", + "compressible": false, + "extensions": ["apk"] + }, + "application/vnd.anki": { + "source": "iana" + }, + "application/vnd.anser-web-certificate-issue-initiation": { + "source": "iana", + "extensions": ["cii"] + }, + "application/vnd.anser-web-funds-transfer-initiation": { + "source": "apache", + "extensions": ["fti"] + }, + "application/vnd.antix.game-component": { + "source": "iana", + "extensions": ["atx"] + }, + "application/vnd.apache.arrow.file": { + "source": "iana" + }, + "application/vnd.apache.arrow.stream": { + "source": "iana" + }, + "application/vnd.apache.thrift.binary": { + "source": "iana" + }, + "application/vnd.apache.thrift.compact": { + "source": "iana" + }, + "application/vnd.apache.thrift.json": { + "source": "iana" + }, + "application/vnd.api+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.aplextor.warrp+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.apothekende.reservation+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.apple.installer+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mpkg"] + }, + "application/vnd.apple.keynote": { + "source": "iana", + "extensions": ["key"] + }, + "application/vnd.apple.mpegurl": { + "source": "iana", + "extensions": ["m3u8"] + }, + "application/vnd.apple.numbers": { + "source": "iana", + "extensions": ["numbers"] + }, + "application/vnd.apple.pages": { + "source": "iana", + "extensions": ["pages"] + }, + "application/vnd.apple.pkpass": { + "compressible": false, + "extensions": ["pkpass"] + }, + "application/vnd.arastra.swi": { + "source": "iana" + }, + "application/vnd.aristanetworks.swi": { + "source": "iana", + "extensions": ["swi"] + }, + "application/vnd.artisan+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.artsquare": { + "source": "iana" + }, + "application/vnd.astraea-software.iota": { + "source": "iana", + "extensions": ["iota"] + }, + "application/vnd.audiograph": { + "source": "iana", + "extensions": ["aep"] + }, + "application/vnd.autopackage": { + "source": "iana" + }, + "application/vnd.avalon+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.avistar+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.balsamiq.bmml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["bmml"] + }, + "application/vnd.balsamiq.bmpr": { + "source": "iana" + }, + "application/vnd.banana-accounting": { + "source": "iana" + }, + "application/vnd.bbf.usp.error": { + "source": "iana" + }, + "application/vnd.bbf.usp.msg": { + "source": "iana" + }, + "application/vnd.bbf.usp.msg+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.bekitzur-stech+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.bint.med-content": { + "source": "iana" + }, + "application/vnd.biopax.rdf+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.blink-idb-value-wrapper": { + "source": "iana" + }, + "application/vnd.blueice.multipass": { + "source": "iana", + "extensions": ["mpm"] + }, + "application/vnd.bluetooth.ep.oob": { + "source": "iana" + }, + "application/vnd.bluetooth.le.oob": { + "source": "iana" + }, + "application/vnd.bmi": { + "source": "iana", + "extensions": ["bmi"] + }, + "application/vnd.bpf": { + "source": "iana" + }, + "application/vnd.bpf3": { + "source": "iana" + }, + "application/vnd.businessobjects": { + "source": "iana", + "extensions": ["rep"] + }, + "application/vnd.byu.uapi+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.cab-jscript": { + "source": "iana" + }, + "application/vnd.canon-cpdl": { + "source": "iana" + }, + "application/vnd.canon-lips": { + "source": "iana" + }, + "application/vnd.capasystems-pg+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.cendio.thinlinc.clientconf": { + "source": "iana" + }, + "application/vnd.century-systems.tcp_stream": { + "source": "iana" + }, + "application/vnd.chemdraw+xml": { + "source": "iana", + "compressible": true, + "extensions": ["cdxml"] + }, + "application/vnd.chess-pgn": { + "source": "iana" + }, + "application/vnd.chipnuts.karaoke-mmd": { + "source": "iana", + "extensions": ["mmd"] + }, + "application/vnd.ciedi": { + "source": "iana" + }, + "application/vnd.cinderella": { + "source": "iana", + "extensions": ["cdy"] + }, + "application/vnd.cirpack.isdn-ext": { + "source": "iana" + }, + "application/vnd.citationstyles.style+xml": { + "source": "iana", + "compressible": true, + "extensions": ["csl"] + }, + "application/vnd.claymore": { + "source": "iana", + "extensions": ["cla"] + }, + "application/vnd.cloanto.rp9": { + "source": "iana", + "extensions": ["rp9"] + }, + "application/vnd.clonk.c4group": { + "source": "iana", + "extensions": ["c4g","c4d","c4f","c4p","c4u"] + }, + "application/vnd.cluetrust.cartomobile-config": { + "source": "iana", + "extensions": ["c11amc"] + }, + "application/vnd.cluetrust.cartomobile-config-pkg": { + "source": "iana", + "extensions": ["c11amz"] + }, + "application/vnd.coffeescript": { + "source": "iana" + }, + "application/vnd.collabio.xodocuments.document": { + "source": "iana" + }, + "application/vnd.collabio.xodocuments.document-template": { + "source": "iana" + }, + "application/vnd.collabio.xodocuments.presentation": { + "source": "iana" + }, + "application/vnd.collabio.xodocuments.presentation-template": { + "source": "iana" + }, + "application/vnd.collabio.xodocuments.spreadsheet": { + "source": "iana" + }, + "application/vnd.collabio.xodocuments.spreadsheet-template": { + "source": "iana" + }, + "application/vnd.collection+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.collection.doc+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.collection.next+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.comicbook+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.comicbook-rar": { + "source": "iana" + }, + "application/vnd.commerce-battelle": { + "source": "iana" + }, + "application/vnd.commonspace": { + "source": "iana", + "extensions": ["csp"] + }, + "application/vnd.contact.cmsg": { + "source": "iana", + "extensions": ["cdbcmsg"] + }, + "application/vnd.coreos.ignition+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.cosmocaller": { + "source": "iana", + "extensions": ["cmc"] + }, + "application/vnd.crick.clicker": { + "source": "iana", + "extensions": ["clkx"] + }, + "application/vnd.crick.clicker.keyboard": { + "source": "iana", + "extensions": ["clkk"] + }, + "application/vnd.crick.clicker.palette": { + "source": "iana", + "extensions": ["clkp"] + }, + "application/vnd.crick.clicker.template": { + "source": "iana", + "extensions": ["clkt"] + }, + "application/vnd.crick.clicker.wordbank": { + "source": "iana", + "extensions": ["clkw"] + }, + "application/vnd.criticaltools.wbs+xml": { + "source": "iana", + "compressible": true, + "extensions": ["wbs"] + }, + "application/vnd.cryptii.pipe+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.crypto-shade-file": { + "source": "iana" + }, + "application/vnd.cryptomator.encrypted": { + "source": "iana" + }, + "application/vnd.cryptomator.vault": { + "source": "iana" + }, + "application/vnd.ctc-posml": { + "source": "iana", + "extensions": ["pml"] + }, + "application/vnd.ctct.ws+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.cups-pdf": { + "source": "iana" + }, + "application/vnd.cups-postscript": { + "source": "iana" + }, + "application/vnd.cups-ppd": { + "source": "iana", + "extensions": ["ppd"] + }, + "application/vnd.cups-raster": { + "source": "iana" + }, + "application/vnd.cups-raw": { + "source": "iana" + }, + "application/vnd.curl": { + "source": "iana" + }, + "application/vnd.curl.car": { + "source": "apache", + "extensions": ["car"] + }, + "application/vnd.curl.pcurl": { + "source": "apache", + "extensions": ["pcurl"] + }, + "application/vnd.cyan.dean.root+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.cybank": { + "source": "iana" + }, + "application/vnd.cyclonedx+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.cyclonedx+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.d2l.coursepackage1p0+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.d3m-dataset": { + "source": "iana" + }, + "application/vnd.d3m-problem": { + "source": "iana" + }, + "application/vnd.dart": { + "source": "iana", + "compressible": true, + "extensions": ["dart"] + }, + "application/vnd.data-vision.rdz": { + "source": "iana", + "extensions": ["rdz"] + }, + "application/vnd.datapackage+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.dataresource+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.dbf": { + "source": "iana", + "extensions": ["dbf"] + }, + "application/vnd.debian.binary-package": { + "source": "iana" + }, + "application/vnd.dece.data": { + "source": "iana", + "extensions": ["uvf","uvvf","uvd","uvvd"] + }, + "application/vnd.dece.ttml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["uvt","uvvt"] + }, + "application/vnd.dece.unspecified": { + "source": "iana", + "extensions": ["uvx","uvvx"] + }, + "application/vnd.dece.zip": { + "source": "iana", + "extensions": ["uvz","uvvz"] + }, + "application/vnd.denovo.fcselayout-link": { + "source": "iana", + "extensions": ["fe_launch"] + }, + "application/vnd.desmume.movie": { + "source": "iana" + }, + "application/vnd.dir-bi.plate-dl-nosuffix": { + "source": "iana" + }, + "application/vnd.dm.delegation+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dna": { + "source": "iana", + "extensions": ["dna"] + }, + "application/vnd.document+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.dolby.mlp": { + "source": "apache", + "extensions": ["mlp"] + }, + "application/vnd.dolby.mobile.1": { + "source": "iana" + }, + "application/vnd.dolby.mobile.2": { + "source": "iana" + }, + "application/vnd.doremir.scorecloud-binary-document": { + "source": "iana" + }, + "application/vnd.dpgraph": { + "source": "iana", + "extensions": ["dpg"] + }, + "application/vnd.dreamfactory": { + "source": "iana", + "extensions": ["dfac"] + }, + "application/vnd.drive+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ds-keypoint": { + "source": "apache", + "extensions": ["kpxx"] + }, + "application/vnd.dtg.local": { + "source": "iana" + }, + "application/vnd.dtg.local.flash": { + "source": "iana" + }, + "application/vnd.dtg.local.html": { + "source": "iana" + }, + "application/vnd.dvb.ait": { + "source": "iana", + "extensions": ["ait"] + }, + "application/vnd.dvb.dvbisl+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.dvbj": { + "source": "iana" + }, + "application/vnd.dvb.esgcontainer": { + "source": "iana" + }, + "application/vnd.dvb.ipdcdftnotifaccess": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgaccess": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgaccess2": { + "source": "iana" + }, + "application/vnd.dvb.ipdcesgpdd": { + "source": "iana" + }, + "application/vnd.dvb.ipdcroaming": { + "source": "iana" + }, + "application/vnd.dvb.iptv.alfec-base": { + "source": "iana" + }, + "application/vnd.dvb.iptv.alfec-enhancement": { + "source": "iana" + }, + "application/vnd.dvb.notif-aggregate-root+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.notif-container+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.notif-generic+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.notif-ia-msglist+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.notif-ia-registration-request+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.notif-ia-registration-response+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.notif-init+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.dvb.pfr": { + "source": "iana" + }, + "application/vnd.dvb.service": { + "source": "iana", + "extensions": ["svc"] + }, + "application/vnd.dxr": { + "source": "iana" + }, + "application/vnd.dynageo": { + "source": "iana", + "extensions": ["geo"] + }, + "application/vnd.dzr": { + "source": "iana" + }, + "application/vnd.easykaraoke.cdgdownload": { + "source": "iana" + }, + "application/vnd.ecdis-update": { + "source": "iana" + }, + "application/vnd.ecip.rlp": { + "source": "iana" + }, + "application/vnd.eclipse.ditto+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ecowin.chart": { + "source": "iana", + "extensions": ["mag"] + }, + "application/vnd.ecowin.filerequest": { + "source": "iana" + }, + "application/vnd.ecowin.fileupdate": { + "source": "iana" + }, + "application/vnd.ecowin.series": { + "source": "iana" + }, + "application/vnd.ecowin.seriesrequest": { + "source": "iana" + }, + "application/vnd.ecowin.seriesupdate": { + "source": "iana" + }, + "application/vnd.efi.img": { + "source": "iana" + }, + "application/vnd.efi.iso": { + "source": "iana" + }, + "application/vnd.emclient.accessrequest+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.enliven": { + "source": "iana", + "extensions": ["nml"] + }, + "application/vnd.enphase.envoy": { + "source": "iana" + }, + "application/vnd.eprints.data+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.epson.esf": { + "source": "iana", + "extensions": ["esf"] + }, + "application/vnd.epson.msf": { + "source": "iana", + "extensions": ["msf"] + }, + "application/vnd.epson.quickanime": { + "source": "iana", + "extensions": ["qam"] + }, + "application/vnd.epson.salt": { + "source": "iana", + "extensions": ["slt"] + }, + "application/vnd.epson.ssf": { + "source": "iana", + "extensions": ["ssf"] + }, + "application/vnd.ericsson.quickcall": { + "source": "iana" + }, + "application/vnd.espass-espass+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.eszigno3+xml": { + "source": "iana", + "compressible": true, + "extensions": ["es3","et3"] + }, + "application/vnd.etsi.aoc+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.asic-e+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.etsi.asic-s+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.etsi.cug+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvcommand+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvdiscovery+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvprofile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvsad-bc+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvsad-cod+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvsad-npvr+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvservice+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvsync+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.iptvueprofile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.mcid+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.mheg5": { + "source": "iana" + }, + "application/vnd.etsi.overload-control-policy-dataset+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.pstn+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.sci+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.simservs+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.timestamp-token": { + "source": "iana" + }, + "application/vnd.etsi.tsl+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.etsi.tsl.der": { + "source": "iana" + }, + "application/vnd.eu.kasparian.car+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.eudora.data": { + "source": "iana" + }, + "application/vnd.evolv.ecig.profile": { + "source": "iana" + }, + "application/vnd.evolv.ecig.settings": { + "source": "iana" + }, + "application/vnd.evolv.ecig.theme": { + "source": "iana" + }, + "application/vnd.exstream-empower+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.exstream-package": { + "source": "iana" + }, + "application/vnd.ezpix-album": { + "source": "iana", + "extensions": ["ez2"] + }, + "application/vnd.ezpix-package": { + "source": "iana", + "extensions": ["ez3"] + }, + "application/vnd.f-secure.mobile": { + "source": "iana" + }, + "application/vnd.familysearch.gedcom+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.fastcopy-disk-image": { + "source": "iana" + }, + "application/vnd.fdf": { + "source": "iana", + "extensions": ["fdf"] + }, + "application/vnd.fdsn.mseed": { + "source": "iana", + "extensions": ["mseed"] + }, + "application/vnd.fdsn.seed": { + "source": "iana", + "extensions": ["seed","dataless"] + }, + "application/vnd.ffsns": { + "source": "iana" + }, + "application/vnd.ficlab.flb+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.filmit.zfc": { + "source": "iana" + }, + "application/vnd.fints": { + "source": "iana" + }, + "application/vnd.firemonkeys.cloudcell": { + "source": "iana" + }, + "application/vnd.flographit": { + "source": "iana", + "extensions": ["gph"] + }, + "application/vnd.fluxtime.clip": { + "source": "iana", + "extensions": ["ftc"] + }, + "application/vnd.font-fontforge-sfd": { + "source": "iana" + }, + "application/vnd.framemaker": { + "source": "iana", + "extensions": ["fm","frame","maker","book"] + }, + "application/vnd.frogans.fnc": { + "source": "iana", + "extensions": ["fnc"] + }, + "application/vnd.frogans.ltf": { + "source": "iana", + "extensions": ["ltf"] + }, + "application/vnd.fsc.weblaunch": { + "source": "iana", + "extensions": ["fsc"] + }, + "application/vnd.fujifilm.fb.docuworks": { + "source": "iana" + }, + "application/vnd.fujifilm.fb.docuworks.binder": { + "source": "iana" + }, + "application/vnd.fujifilm.fb.docuworks.container": { + "source": "iana" + }, + "application/vnd.fujifilm.fb.jfi+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.fujitsu.oasys": { + "source": "iana", + "extensions": ["oas"] + }, + "application/vnd.fujitsu.oasys2": { + "source": "iana", + "extensions": ["oa2"] + }, + "application/vnd.fujitsu.oasys3": { + "source": "iana", + "extensions": ["oa3"] + }, + "application/vnd.fujitsu.oasysgp": { + "source": "iana", + "extensions": ["fg5"] + }, + "application/vnd.fujitsu.oasysprs": { + "source": "iana", + "extensions": ["bh2"] + }, + "application/vnd.fujixerox.art-ex": { + "source": "iana" + }, + "application/vnd.fujixerox.art4": { + "source": "iana" + }, + "application/vnd.fujixerox.ddd": { + "source": "iana", + "extensions": ["ddd"] + }, + "application/vnd.fujixerox.docuworks": { + "source": "iana", + "extensions": ["xdw"] + }, + "application/vnd.fujixerox.docuworks.binder": { + "source": "iana", + "extensions": ["xbd"] + }, + "application/vnd.fujixerox.docuworks.container": { + "source": "iana" + }, + "application/vnd.fujixerox.hbpl": { + "source": "iana" + }, + "application/vnd.fut-misnet": { + "source": "iana" + }, + "application/vnd.futoin+cbor": { + "source": "iana" + }, + "application/vnd.futoin+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.fuzzysheet": { + "source": "iana", + "extensions": ["fzs"] + }, + "application/vnd.genomatix.tuxedo": { + "source": "iana", + "extensions": ["txd"] + }, + "application/vnd.gentics.grd+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.geo+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.geocube+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.geogebra.file": { + "source": "iana", + "extensions": ["ggb"] + }, + "application/vnd.geogebra.slides": { + "source": "iana" + }, + "application/vnd.geogebra.tool": { + "source": "iana", + "extensions": ["ggt"] + }, + "application/vnd.geometry-explorer": { + "source": "iana", + "extensions": ["gex","gre"] + }, + "application/vnd.geonext": { + "source": "iana", + "extensions": ["gxt"] + }, + "application/vnd.geoplan": { + "source": "iana", + "extensions": ["g2w"] + }, + "application/vnd.geospace": { + "source": "iana", + "extensions": ["g3w"] + }, + "application/vnd.gerber": { + "source": "iana" + }, + "application/vnd.globalplatform.card-content-mgt": { + "source": "iana" + }, + "application/vnd.globalplatform.card-content-mgt-response": { + "source": "iana" + }, + "application/vnd.gmx": { + "source": "iana", + "extensions": ["gmx"] + }, + "application/vnd.google-apps.document": { + "compressible": false, + "extensions": ["gdoc"] + }, + "application/vnd.google-apps.presentation": { + "compressible": false, + "extensions": ["gslides"] + }, + "application/vnd.google-apps.spreadsheet": { + "compressible": false, + "extensions": ["gsheet"] + }, + "application/vnd.google-earth.kml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["kml"] + }, + "application/vnd.google-earth.kmz": { + "source": "iana", + "compressible": false, + "extensions": ["kmz"] + }, + "application/vnd.gov.sk.e-form+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.gov.sk.e-form+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.gov.sk.xmldatacontainer+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.grafeq": { + "source": "iana", + "extensions": ["gqf","gqs"] + }, + "application/vnd.gridmp": { + "source": "iana" + }, + "application/vnd.groove-account": { + "source": "iana", + "extensions": ["gac"] + }, + "application/vnd.groove-help": { + "source": "iana", + "extensions": ["ghf"] + }, + "application/vnd.groove-identity-message": { + "source": "iana", + "extensions": ["gim"] + }, + "application/vnd.groove-injector": { + "source": "iana", + "extensions": ["grv"] + }, + "application/vnd.groove-tool-message": { + "source": "iana", + "extensions": ["gtm"] + }, + "application/vnd.groove-tool-template": { + "source": "iana", + "extensions": ["tpl"] + }, + "application/vnd.groove-vcard": { + "source": "iana", + "extensions": ["vcg"] + }, + "application/vnd.hal+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hal+xml": { + "source": "iana", + "compressible": true, + "extensions": ["hal"] + }, + "application/vnd.handheld-entertainment+xml": { + "source": "iana", + "compressible": true, + "extensions": ["zmm"] + }, + "application/vnd.hbci": { + "source": "iana", + "extensions": ["hbci"] + }, + "application/vnd.hc+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hcl-bireports": { + "source": "iana" + }, + "application/vnd.hdt": { + "source": "iana" + }, + "application/vnd.heroku+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hhe.lesson-player": { + "source": "iana", + "extensions": ["les"] + }, + "application/vnd.hl7cda+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/vnd.hl7v2+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/vnd.hp-hpgl": { + "source": "iana", + "extensions": ["hpgl"] + }, + "application/vnd.hp-hpid": { + "source": "iana", + "extensions": ["hpid"] + }, + "application/vnd.hp-hps": { + "source": "iana", + "extensions": ["hps"] + }, + "application/vnd.hp-jlyt": { + "source": "iana", + "extensions": ["jlt"] + }, + "application/vnd.hp-pcl": { + "source": "iana", + "extensions": ["pcl"] + }, + "application/vnd.hp-pclxl": { + "source": "iana", + "extensions": ["pclxl"] + }, + "application/vnd.httphone": { + "source": "iana" + }, + "application/vnd.hydrostatix.sof-data": { + "source": "iana", + "extensions": ["sfd-hdstx"] + }, + "application/vnd.hyper+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hyper-item+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hyperdrive+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.hzn-3d-crossword": { + "source": "iana" + }, + "application/vnd.ibm.afplinedata": { + "source": "iana" + }, + "application/vnd.ibm.electronic-media": { + "source": "iana" + }, + "application/vnd.ibm.minipay": { + "source": "iana", + "extensions": ["mpy"] + }, + "application/vnd.ibm.modcap": { + "source": "iana", + "extensions": ["afp","listafp","list3820"] + }, + "application/vnd.ibm.rights-management": { + "source": "iana", + "extensions": ["irm"] + }, + "application/vnd.ibm.secure-container": { + "source": "iana", + "extensions": ["sc"] + }, + "application/vnd.iccprofile": { + "source": "iana", + "extensions": ["icc","icm"] + }, + "application/vnd.ieee.1905": { + "source": "iana" + }, + "application/vnd.igloader": { + "source": "iana", + "extensions": ["igl"] + }, + "application/vnd.imagemeter.folder+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.imagemeter.image+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.immervision-ivp": { + "source": "iana", + "extensions": ["ivp"] + }, + "application/vnd.immervision-ivu": { + "source": "iana", + "extensions": ["ivu"] + }, + "application/vnd.ims.imsccv1p1": { + "source": "iana" + }, + "application/vnd.ims.imsccv1p2": { + "source": "iana" + }, + "application/vnd.ims.imsccv1p3": { + "source": "iana" + }, + "application/vnd.ims.lis.v2.result+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolconsumerprofile+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolproxy+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolproxy.id+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolsettings+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ims.lti.v2.toolsettings.simple+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.informedcontrol.rms+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.informix-visionary": { + "source": "iana" + }, + "application/vnd.infotech.project": { + "source": "iana" + }, + "application/vnd.infotech.project+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.innopath.wamp.notification": { + "source": "iana" + }, + "application/vnd.insors.igm": { + "source": "iana", + "extensions": ["igm"] + }, + "application/vnd.intercon.formnet": { + "source": "iana", + "extensions": ["xpw","xpx"] + }, + "application/vnd.intergeo": { + "source": "iana", + "extensions": ["i2g"] + }, + "application/vnd.intertrust.digibox": { + "source": "iana" + }, + "application/vnd.intertrust.nncp": { + "source": "iana" + }, + "application/vnd.intu.qbo": { + "source": "iana", + "extensions": ["qbo"] + }, + "application/vnd.intu.qfx": { + "source": "iana", + "extensions": ["qfx"] + }, + "application/vnd.iptc.g2.catalogitem+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.iptc.g2.conceptitem+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.iptc.g2.knowledgeitem+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.iptc.g2.newsitem+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.iptc.g2.newsmessage+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.iptc.g2.packageitem+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.iptc.g2.planningitem+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.ipunplugged.rcprofile": { + "source": "iana", + "extensions": ["rcprofile"] + }, + "application/vnd.irepository.package+xml": { + "source": "iana", + "compressible": true, + "extensions": ["irp"] + }, + "application/vnd.is-xpr": { + "source": "iana", + "extensions": ["xpr"] + }, + "application/vnd.isac.fcs": { + "source": "iana", + "extensions": ["fcs"] + }, + "application/vnd.iso11783-10+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.jam": { + "source": "iana", + "extensions": ["jam"] + }, + "application/vnd.japannet-directory-service": { + "source": "iana" + }, + "application/vnd.japannet-jpnstore-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-payment-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-registration": { + "source": "iana" + }, + "application/vnd.japannet-registration-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-setstore-wakeup": { + "source": "iana" + }, + "application/vnd.japannet-verification": { + "source": "iana" + }, + "application/vnd.japannet-verification-wakeup": { + "source": "iana" + }, + "application/vnd.jcp.javame.midlet-rms": { + "source": "iana", + "extensions": ["rms"] + }, + "application/vnd.jisp": { + "source": "iana", + "extensions": ["jisp"] + }, + "application/vnd.joost.joda-archive": { + "source": "iana", + "extensions": ["joda"] + }, + "application/vnd.jsk.isdn-ngn": { + "source": "iana" + }, + "application/vnd.kahootz": { + "source": "iana", + "extensions": ["ktz","ktr"] + }, + "application/vnd.kde.karbon": { + "source": "iana", + "extensions": ["karbon"] + }, + "application/vnd.kde.kchart": { + "source": "iana", + "extensions": ["chrt"] + }, + "application/vnd.kde.kformula": { + "source": "iana", + "extensions": ["kfo"] + }, + "application/vnd.kde.kivio": { + "source": "iana", + "extensions": ["flw"] + }, + "application/vnd.kde.kontour": { + "source": "iana", + "extensions": ["kon"] + }, + "application/vnd.kde.kpresenter": { + "source": "iana", + "extensions": ["kpr","kpt"] + }, + "application/vnd.kde.kspread": { + "source": "iana", + "extensions": ["ksp"] + }, + "application/vnd.kde.kword": { + "source": "iana", + "extensions": ["kwd","kwt"] + }, + "application/vnd.kenameaapp": { + "source": "iana", + "extensions": ["htke"] + }, + "application/vnd.kidspiration": { + "source": "iana", + "extensions": ["kia"] + }, + "application/vnd.kinar": { + "source": "iana", + "extensions": ["kne","knp"] + }, + "application/vnd.koan": { + "source": "iana", + "extensions": ["skp","skd","skt","skm"] + }, + "application/vnd.kodak-descriptor": { + "source": "iana", + "extensions": ["sse"] + }, + "application/vnd.las": { + "source": "iana" + }, + "application/vnd.las.las+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.las.las+xml": { + "source": "iana", + "compressible": true, + "extensions": ["lasxml"] + }, + "application/vnd.laszip": { + "source": "iana" + }, + "application/vnd.leap+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.liberty-request+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.llamagraphics.life-balance.desktop": { + "source": "iana", + "extensions": ["lbd"] + }, + "application/vnd.llamagraphics.life-balance.exchange+xml": { + "source": "iana", + "compressible": true, + "extensions": ["lbe"] + }, + "application/vnd.logipipe.circuit+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.loom": { + "source": "iana" + }, + "application/vnd.lotus-1-2-3": { + "source": "iana", + "extensions": ["123"] + }, + "application/vnd.lotus-approach": { + "source": "iana", + "extensions": ["apr"] + }, + "application/vnd.lotus-freelance": { + "source": "iana", + "extensions": ["pre"] + }, + "application/vnd.lotus-notes": { + "source": "iana", + "extensions": ["nsf"] + }, + "application/vnd.lotus-organizer": { + "source": "iana", + "extensions": ["org"] + }, + "application/vnd.lotus-screencam": { + "source": "iana", + "extensions": ["scm"] + }, + "application/vnd.lotus-wordpro": { + "source": "iana", + "extensions": ["lwp"] + }, + "application/vnd.macports.portpkg": { + "source": "iana", + "extensions": ["portpkg"] + }, + "application/vnd.mapbox-vector-tile": { + "source": "iana", + "extensions": ["mvt"] + }, + "application/vnd.marlin.drm.actiontoken+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.marlin.drm.conftoken+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.marlin.drm.license+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.marlin.drm.mdcf": { + "source": "iana" + }, + "application/vnd.mason+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.maxar.archive.3tz+zip": { + "source": "iana", + "compressible": false + }, + "application/vnd.maxmind.maxmind-db": { + "source": "iana" + }, + "application/vnd.mcd": { + "source": "iana", + "extensions": ["mcd"] + }, + "application/vnd.medcalcdata": { + "source": "iana", + "extensions": ["mc1"] + }, + "application/vnd.mediastation.cdkey": { + "source": "iana", + "extensions": ["cdkey"] + }, + "application/vnd.meridian-slingshot": { + "source": "iana" + }, + "application/vnd.mfer": { + "source": "iana", + "extensions": ["mwf"] + }, + "application/vnd.mfmp": { + "source": "iana", + "extensions": ["mfm"] + }, + "application/vnd.micro+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.micrografx.flo": { + "source": "iana", + "extensions": ["flo"] + }, + "application/vnd.micrografx.igx": { + "source": "iana", + "extensions": ["igx"] + }, + "application/vnd.microsoft.portable-executable": { + "source": "iana" + }, + "application/vnd.microsoft.windows.thumbnail-cache": { + "source": "iana" + }, + "application/vnd.miele+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.mif": { + "source": "iana", + "extensions": ["mif"] + }, + "application/vnd.minisoft-hp3000-save": { + "source": "iana" + }, + "application/vnd.mitsubishi.misty-guard.trustweb": { + "source": "iana" + }, + "application/vnd.mobius.daf": { + "source": "iana", + "extensions": ["daf"] + }, + "application/vnd.mobius.dis": { + "source": "iana", + "extensions": ["dis"] + }, + "application/vnd.mobius.mbk": { + "source": "iana", + "extensions": ["mbk"] + }, + "application/vnd.mobius.mqy": { + "source": "iana", + "extensions": ["mqy"] + }, + "application/vnd.mobius.msl": { + "source": "iana", + "extensions": ["msl"] + }, + "application/vnd.mobius.plc": { + "source": "iana", + "extensions": ["plc"] + }, + "application/vnd.mobius.txf": { + "source": "iana", + "extensions": ["txf"] + }, + "application/vnd.mophun.application": { + "source": "iana", + "extensions": ["mpn"] + }, + "application/vnd.mophun.certificate": { + "source": "iana", + "extensions": ["mpc"] + }, + "application/vnd.motorola.flexsuite": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.adsi": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.fis": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.gotap": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.kmr": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.ttc": { + "source": "iana" + }, + "application/vnd.motorola.flexsuite.wem": { + "source": "iana" + }, + "application/vnd.motorola.iprm": { + "source": "iana" + }, + "application/vnd.mozilla.xul+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xul"] + }, + "application/vnd.ms-3mfdocument": { + "source": "iana" + }, + "application/vnd.ms-artgalry": { + "source": "iana", + "extensions": ["cil"] + }, + "application/vnd.ms-asf": { + "source": "iana" + }, + "application/vnd.ms-cab-compressed": { + "source": "iana", + "extensions": ["cab"] + }, + "application/vnd.ms-color.iccprofile": { + "source": "apache" + }, + "application/vnd.ms-excel": { + "source": "iana", + "compressible": false, + "extensions": ["xls","xlm","xla","xlc","xlt","xlw"] + }, + "application/vnd.ms-excel.addin.macroenabled.12": { + "source": "iana", + "extensions": ["xlam"] + }, + "application/vnd.ms-excel.sheet.binary.macroenabled.12": { + "source": "iana", + "extensions": ["xlsb"] + }, + "application/vnd.ms-excel.sheet.macroenabled.12": { + "source": "iana", + "extensions": ["xlsm"] + }, + "application/vnd.ms-excel.template.macroenabled.12": { + "source": "iana", + "extensions": ["xltm"] + }, + "application/vnd.ms-fontobject": { + "source": "iana", + "compressible": true, + "extensions": ["eot"] + }, + "application/vnd.ms-htmlhelp": { + "source": "iana", + "extensions": ["chm"] + }, + "application/vnd.ms-ims": { + "source": "iana", + "extensions": ["ims"] + }, + "application/vnd.ms-lrm": { + "source": "iana", + "extensions": ["lrm"] + }, + "application/vnd.ms-office.activex+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.ms-officetheme": { + "source": "iana", + "extensions": ["thmx"] + }, + "application/vnd.ms-opentype": { + "source": "apache", + "compressible": true + }, + "application/vnd.ms-outlook": { + "compressible": false, + "extensions": ["msg"] + }, + "application/vnd.ms-package.obfuscated-opentype": { + "source": "apache" + }, + "application/vnd.ms-pki.seccat": { + "source": "apache", + "extensions": ["cat"] + }, + "application/vnd.ms-pki.stl": { + "source": "apache", + "extensions": ["stl"] + }, + "application/vnd.ms-playready.initiator+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.ms-powerpoint": { + "source": "iana", + "compressible": false, + "extensions": ["ppt","pps","pot"] + }, + "application/vnd.ms-powerpoint.addin.macroenabled.12": { + "source": "iana", + "extensions": ["ppam"] + }, + "application/vnd.ms-powerpoint.presentation.macroenabled.12": { + "source": "iana", + "extensions": ["pptm"] + }, + "application/vnd.ms-powerpoint.slide.macroenabled.12": { + "source": "iana", + "extensions": ["sldm"] + }, + "application/vnd.ms-powerpoint.slideshow.macroenabled.12": { + "source": "iana", + "extensions": ["ppsm"] + }, + "application/vnd.ms-powerpoint.template.macroenabled.12": { + "source": "iana", + "extensions": ["potm"] + }, + "application/vnd.ms-printdevicecapabilities+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.ms-printing.printticket+xml": { + "source": "apache", + "compressible": true + }, + "application/vnd.ms-printschematicket+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.ms-project": { + "source": "iana", + "extensions": ["mpp","mpt"] + }, + "application/vnd.ms-tnef": { + "source": "iana" + }, + "application/vnd.ms-windows.devicepairing": { + "source": "iana" + }, + "application/vnd.ms-windows.nwprinting.oob": { + "source": "iana" + }, + "application/vnd.ms-windows.printerpairing": { + "source": "iana" + }, + "application/vnd.ms-windows.wsd.oob": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.lic-chlg-req": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.lic-resp": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.meter-chlg-req": { + "source": "iana" + }, + "application/vnd.ms-wmdrm.meter-resp": { + "source": "iana" + }, + "application/vnd.ms-word.document.macroenabled.12": { + "source": "iana", + "extensions": ["docm"] + }, + "application/vnd.ms-word.template.macroenabled.12": { + "source": "iana", + "extensions": ["dotm"] + }, + "application/vnd.ms-works": { + "source": "iana", + "extensions": ["wps","wks","wcm","wdb"] + }, + "application/vnd.ms-wpl": { + "source": "iana", + "extensions": ["wpl"] + }, + "application/vnd.ms-xpsdocument": { + "source": "iana", + "compressible": false, + "extensions": ["xps"] + }, + "application/vnd.msa-disk-image": { + "source": "iana" + }, + "application/vnd.mseq": { + "source": "iana", + "extensions": ["mseq"] + }, + "application/vnd.msign": { + "source": "iana" + }, + "application/vnd.multiad.creator": { + "source": "iana" + }, + "application/vnd.multiad.creator.cif": { + "source": "iana" + }, + "application/vnd.music-niff": { + "source": "iana" + }, + "application/vnd.musician": { + "source": "iana", + "extensions": ["mus"] + }, + "application/vnd.muvee.style": { + "source": "iana", + "extensions": ["msty"] + }, + "application/vnd.mynfc": { + "source": "iana", + "extensions": ["taglet"] + }, + "application/vnd.nacamar.ybrid+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.ncd.control": { + "source": "iana" + }, + "application/vnd.ncd.reference": { + "source": "iana" + }, + "application/vnd.nearst.inv+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.nebumind.line": { + "source": "iana" + }, + "application/vnd.nervana": { + "source": "iana" + }, + "application/vnd.netfpx": { + "source": "iana" + }, + "application/vnd.neurolanguage.nlu": { + "source": "iana", + "extensions": ["nlu"] + }, + "application/vnd.nimn": { + "source": "iana" + }, + "application/vnd.nintendo.nitro.rom": { + "source": "iana" + }, + "application/vnd.nintendo.snes.rom": { + "source": "iana" + }, + "application/vnd.nitf": { + "source": "iana", + "extensions": ["ntf","nitf"] + }, + "application/vnd.noblenet-directory": { + "source": "iana", + "extensions": ["nnd"] + }, + "application/vnd.noblenet-sealer": { + "source": "iana", + "extensions": ["nns"] + }, + "application/vnd.noblenet-web": { + "source": "iana", + "extensions": ["nnw"] + }, + "application/vnd.nokia.catalogs": { + "source": "iana" + }, + "application/vnd.nokia.conml+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.conml+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.nokia.iptv.config+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.nokia.isds-radio-presets": { + "source": "iana" + }, + "application/vnd.nokia.landmark+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.landmark+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.nokia.landmarkcollection+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.nokia.n-gage.ac+xml": { + "source": "iana", + "compressible": true, + "extensions": ["ac"] + }, + "application/vnd.nokia.n-gage.data": { + "source": "iana", + "extensions": ["ngdat"] + }, + "application/vnd.nokia.n-gage.symbian.install": { + "source": "iana", + "extensions": ["n-gage"] + }, + "application/vnd.nokia.ncd": { + "source": "iana" + }, + "application/vnd.nokia.pcd+wbxml": { + "source": "iana" + }, + "application/vnd.nokia.pcd+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.nokia.radio-preset": { + "source": "iana", + "extensions": ["rpst"] + }, + "application/vnd.nokia.radio-presets": { + "source": "iana", + "extensions": ["rpss"] + }, + "application/vnd.novadigm.edm": { + "source": "iana", + "extensions": ["edm"] + }, + "application/vnd.novadigm.edx": { + "source": "iana", + "extensions": ["edx"] + }, + "application/vnd.novadigm.ext": { + "source": "iana", + "extensions": ["ext"] + }, + "application/vnd.ntt-local.content-share": { + "source": "iana" + }, + "application/vnd.ntt-local.file-transfer": { + "source": "iana" + }, + "application/vnd.ntt-local.ogw_remote-access": { + "source": "iana" + }, + "application/vnd.ntt-local.sip-ta_remote": { + "source": "iana" + }, + "application/vnd.ntt-local.sip-ta_tcp_stream": { + "source": "iana" + }, + "application/vnd.oasis.opendocument.chart": { + "source": "iana", + "extensions": ["odc"] + }, + "application/vnd.oasis.opendocument.chart-template": { + "source": "iana", + "extensions": ["otc"] + }, + "application/vnd.oasis.opendocument.database": { + "source": "iana", + "extensions": ["odb"] + }, + "application/vnd.oasis.opendocument.formula": { + "source": "iana", + "extensions": ["odf"] + }, + "application/vnd.oasis.opendocument.formula-template": { + "source": "iana", + "extensions": ["odft"] + }, + "application/vnd.oasis.opendocument.graphics": { + "source": "iana", + "compressible": false, + "extensions": ["odg"] + }, + "application/vnd.oasis.opendocument.graphics-template": { + "source": "iana", + "extensions": ["otg"] + }, + "application/vnd.oasis.opendocument.image": { + "source": "iana", + "extensions": ["odi"] + }, + "application/vnd.oasis.opendocument.image-template": { + "source": "iana", + "extensions": ["oti"] + }, + "application/vnd.oasis.opendocument.presentation": { + "source": "iana", + "compressible": false, + "extensions": ["odp"] + }, + "application/vnd.oasis.opendocument.presentation-template": { + "source": "iana", + "extensions": ["otp"] + }, + "application/vnd.oasis.opendocument.spreadsheet": { + "source": "iana", + "compressible": false, + "extensions": ["ods"] + }, + "application/vnd.oasis.opendocument.spreadsheet-template": { + "source": "iana", + "extensions": ["ots"] + }, + "application/vnd.oasis.opendocument.text": { + "source": "iana", + "compressible": false, + "extensions": ["odt"] + }, + "application/vnd.oasis.opendocument.text-master": { + "source": "iana", + "extensions": ["odm"] + }, + "application/vnd.oasis.opendocument.text-template": { + "source": "iana", + "extensions": ["ott"] + }, + "application/vnd.oasis.opendocument.text-web": { + "source": "iana", + "extensions": ["oth"] + }, + "application/vnd.obn": { + "source": "iana" + }, + "application/vnd.ocf+cbor": { + "source": "iana" + }, + "application/vnd.oci.image.manifest.v1+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.oftn.l10n+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.contentaccessdownload+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.contentaccessstreaming+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.cspg-hexbinary": { + "source": "iana" + }, + "application/vnd.oipf.dae.svg+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.dae.xhtml+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.mippvcontrolmessage+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.pae.gem": { + "source": "iana" + }, + "application/vnd.oipf.spdiscovery+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.spdlist+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.ueprofile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oipf.userprofile+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.olpc-sugar": { + "source": "iana", + "extensions": ["xo"] + }, + "application/vnd.oma-scws-config": { + "source": "iana" + }, + "application/vnd.oma-scws-http-request": { + "source": "iana" + }, + "application/vnd.oma-scws-http-response": { + "source": "iana" + }, + "application/vnd.oma.bcast.associated-procedure-parameter+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.drm-trigger+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.imd+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.ltkm": { + "source": "iana" + }, + "application/vnd.oma.bcast.notification+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.provisioningtrigger": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgboot": { + "source": "iana" + }, + "application/vnd.oma.bcast.sgdd+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.sgdu": { + "source": "iana" + }, + "application/vnd.oma.bcast.simple-symbol-container": { + "source": "iana" + }, + "application/vnd.oma.bcast.smartcard-trigger+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.sprov+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.bcast.stkm": { + "source": "iana" + }, + "application/vnd.oma.cab-address-book+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.cab-feature-handler+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.cab-pcc+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.cab-subs-invite+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.cab-user-prefs+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.dcd": { + "source": "iana" + }, + "application/vnd.oma.dcdc": { + "source": "iana" + }, + "application/vnd.oma.dd2+xml": { + "source": "iana", + "compressible": true, + "extensions": ["dd2"] + }, + "application/vnd.oma.drm.risd+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.group-usage-list+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.lwm2m+cbor": { + "source": "iana" + }, + "application/vnd.oma.lwm2m+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.lwm2m+tlv": { + "source": "iana" + }, + "application/vnd.oma.pal+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.poc.detailed-progress-report+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.poc.final-report+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.poc.groups+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.poc.invocation-descriptor+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.poc.optimized-progress-report+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.push": { + "source": "iana" + }, + "application/vnd.oma.scidm.messages+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oma.xcap-directory+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.omads-email+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/vnd.omads-file+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/vnd.omads-folder+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/vnd.omaloc-supl-init": { + "source": "iana" + }, + "application/vnd.onepager": { + "source": "iana" + }, + "application/vnd.onepagertamp": { + "source": "iana" + }, + "application/vnd.onepagertamx": { + "source": "iana" + }, + "application/vnd.onepagertat": { + "source": "iana" + }, + "application/vnd.onepagertatp": { + "source": "iana" + }, + "application/vnd.onepagertatx": { + "source": "iana" + }, + "application/vnd.openblox.game+xml": { + "source": "iana", + "compressible": true, + "extensions": ["obgx"] + }, + "application/vnd.openblox.game-binary": { + "source": "iana" + }, + "application/vnd.openeye.oeb": { + "source": "iana" + }, + "application/vnd.openofficeorg.extension": { + "source": "apache", + "extensions": ["oxt"] + }, + "application/vnd.openstreetmap.data+xml": { + "source": "iana", + "compressible": true, + "extensions": ["osm"] + }, + "application/vnd.opentimestamps.ots": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.custom-properties+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.customxmlproperties+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawing+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramcolors+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramdata+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramlayout+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.drawingml.diagramstyle+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.extended-properties+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.commentauthors+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.comments+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.handoutmaster+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesmaster+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.notesslide+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation": { + "source": "iana", + "compressible": false, + "extensions": ["pptx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.presprops+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide": { + "source": "iana", + "extensions": ["sldx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slide+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidelayout+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slidemaster+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow": { + "source": "iana", + "extensions": ["ppsx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.slideupdateinfo+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.tablestyles+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.tags+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.template": { + "source": "iana", + "extensions": ["potx"] + }, + "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.presentationml.viewprops+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.calcchain+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.externallink+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcachedefinition+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotcacherecords+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.pivottable+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.querytable+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionheaders+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionlog+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedstrings+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": { + "source": "iana", + "compressible": false, + "extensions": ["xlsx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetmetadata+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.tablesinglecells+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template": { + "source": "iana", + "extensions": ["xltx"] + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.usernames+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.volatiledependencies+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.theme+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.themeoverride+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.vmldrawing": { + "source": "iana" + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": { + "source": "iana", + "compressible": false, + "extensions": ["docx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.fonttable+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template": { + "source": "iana", + "extensions": ["dotx"] + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-officedocument.wordprocessingml.websettings+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-package.core-properties+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.openxmlformats-package.relationships+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oracle.resource+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.orange.indata": { + "source": "iana" + }, + "application/vnd.osa.netdeploy": { + "source": "iana" + }, + "application/vnd.osgeo.mapguide.package": { + "source": "iana", + "extensions": ["mgp"] + }, + "application/vnd.osgi.bundle": { + "source": "iana" + }, + "application/vnd.osgi.dp": { + "source": "iana", + "extensions": ["dp"] + }, + "application/vnd.osgi.subsystem": { + "source": "iana", + "extensions": ["esa"] + }, + "application/vnd.otps.ct-kip+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.oxli.countgraph": { + "source": "iana" + }, + "application/vnd.pagerduty+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.palm": { + "source": "iana", + "extensions": ["pdb","pqa","oprc"] + }, + "application/vnd.panoply": { + "source": "iana" + }, + "application/vnd.paos.xml": { + "source": "iana" + }, + "application/vnd.patentdive": { + "source": "iana" + }, + "application/vnd.patientecommsdoc": { + "source": "iana" + }, + "application/vnd.pawaafile": { + "source": "iana", + "extensions": ["paw"] + }, + "application/vnd.pcos": { + "source": "iana" + }, + "application/vnd.pg.format": { + "source": "iana", + "extensions": ["str"] + }, + "application/vnd.pg.osasli": { + "source": "iana", + "extensions": ["ei6"] + }, + "application/vnd.piaccess.application-licence": { + "source": "iana" + }, + "application/vnd.picsel": { + "source": "iana", + "extensions": ["efif"] + }, + "application/vnd.pmi.widget": { + "source": "iana", + "extensions": ["wg"] + }, + "application/vnd.poc.group-advertisement+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.pocketlearn": { + "source": "iana", + "extensions": ["plf"] + }, + "application/vnd.powerbuilder6": { + "source": "iana", + "extensions": ["pbd"] + }, + "application/vnd.powerbuilder6-s": { + "source": "iana" + }, + "application/vnd.powerbuilder7": { + "source": "iana" + }, + "application/vnd.powerbuilder7-s": { + "source": "iana" + }, + "application/vnd.powerbuilder75": { + "source": "iana" + }, + "application/vnd.powerbuilder75-s": { + "source": "iana" + }, + "application/vnd.preminet": { + "source": "iana" + }, + "application/vnd.previewsystems.box": { + "source": "iana", + "extensions": ["box"] + }, + "application/vnd.proteus.magazine": { + "source": "iana", + "extensions": ["mgz"] + }, + "application/vnd.psfs": { + "source": "iana" + }, + "application/vnd.publishare-delta-tree": { + "source": "iana", + "extensions": ["qps"] + }, + "application/vnd.pvi.ptid1": { + "source": "iana", + "extensions": ["ptid"] + }, + "application/vnd.pwg-multiplexed": { + "source": "iana" + }, + "application/vnd.pwg-xhtml-print+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.qualcomm.brew-app-res": { + "source": "iana" + }, + "application/vnd.quarantainenet": { + "source": "iana" + }, + "application/vnd.quark.quarkxpress": { + "source": "iana", + "extensions": ["qxd","qxt","qwd","qwt","qxl","qxb"] + }, + "application/vnd.quobject-quoxdocument": { + "source": "iana" + }, + "application/vnd.radisys.moml+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-audit+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-audit-conf+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-audit-conn+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-audit-dialog+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-audit-stream+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-conf+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog-base+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog-fax-detect+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog-fax-sendrecv+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog-group+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog-speech+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.radisys.msml-dialog-transform+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.rainstor.data": { + "source": "iana" + }, + "application/vnd.rapid": { + "source": "iana" + }, + "application/vnd.rar": { + "source": "iana", + "extensions": ["rar"] + }, + "application/vnd.realvnc.bed": { + "source": "iana", + "extensions": ["bed"] + }, + "application/vnd.recordare.musicxml": { + "source": "iana", + "extensions": ["mxl"] + }, + "application/vnd.recordare.musicxml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["musicxml"] + }, + "application/vnd.renlearn.rlprint": { + "source": "iana" + }, + "application/vnd.resilient.logic": { + "source": "iana" + }, + "application/vnd.restful+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.rig.cryptonote": { + "source": "iana", + "extensions": ["cryptonote"] + }, + "application/vnd.rim.cod": { + "source": "apache", + "extensions": ["cod"] + }, + "application/vnd.rn-realmedia": { + "source": "apache", + "extensions": ["rm"] + }, + "application/vnd.rn-realmedia-vbr": { + "source": "apache", + "extensions": ["rmvb"] + }, + "application/vnd.route66.link66+xml": { + "source": "iana", + "compressible": true, + "extensions": ["link66"] + }, + "application/vnd.rs-274x": { + "source": "iana" + }, + "application/vnd.ruckus.download": { + "source": "iana" + }, + "application/vnd.s3sms": { + "source": "iana" + }, + "application/vnd.sailingtracker.track": { + "source": "iana", + "extensions": ["st"] + }, + "application/vnd.sar": { + "source": "iana" + }, + "application/vnd.sbm.cid": { + "source": "iana" + }, + "application/vnd.sbm.mid2": { + "source": "iana" + }, + "application/vnd.scribus": { + "source": "iana" + }, + "application/vnd.sealed.3df": { + "source": "iana" + }, + "application/vnd.sealed.csf": { + "source": "iana" + }, + "application/vnd.sealed.doc": { + "source": "iana" + }, + "application/vnd.sealed.eml": { + "source": "iana" + }, + "application/vnd.sealed.mht": { + "source": "iana" + }, + "application/vnd.sealed.net": { + "source": "iana" + }, + "application/vnd.sealed.ppt": { + "source": "iana" + }, + "application/vnd.sealed.tiff": { + "source": "iana" + }, + "application/vnd.sealed.xls": { + "source": "iana" + }, + "application/vnd.sealedmedia.softseal.html": { + "source": "iana" + }, + "application/vnd.sealedmedia.softseal.pdf": { + "source": "iana" + }, + "application/vnd.seemail": { + "source": "iana", + "extensions": ["see"] + }, + "application/vnd.seis+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.sema": { + "source": "iana", + "extensions": ["sema"] + }, + "application/vnd.semd": { + "source": "iana", + "extensions": ["semd"] + }, + "application/vnd.semf": { + "source": "iana", + "extensions": ["semf"] + }, + "application/vnd.shade-save-file": { + "source": "iana" + }, + "application/vnd.shana.informed.formdata": { + "source": "iana", + "extensions": ["ifm"] + }, + "application/vnd.shana.informed.formtemplate": { + "source": "iana", + "extensions": ["itp"] + }, + "application/vnd.shana.informed.interchange": { + "source": "iana", + "extensions": ["iif"] + }, + "application/vnd.shana.informed.package": { + "source": "iana", + "extensions": ["ipk"] + }, + "application/vnd.shootproof+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.shopkick+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.shp": { + "source": "iana" + }, + "application/vnd.shx": { + "source": "iana" + }, + "application/vnd.sigrok.session": { + "source": "iana" + }, + "application/vnd.simtech-mindmapper": { + "source": "iana", + "extensions": ["twd","twds"] + }, + "application/vnd.siren+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.smaf": { + "source": "iana", + "extensions": ["mmf"] + }, + "application/vnd.smart.notebook": { + "source": "iana" + }, + "application/vnd.smart.teacher": { + "source": "iana", + "extensions": ["teacher"] + }, + "application/vnd.snesdev-page-table": { + "source": "iana" + }, + "application/vnd.software602.filler.form+xml": { + "source": "iana", + "compressible": true, + "extensions": ["fo"] + }, + "application/vnd.software602.filler.form-xml-zip": { + "source": "iana" + }, + "application/vnd.solent.sdkm+xml": { + "source": "iana", + "compressible": true, + "extensions": ["sdkm","sdkd"] + }, + "application/vnd.spotfire.dxp": { + "source": "iana", + "extensions": ["dxp"] + }, + "application/vnd.spotfire.sfs": { + "source": "iana", + "extensions": ["sfs"] + }, + "application/vnd.sqlite3": { + "source": "iana" + }, + "application/vnd.sss-cod": { + "source": "iana" + }, + "application/vnd.sss-dtf": { + "source": "iana" + }, + "application/vnd.sss-ntf": { + "source": "iana" + }, + "application/vnd.stardivision.calc": { + "source": "apache", + "extensions": ["sdc"] + }, + "application/vnd.stardivision.draw": { + "source": "apache", + "extensions": ["sda"] + }, + "application/vnd.stardivision.impress": { + "source": "apache", + "extensions": ["sdd"] + }, + "application/vnd.stardivision.math": { + "source": "apache", + "extensions": ["smf"] + }, + "application/vnd.stardivision.writer": { + "source": "apache", + "extensions": ["sdw","vor"] + }, + "application/vnd.stardivision.writer-global": { + "source": "apache", + "extensions": ["sgl"] + }, + "application/vnd.stepmania.package": { + "source": "iana", + "extensions": ["smzip"] + }, + "application/vnd.stepmania.stepchart": { + "source": "iana", + "extensions": ["sm"] + }, + "application/vnd.street-stream": { + "source": "iana" + }, + "application/vnd.sun.wadl+xml": { + "source": "iana", + "compressible": true, + "extensions": ["wadl"] + }, + "application/vnd.sun.xml.calc": { + "source": "apache", + "extensions": ["sxc"] + }, + "application/vnd.sun.xml.calc.template": { + "source": "apache", + "extensions": ["stc"] + }, + "application/vnd.sun.xml.draw": { + "source": "apache", + "extensions": ["sxd"] + }, + "application/vnd.sun.xml.draw.template": { + "source": "apache", + "extensions": ["std"] + }, + "application/vnd.sun.xml.impress": { + "source": "apache", + "extensions": ["sxi"] + }, + "application/vnd.sun.xml.impress.template": { + "source": "apache", + "extensions": ["sti"] + }, + "application/vnd.sun.xml.math": { + "source": "apache", + "extensions": ["sxm"] + }, + "application/vnd.sun.xml.writer": { + "source": "apache", + "extensions": ["sxw"] + }, + "application/vnd.sun.xml.writer.global": { + "source": "apache", + "extensions": ["sxg"] + }, + "application/vnd.sun.xml.writer.template": { + "source": "apache", + "extensions": ["stw"] + }, + "application/vnd.sus-calendar": { + "source": "iana", + "extensions": ["sus","susp"] + }, + "application/vnd.svd": { + "source": "iana", + "extensions": ["svd"] + }, + "application/vnd.swiftview-ics": { + "source": "iana" + }, + "application/vnd.sycle+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.syft+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.symbian.install": { + "source": "apache", + "extensions": ["sis","sisx"] + }, + "application/vnd.syncml+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["xsm"] + }, + "application/vnd.syncml.dm+wbxml": { + "source": "iana", + "charset": "UTF-8", + "extensions": ["bdm"] + }, + "application/vnd.syncml.dm+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["xdm"] + }, + "application/vnd.syncml.dm.notification": { + "source": "iana" + }, + "application/vnd.syncml.dmddf+wbxml": { + "source": "iana" + }, + "application/vnd.syncml.dmddf+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["ddf"] + }, + "application/vnd.syncml.dmtnds+wbxml": { + "source": "iana" + }, + "application/vnd.syncml.dmtnds+xml": { + "source": "iana", + "charset": "UTF-8", + "compressible": true + }, + "application/vnd.syncml.ds.notification": { + "source": "iana" + }, + "application/vnd.tableschema+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.tao.intent-module-archive": { + "source": "iana", + "extensions": ["tao"] + }, + "application/vnd.tcpdump.pcap": { + "source": "iana", + "extensions": ["pcap","cap","dmp"] + }, + "application/vnd.think-cell.ppttc+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.tmd.mediaflex.api+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.tml": { + "source": "iana" + }, + "application/vnd.tmobile-livetv": { + "source": "iana", + "extensions": ["tmo"] + }, + "application/vnd.tri.onesource": { + "source": "iana" + }, + "application/vnd.trid.tpt": { + "source": "iana", + "extensions": ["tpt"] + }, + "application/vnd.triscape.mxs": { + "source": "iana", + "extensions": ["mxs"] + }, + "application/vnd.trueapp": { + "source": "iana", + "extensions": ["tra"] + }, + "application/vnd.truedoc": { + "source": "iana" + }, + "application/vnd.ubisoft.webplayer": { + "source": "iana" + }, + "application/vnd.ufdl": { + "source": "iana", + "extensions": ["ufd","ufdl"] + }, + "application/vnd.uiq.theme": { + "source": "iana", + "extensions": ["utz"] + }, + "application/vnd.umajin": { + "source": "iana", + "extensions": ["umj"] + }, + "application/vnd.unity": { + "source": "iana", + "extensions": ["unityweb"] + }, + "application/vnd.uoml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["uoml"] + }, + "application/vnd.uplanet.alert": { + "source": "iana" + }, + "application/vnd.uplanet.alert-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.bearer-choice": { + "source": "iana" + }, + "application/vnd.uplanet.bearer-choice-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.cacheop": { + "source": "iana" + }, + "application/vnd.uplanet.cacheop-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.channel": { + "source": "iana" + }, + "application/vnd.uplanet.channel-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.list": { + "source": "iana" + }, + "application/vnd.uplanet.list-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.listcmd": { + "source": "iana" + }, + "application/vnd.uplanet.listcmd-wbxml": { + "source": "iana" + }, + "application/vnd.uplanet.signal": { + "source": "iana" + }, + "application/vnd.uri-map": { + "source": "iana" + }, + "application/vnd.valve.source.material": { + "source": "iana" + }, + "application/vnd.vcx": { + "source": "iana", + "extensions": ["vcx"] + }, + "application/vnd.vd-study": { + "source": "iana" + }, + "application/vnd.vectorworks": { + "source": "iana" + }, + "application/vnd.vel+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.verimatrix.vcas": { + "source": "iana" + }, + "application/vnd.veritone.aion+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.veryant.thin": { + "source": "iana" + }, + "application/vnd.ves.encrypted": { + "source": "iana" + }, + "application/vnd.vidsoft.vidconference": { + "source": "iana" + }, + "application/vnd.visio": { + "source": "iana", + "extensions": ["vsd","vst","vss","vsw"] + }, + "application/vnd.visionary": { + "source": "iana", + "extensions": ["vis"] + }, + "application/vnd.vividence.scriptfile": { + "source": "iana" + }, + "application/vnd.vsf": { + "source": "iana", + "extensions": ["vsf"] + }, + "application/vnd.wap.sic": { + "source": "iana" + }, + "application/vnd.wap.slc": { + "source": "iana" + }, + "application/vnd.wap.wbxml": { + "source": "iana", + "charset": "UTF-8", + "extensions": ["wbxml"] + }, + "application/vnd.wap.wmlc": { + "source": "iana", + "extensions": ["wmlc"] + }, + "application/vnd.wap.wmlscriptc": { + "source": "iana", + "extensions": ["wmlsc"] + }, + "application/vnd.webturbo": { + "source": "iana", + "extensions": ["wtb"] + }, + "application/vnd.wfa.dpp": { + "source": "iana" + }, + "application/vnd.wfa.p2p": { + "source": "iana" + }, + "application/vnd.wfa.wsc": { + "source": "iana" + }, + "application/vnd.windows.devicepairing": { + "source": "iana" + }, + "application/vnd.wmc": { + "source": "iana" + }, + "application/vnd.wmf.bootstrap": { + "source": "iana" + }, + "application/vnd.wolfram.mathematica": { + "source": "iana" + }, + "application/vnd.wolfram.mathematica.package": { + "source": "iana" + }, + "application/vnd.wolfram.player": { + "source": "iana", + "extensions": ["nbp"] + }, + "application/vnd.wordperfect": { + "source": "iana", + "extensions": ["wpd"] + }, + "application/vnd.wqd": { + "source": "iana", + "extensions": ["wqd"] + }, + "application/vnd.wrq-hp3000-labelled": { + "source": "iana" + }, + "application/vnd.wt.stf": { + "source": "iana", + "extensions": ["stf"] + }, + "application/vnd.wv.csp+wbxml": { + "source": "iana" + }, + "application/vnd.wv.csp+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.wv.ssp+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.xacml+json": { + "source": "iana", + "compressible": true + }, + "application/vnd.xara": { + "source": "iana", + "extensions": ["xar"] + }, + "application/vnd.xfdl": { + "source": "iana", + "extensions": ["xfdl"] + }, + "application/vnd.xfdl.webform": { + "source": "iana" + }, + "application/vnd.xmi+xml": { + "source": "iana", + "compressible": true + }, + "application/vnd.xmpie.cpkg": { + "source": "iana" + }, + "application/vnd.xmpie.dpkg": { + "source": "iana" + }, + "application/vnd.xmpie.plan": { + "source": "iana" + }, + "application/vnd.xmpie.ppkg": { + "source": "iana" + }, + "application/vnd.xmpie.xlim": { + "source": "iana" + }, + "application/vnd.yamaha.hv-dic": { + "source": "iana", + "extensions": ["hvd"] + }, + "application/vnd.yamaha.hv-script": { + "source": "iana", + "extensions": ["hvs"] + }, + "application/vnd.yamaha.hv-voice": { + "source": "iana", + "extensions": ["hvp"] + }, + "application/vnd.yamaha.openscoreformat": { + "source": "iana", + "extensions": ["osf"] + }, + "application/vnd.yamaha.openscoreformat.osfpvg+xml": { + "source": "iana", + "compressible": true, + "extensions": ["osfpvg"] + }, + "application/vnd.yamaha.remote-setup": { + "source": "iana" + }, + "application/vnd.yamaha.smaf-audio": { + "source": "iana", + "extensions": ["saf"] + }, + "application/vnd.yamaha.smaf-phrase": { + "source": "iana", + "extensions": ["spf"] + }, + "application/vnd.yamaha.through-ngn": { + "source": "iana" + }, + "application/vnd.yamaha.tunnel-udpencap": { + "source": "iana" + }, + "application/vnd.yaoweme": { + "source": "iana" + }, + "application/vnd.yellowriver-custom-menu": { + "source": "iana", + "extensions": ["cmp"] + }, + "application/vnd.youtube.yt": { + "source": "iana" + }, + "application/vnd.zul": { + "source": "iana", + "extensions": ["zir","zirz"] + }, + "application/vnd.zzazz.deck+xml": { + "source": "iana", + "compressible": true, + "extensions": ["zaz"] + }, + "application/voicexml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["vxml"] + }, + "application/voucher-cms+json": { + "source": "iana", + "compressible": true + }, + "application/vq-rtcpxr": { + "source": "iana" + }, + "application/wasm": { + "source": "iana", + "compressible": true, + "extensions": ["wasm"] + }, + "application/watcherinfo+xml": { + "source": "iana", + "compressible": true, + "extensions": ["wif"] + }, + "application/webpush-options+json": { + "source": "iana", + "compressible": true + }, + "application/whoispp-query": { + "source": "iana" + }, + "application/whoispp-response": { + "source": "iana" + }, + "application/widget": { + "source": "iana", + "extensions": ["wgt"] + }, + "application/winhlp": { + "source": "apache", + "extensions": ["hlp"] + }, + "application/wita": { + "source": "iana" + }, + "application/wordperfect5.1": { + "source": "iana" + }, + "application/wsdl+xml": { + "source": "iana", + "compressible": true, + "extensions": ["wsdl"] + }, + "application/wspolicy+xml": { + "source": "iana", + "compressible": true, + "extensions": ["wspolicy"] + }, + "application/x-7z-compressed": { + "source": "apache", + "compressible": false, + "extensions": ["7z"] + }, + "application/x-abiword": { + "source": "apache", + "extensions": ["abw"] + }, + "application/x-ace-compressed": { + "source": "apache", + "extensions": ["ace"] + }, + "application/x-amf": { + "source": "apache" + }, + "application/x-apple-diskimage": { + "source": "apache", + "extensions": ["dmg"] + }, + "application/x-arj": { + "compressible": false, + "extensions": ["arj"] + }, + "application/x-authorware-bin": { + "source": "apache", + "extensions": ["aab","x32","u32","vox"] + }, + "application/x-authorware-map": { + "source": "apache", + "extensions": ["aam"] + }, + "application/x-authorware-seg": { + "source": "apache", + "extensions": ["aas"] + }, + "application/x-bcpio": { + "source": "apache", + "extensions": ["bcpio"] + }, + "application/x-bdoc": { + "compressible": false, + "extensions": ["bdoc"] + }, + "application/x-bittorrent": { + "source": "apache", + "extensions": ["torrent"] + }, + "application/x-blorb": { + "source": "apache", + "extensions": ["blb","blorb"] + }, + "application/x-bzip": { + "source": "apache", + "compressible": false, + "extensions": ["bz"] + }, + "application/x-bzip2": { + "source": "apache", + "compressible": false, + "extensions": ["bz2","boz"] + }, + "application/x-cbr": { + "source": "apache", + "extensions": ["cbr","cba","cbt","cbz","cb7"] + }, + "application/x-cdlink": { + "source": "apache", + "extensions": ["vcd"] + }, + "application/x-cfs-compressed": { + "source": "apache", + "extensions": ["cfs"] + }, + "application/x-chat": { + "source": "apache", + "extensions": ["chat"] + }, + "application/x-chess-pgn": { + "source": "apache", + "extensions": ["pgn"] + }, + "application/x-chrome-extension": { + "extensions": ["crx"] + }, + "application/x-cocoa": { + "source": "nginx", + "extensions": ["cco"] + }, + "application/x-compress": { + "source": "apache" + }, + "application/x-conference": { + "source": "apache", + "extensions": ["nsc"] + }, + "application/x-cpio": { + "source": "apache", + "extensions": ["cpio"] + }, + "application/x-csh": { + "source": "apache", + "extensions": ["csh"] + }, + "application/x-deb": { + "compressible": false + }, + "application/x-debian-package": { + "source": "apache", + "extensions": ["deb","udeb"] + }, + "application/x-dgc-compressed": { + "source": "apache", + "extensions": ["dgc"] + }, + "application/x-director": { + "source": "apache", + "extensions": ["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"] + }, + "application/x-doom": { + "source": "apache", + "extensions": ["wad"] + }, + "application/x-dtbncx+xml": { + "source": "apache", + "compressible": true, + "extensions": ["ncx"] + }, + "application/x-dtbook+xml": { + "source": "apache", + "compressible": true, + "extensions": ["dtb"] + }, + "application/x-dtbresource+xml": { + "source": "apache", + "compressible": true, + "extensions": ["res"] + }, + "application/x-dvi": { + "source": "apache", + "compressible": false, + "extensions": ["dvi"] + }, + "application/x-envoy": { + "source": "apache", + "extensions": ["evy"] + }, + "application/x-eva": { + "source": "apache", + "extensions": ["eva"] + }, + "application/x-font-bdf": { + "source": "apache", + "extensions": ["bdf"] + }, + "application/x-font-dos": { + "source": "apache" + }, + "application/x-font-framemaker": { + "source": "apache" + }, + "application/x-font-ghostscript": { + "source": "apache", + "extensions": ["gsf"] + }, + "application/x-font-libgrx": { + "source": "apache" + }, + "application/x-font-linux-psf": { + "source": "apache", + "extensions": ["psf"] + }, + "application/x-font-pcf": { + "source": "apache", + "extensions": ["pcf"] + }, + "application/x-font-snf": { + "source": "apache", + "extensions": ["snf"] + }, + "application/x-font-speedo": { + "source": "apache" + }, + "application/x-font-sunos-news": { + "source": "apache" + }, + "application/x-font-type1": { + "source": "apache", + "extensions": ["pfa","pfb","pfm","afm"] + }, + "application/x-font-vfont": { + "source": "apache" + }, + "application/x-freearc": { + "source": "apache", + "extensions": ["arc"] + }, + "application/x-futuresplash": { + "source": "apache", + "extensions": ["spl"] + }, + "application/x-gca-compressed": { + "source": "apache", + "extensions": ["gca"] + }, + "application/x-glulx": { + "source": "apache", + "extensions": ["ulx"] + }, + "application/x-gnumeric": { + "source": "apache", + "extensions": ["gnumeric"] + }, + "application/x-gramps-xml": { + "source": "apache", + "extensions": ["gramps"] + }, + "application/x-gtar": { + "source": "apache", + "extensions": ["gtar"] + }, + "application/x-gzip": { + "source": "apache" + }, + "application/x-hdf": { + "source": "apache", + "extensions": ["hdf"] + }, + "application/x-httpd-php": { + "compressible": true, + "extensions": ["php"] + }, + "application/x-install-instructions": { + "source": "apache", + "extensions": ["install"] + }, + "application/x-iso9660-image": { + "source": "apache", + "extensions": ["iso"] + }, + "application/x-iwork-keynote-sffkey": { + "extensions": ["key"] + }, + "application/x-iwork-numbers-sffnumbers": { + "extensions": ["numbers"] + }, + "application/x-iwork-pages-sffpages": { + "extensions": ["pages"] + }, + "application/x-java-archive-diff": { + "source": "nginx", + "extensions": ["jardiff"] + }, + "application/x-java-jnlp-file": { + "source": "apache", + "compressible": false, + "extensions": ["jnlp"] + }, + "application/x-javascript": { + "compressible": true + }, + "application/x-keepass2": { + "extensions": ["kdbx"] + }, + "application/x-latex": { + "source": "apache", + "compressible": false, + "extensions": ["latex"] + }, + "application/x-lua-bytecode": { + "extensions": ["luac"] + }, + "application/x-lzh-compressed": { + "source": "apache", + "extensions": ["lzh","lha"] + }, + "application/x-makeself": { + "source": "nginx", + "extensions": ["run"] + }, + "application/x-mie": { + "source": "apache", + "extensions": ["mie"] + }, + "application/x-mobipocket-ebook": { + "source": "apache", + "extensions": ["prc","mobi"] + }, + "application/x-mpegurl": { + "compressible": false + }, + "application/x-ms-application": { + "source": "apache", + "extensions": ["application"] + }, + "application/x-ms-shortcut": { + "source": "apache", + "extensions": ["lnk"] + }, + "application/x-ms-wmd": { + "source": "apache", + "extensions": ["wmd"] + }, + "application/x-ms-wmz": { + "source": "apache", + "extensions": ["wmz"] + }, + "application/x-ms-xbap": { + "source": "apache", + "extensions": ["xbap"] + }, + "application/x-msaccess": { + "source": "apache", + "extensions": ["mdb"] + }, + "application/x-msbinder": { + "source": "apache", + "extensions": ["obd"] + }, + "application/x-mscardfile": { + "source": "apache", + "extensions": ["crd"] + }, + "application/x-msclip": { + "source": "apache", + "extensions": ["clp"] + }, + "application/x-msdos-program": { + "extensions": ["exe"] + }, + "application/x-msdownload": { + "source": "apache", + "extensions": ["exe","dll","com","bat","msi"] + }, + "application/x-msmediaview": { + "source": "apache", + "extensions": ["mvb","m13","m14"] + }, + "application/x-msmetafile": { + "source": "apache", + "extensions": ["wmf","wmz","emf","emz"] + }, + "application/x-msmoney": { + "source": "apache", + "extensions": ["mny"] + }, + "application/x-mspublisher": { + "source": "apache", + "extensions": ["pub"] + }, + "application/x-msschedule": { + "source": "apache", + "extensions": ["scd"] + }, + "application/x-msterminal": { + "source": "apache", + "extensions": ["trm"] + }, + "application/x-mswrite": { + "source": "apache", + "extensions": ["wri"] + }, + "application/x-netcdf": { + "source": "apache", + "extensions": ["nc","cdf"] + }, + "application/x-ns-proxy-autoconfig": { + "compressible": true, + "extensions": ["pac"] + }, + "application/x-nzb": { + "source": "apache", + "extensions": ["nzb"] + }, + "application/x-perl": { + "source": "nginx", + "extensions": ["pl","pm"] + }, + "application/x-pilot": { + "source": "nginx", + "extensions": ["prc","pdb"] + }, + "application/x-pkcs12": { + "source": "apache", + "compressible": false, + "extensions": ["p12","pfx"] + }, + "application/x-pkcs7-certificates": { + "source": "apache", + "extensions": ["p7b","spc"] + }, + "application/x-pkcs7-certreqresp": { + "source": "apache", + "extensions": ["p7r"] + }, + "application/x-pki-message": { + "source": "iana" + }, + "application/x-rar-compressed": { + "source": "apache", + "compressible": false, + "extensions": ["rar"] + }, + "application/x-redhat-package-manager": { + "source": "nginx", + "extensions": ["rpm"] + }, + "application/x-research-info-systems": { + "source": "apache", + "extensions": ["ris"] + }, + "application/x-sea": { + "source": "nginx", + "extensions": ["sea"] + }, + "application/x-sh": { + "source": "apache", + "compressible": true, + "extensions": ["sh"] + }, + "application/x-shar": { + "source": "apache", + "extensions": ["shar"] + }, + "application/x-shockwave-flash": { + "source": "apache", + "compressible": false, + "extensions": ["swf"] + }, + "application/x-silverlight-app": { + "source": "apache", + "extensions": ["xap"] + }, + "application/x-sql": { + "source": "apache", + "extensions": ["sql"] + }, + "application/x-stuffit": { + "source": "apache", + "compressible": false, + "extensions": ["sit"] + }, + "application/x-stuffitx": { + "source": "apache", + "extensions": ["sitx"] + }, + "application/x-subrip": { + "source": "apache", + "extensions": ["srt"] + }, + "application/x-sv4cpio": { + "source": "apache", + "extensions": ["sv4cpio"] + }, + "application/x-sv4crc": { + "source": "apache", + "extensions": ["sv4crc"] + }, + "application/x-t3vm-image": { + "source": "apache", + "extensions": ["t3"] + }, + "application/x-tads": { + "source": "apache", + "extensions": ["gam"] + }, + "application/x-tar": { + "source": "apache", + "compressible": true, + "extensions": ["tar"] + }, + "application/x-tcl": { + "source": "apache", + "extensions": ["tcl","tk"] + }, + "application/x-tex": { + "source": "apache", + "extensions": ["tex"] + }, + "application/x-tex-tfm": { + "source": "apache", + "extensions": ["tfm"] + }, + "application/x-texinfo": { + "source": "apache", + "extensions": ["texinfo","texi"] + }, + "application/x-tgif": { + "source": "apache", + "extensions": ["obj"] + }, + "application/x-ustar": { + "source": "apache", + "extensions": ["ustar"] + }, + "application/x-virtualbox-hdd": { + "compressible": true, + "extensions": ["hdd"] + }, + "application/x-virtualbox-ova": { + "compressible": true, + "extensions": ["ova"] + }, + "application/x-virtualbox-ovf": { + "compressible": true, + "extensions": ["ovf"] + }, + "application/x-virtualbox-vbox": { + "compressible": true, + "extensions": ["vbox"] + }, + "application/x-virtualbox-vbox-extpack": { + "compressible": false, + "extensions": ["vbox-extpack"] + }, + "application/x-virtualbox-vdi": { + "compressible": true, + "extensions": ["vdi"] + }, + "application/x-virtualbox-vhd": { + "compressible": true, + "extensions": ["vhd"] + }, + "application/x-virtualbox-vmdk": { + "compressible": true, + "extensions": ["vmdk"] + }, + "application/x-wais-source": { + "source": "apache", + "extensions": ["src"] + }, + "application/x-web-app-manifest+json": { + "compressible": true, + "extensions": ["webapp"] + }, + "application/x-www-form-urlencoded": { + "source": "iana", + "compressible": true + }, + "application/x-x509-ca-cert": { + "source": "iana", + "extensions": ["der","crt","pem"] + }, + "application/x-x509-ca-ra-cert": { + "source": "iana" + }, + "application/x-x509-next-ca-cert": { + "source": "iana" + }, + "application/x-xfig": { + "source": "apache", + "extensions": ["fig"] + }, + "application/x-xliff+xml": { + "source": "apache", + "compressible": true, + "extensions": ["xlf"] + }, + "application/x-xpinstall": { + "source": "apache", + "compressible": false, + "extensions": ["xpi"] + }, + "application/x-xz": { + "source": "apache", + "extensions": ["xz"] + }, + "application/x-zmachine": { + "source": "apache", + "extensions": ["z1","z2","z3","z4","z5","z6","z7","z8"] + }, + "application/x400-bp": { + "source": "iana" + }, + "application/xacml+xml": { + "source": "iana", + "compressible": true + }, + "application/xaml+xml": { + "source": "apache", + "compressible": true, + "extensions": ["xaml"] + }, + "application/xcap-att+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xav"] + }, + "application/xcap-caps+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xca"] + }, + "application/xcap-diff+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xdf"] + }, + "application/xcap-el+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xel"] + }, + "application/xcap-error+xml": { + "source": "iana", + "compressible": true + }, + "application/xcap-ns+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xns"] + }, + "application/xcon-conference-info+xml": { + "source": "iana", + "compressible": true + }, + "application/xcon-conference-info-diff+xml": { + "source": "iana", + "compressible": true + }, + "application/xenc+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xenc"] + }, + "application/xhtml+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xhtml","xht"] + }, + "application/xhtml-voice+xml": { + "source": "apache", + "compressible": true + }, + "application/xliff+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xlf"] + }, + "application/xml": { + "source": "iana", + "compressible": true, + "extensions": ["xml","xsl","xsd","rng"] + }, + "application/xml-dtd": { + "source": "iana", + "compressible": true, + "extensions": ["dtd"] + }, + "application/xml-external-parsed-entity": { + "source": "iana" + }, + "application/xml-patch+xml": { + "source": "iana", + "compressible": true + }, + "application/xmpp+xml": { + "source": "iana", + "compressible": true + }, + "application/xop+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xop"] + }, + "application/xproc+xml": { + "source": "apache", + "compressible": true, + "extensions": ["xpl"] + }, + "application/xslt+xml": { + "source": "iana", + "compressible": true, + "extensions": ["xsl","xslt"] + }, + "application/xspf+xml": { + "source": "apache", + "compressible": true, + "extensions": ["xspf"] + }, + "application/xv+xml": { + "source": "iana", + "compressible": true, + "extensions": ["mxml","xhvml","xvml","xvm"] + }, + "application/yang": { + "source": "iana", + "extensions": ["yang"] + }, + "application/yang-data+json": { + "source": "iana", + "compressible": true + }, + "application/yang-data+xml": { + "source": "iana", + "compressible": true + }, + "application/yang-patch+json": { + "source": "iana", + "compressible": true + }, + "application/yang-patch+xml": { + "source": "iana", + "compressible": true + }, + "application/yin+xml": { + "source": "iana", + "compressible": true, + "extensions": ["yin"] + }, + "application/zip": { + "source": "iana", + "compressible": false, + "extensions": ["zip"] + }, + "application/zlib": { + "source": "iana" + }, + "application/zstd": { + "source": "iana" + }, + "audio/1d-interleaved-parityfec": { + "source": "iana" + }, + "audio/32kadpcm": { + "source": "iana" + }, + "audio/3gpp": { + "source": "iana", + "compressible": false, + "extensions": ["3gpp"] + }, + "audio/3gpp2": { + "source": "iana" + }, + "audio/aac": { + "source": "iana" + }, + "audio/ac3": { + "source": "iana" + }, + "audio/adpcm": { + "source": "apache", + "extensions": ["adp"] + }, + "audio/amr": { + "source": "iana", + "extensions": ["amr"] + }, + "audio/amr-wb": { + "source": "iana" + }, + "audio/amr-wb+": { + "source": "iana" + }, + "audio/aptx": { + "source": "iana" + }, + "audio/asc": { + "source": "iana" + }, + "audio/atrac-advanced-lossless": { + "source": "iana" + }, + "audio/atrac-x": { + "source": "iana" + }, + "audio/atrac3": { + "source": "iana" + }, + "audio/basic": { + "source": "iana", + "compressible": false, + "extensions": ["au","snd"] + }, + "audio/bv16": { + "source": "iana" + }, + "audio/bv32": { + "source": "iana" + }, + "audio/clearmode": { + "source": "iana" + }, + "audio/cn": { + "source": "iana" + }, + "audio/dat12": { + "source": "iana" + }, + "audio/dls": { + "source": "iana" + }, + "audio/dsr-es201108": { + "source": "iana" + }, + "audio/dsr-es202050": { + "source": "iana" + }, + "audio/dsr-es202211": { + "source": "iana" + }, + "audio/dsr-es202212": { + "source": "iana" + }, + "audio/dv": { + "source": "iana" + }, + "audio/dvi4": { + "source": "iana" + }, + "audio/eac3": { + "source": "iana" + }, + "audio/encaprtp": { + "source": "iana" + }, + "audio/evrc": { + "source": "iana" + }, + "audio/evrc-qcp": { + "source": "iana" + }, + "audio/evrc0": { + "source": "iana" + }, + "audio/evrc1": { + "source": "iana" + }, + "audio/evrcb": { + "source": "iana" + }, + "audio/evrcb0": { + "source": "iana" + }, + "audio/evrcb1": { + "source": "iana" + }, + "audio/evrcnw": { + "source": "iana" + }, + "audio/evrcnw0": { + "source": "iana" + }, + "audio/evrcnw1": { + "source": "iana" + }, + "audio/evrcwb": { + "source": "iana" + }, + "audio/evrcwb0": { + "source": "iana" + }, + "audio/evrcwb1": { + "source": "iana" + }, + "audio/evs": { + "source": "iana" + }, + "audio/flexfec": { + "source": "iana" + }, + "audio/fwdred": { + "source": "iana" + }, + "audio/g711-0": { + "source": "iana" + }, + "audio/g719": { + "source": "iana" + }, + "audio/g722": { + "source": "iana" + }, + "audio/g7221": { + "source": "iana" + }, + "audio/g723": { + "source": "iana" + }, + "audio/g726-16": { + "source": "iana" + }, + "audio/g726-24": { + "source": "iana" + }, + "audio/g726-32": { + "source": "iana" + }, + "audio/g726-40": { + "source": "iana" + }, + "audio/g728": { + "source": "iana" + }, + "audio/g729": { + "source": "iana" + }, + "audio/g7291": { + "source": "iana" + }, + "audio/g729d": { + "source": "iana" + }, + "audio/g729e": { + "source": "iana" + }, + "audio/gsm": { + "source": "iana" + }, + "audio/gsm-efr": { + "source": "iana" + }, + "audio/gsm-hr-08": { + "source": "iana" + }, + "audio/ilbc": { + "source": "iana" + }, + "audio/ip-mr_v2.5": { + "source": "iana" + }, + "audio/isac": { + "source": "apache" + }, + "audio/l16": { + "source": "iana" + }, + "audio/l20": { + "source": "iana" + }, + "audio/l24": { + "source": "iana", + "compressible": false + }, + "audio/l8": { + "source": "iana" + }, + "audio/lpc": { + "source": "iana" + }, + "audio/melp": { + "source": "iana" + }, + "audio/melp1200": { + "source": "iana" + }, + "audio/melp2400": { + "source": "iana" + }, + "audio/melp600": { + "source": "iana" + }, + "audio/mhas": { + "source": "iana" + }, + "audio/midi": { + "source": "apache", + "extensions": ["mid","midi","kar","rmi"] + }, + "audio/mobile-xmf": { + "source": "iana", + "extensions": ["mxmf"] + }, + "audio/mp3": { + "compressible": false, + "extensions": ["mp3"] + }, + "audio/mp4": { + "source": "iana", + "compressible": false, + "extensions": ["m4a","mp4a"] + }, + "audio/mp4a-latm": { + "source": "iana" + }, + "audio/mpa": { + "source": "iana" + }, + "audio/mpa-robust": { + "source": "iana" + }, + "audio/mpeg": { + "source": "iana", + "compressible": false, + "extensions": ["mpga","mp2","mp2a","mp3","m2a","m3a"] + }, + "audio/mpeg4-generic": { + "source": "iana" + }, + "audio/musepack": { + "source": "apache" + }, + "audio/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["oga","ogg","spx","opus"] + }, + "audio/opus": { + "source": "iana" + }, + "audio/parityfec": { + "source": "iana" + }, + "audio/pcma": { + "source": "iana" + }, + "audio/pcma-wb": { + "source": "iana" + }, + "audio/pcmu": { + "source": "iana" + }, + "audio/pcmu-wb": { + "source": "iana" + }, + "audio/prs.sid": { + "source": "iana" + }, + "audio/qcelp": { + "source": "iana" + }, + "audio/raptorfec": { + "source": "iana" + }, + "audio/red": { + "source": "iana" + }, + "audio/rtp-enc-aescm128": { + "source": "iana" + }, + "audio/rtp-midi": { + "source": "iana" + }, + "audio/rtploopback": { + "source": "iana" + }, + "audio/rtx": { + "source": "iana" + }, + "audio/s3m": { + "source": "apache", + "extensions": ["s3m"] + }, + "audio/scip": { + "source": "iana" + }, + "audio/silk": { + "source": "apache", + "extensions": ["sil"] + }, + "audio/smv": { + "source": "iana" + }, + "audio/smv-qcp": { + "source": "iana" + }, + "audio/smv0": { + "source": "iana" + }, + "audio/sofa": { + "source": "iana" + }, + "audio/sp-midi": { + "source": "iana" + }, + "audio/speex": { + "source": "iana" + }, + "audio/t140c": { + "source": "iana" + }, + "audio/t38": { + "source": "iana" + }, + "audio/telephone-event": { + "source": "iana" + }, + "audio/tetra_acelp": { + "source": "iana" + }, + "audio/tetra_acelp_bb": { + "source": "iana" + }, + "audio/tone": { + "source": "iana" + }, + "audio/tsvcis": { + "source": "iana" + }, + "audio/uemclip": { + "source": "iana" + }, + "audio/ulpfec": { + "source": "iana" + }, + "audio/usac": { + "source": "iana" + }, + "audio/vdvi": { + "source": "iana" + }, + "audio/vmr-wb": { + "source": "iana" + }, + "audio/vnd.3gpp.iufp": { + "source": "iana" + }, + "audio/vnd.4sb": { + "source": "iana" + }, + "audio/vnd.audiokoz": { + "source": "iana" + }, + "audio/vnd.celp": { + "source": "iana" + }, + "audio/vnd.cisco.nse": { + "source": "iana" + }, + "audio/vnd.cmles.radio-events": { + "source": "iana" + }, + "audio/vnd.cns.anp1": { + "source": "iana" + }, + "audio/vnd.cns.inf1": { + "source": "iana" + }, + "audio/vnd.dece.audio": { + "source": "iana", + "extensions": ["uva","uvva"] + }, + "audio/vnd.digital-winds": { + "source": "iana", + "extensions": ["eol"] + }, + "audio/vnd.dlna.adts": { + "source": "iana" + }, + "audio/vnd.dolby.heaac.1": { + "source": "iana" + }, + "audio/vnd.dolby.heaac.2": { + "source": "iana" + }, + "audio/vnd.dolby.mlp": { + "source": "iana" + }, + "audio/vnd.dolby.mps": { + "source": "iana" + }, + "audio/vnd.dolby.pl2": { + "source": "iana" + }, + "audio/vnd.dolby.pl2x": { + "source": "iana" + }, + "audio/vnd.dolby.pl2z": { + "source": "iana" + }, + "audio/vnd.dolby.pulse.1": { + "source": "iana" + }, + "audio/vnd.dra": { + "source": "iana", + "extensions": ["dra"] + }, + "audio/vnd.dts": { + "source": "iana", + "extensions": ["dts"] + }, + "audio/vnd.dts.hd": { + "source": "iana", + "extensions": ["dtshd"] + }, + "audio/vnd.dts.uhd": { + "source": "iana" + }, + "audio/vnd.dvb.file": { + "source": "iana" + }, + "audio/vnd.everad.plj": { + "source": "iana" + }, + "audio/vnd.hns.audio": { + "source": "iana" + }, + "audio/vnd.lucent.voice": { + "source": "iana", + "extensions": ["lvp"] + }, + "audio/vnd.ms-playready.media.pya": { + "source": "iana", + "extensions": ["pya"] + }, + "audio/vnd.nokia.mobile-xmf": { + "source": "iana" + }, + "audio/vnd.nortel.vbk": { + "source": "iana" + }, + "audio/vnd.nuera.ecelp4800": { + "source": "iana", + "extensions": ["ecelp4800"] + }, + "audio/vnd.nuera.ecelp7470": { + "source": "iana", + "extensions": ["ecelp7470"] + }, + "audio/vnd.nuera.ecelp9600": { + "source": "iana", + "extensions": ["ecelp9600"] + }, + "audio/vnd.octel.sbc": { + "source": "iana" + }, + "audio/vnd.presonus.multitrack": { + "source": "iana" + }, + "audio/vnd.qcelp": { + "source": "iana" + }, + "audio/vnd.rhetorex.32kadpcm": { + "source": "iana" + }, + "audio/vnd.rip": { + "source": "iana", + "extensions": ["rip"] + }, + "audio/vnd.rn-realaudio": { + "compressible": false + }, + "audio/vnd.sealedmedia.softseal.mpeg": { + "source": "iana" + }, + "audio/vnd.vmx.cvsd": { + "source": "iana" + }, + "audio/vnd.wave": { + "compressible": false + }, + "audio/vorbis": { + "source": "iana", + "compressible": false + }, + "audio/vorbis-config": { + "source": "iana" + }, + "audio/wav": { + "compressible": false, + "extensions": ["wav"] + }, + "audio/wave": { + "compressible": false, + "extensions": ["wav"] + }, + "audio/webm": { + "source": "apache", + "compressible": false, + "extensions": ["weba"] + }, + "audio/x-aac": { + "source": "apache", + "compressible": false, + "extensions": ["aac"] + }, + "audio/x-aiff": { + "source": "apache", + "extensions": ["aif","aiff","aifc"] + }, + "audio/x-caf": { + "source": "apache", + "compressible": false, + "extensions": ["caf"] + }, + "audio/x-flac": { + "source": "apache", + "extensions": ["flac"] + }, + "audio/x-m4a": { + "source": "nginx", + "extensions": ["m4a"] + }, + "audio/x-matroska": { + "source": "apache", + "extensions": ["mka"] + }, + "audio/x-mpegurl": { + "source": "apache", + "extensions": ["m3u"] + }, + "audio/x-ms-wax": { + "source": "apache", + "extensions": ["wax"] + }, + "audio/x-ms-wma": { + "source": "apache", + "extensions": ["wma"] + }, + "audio/x-pn-realaudio": { + "source": "apache", + "extensions": ["ram","ra"] + }, + "audio/x-pn-realaudio-plugin": { + "source": "apache", + "extensions": ["rmp"] + }, + "audio/x-realaudio": { + "source": "nginx", + "extensions": ["ra"] + }, + "audio/x-tta": { + "source": "apache" + }, + "audio/x-wav": { + "source": "apache", + "extensions": ["wav"] + }, + "audio/xm": { + "source": "apache", + "extensions": ["xm"] + }, + "chemical/x-cdx": { + "source": "apache", + "extensions": ["cdx"] + }, + "chemical/x-cif": { + "source": "apache", + "extensions": ["cif"] + }, + "chemical/x-cmdf": { + "source": "apache", + "extensions": ["cmdf"] + }, + "chemical/x-cml": { + "source": "apache", + "extensions": ["cml"] + }, + "chemical/x-csml": { + "source": "apache", + "extensions": ["csml"] + }, + "chemical/x-pdb": { + "source": "apache" + }, + "chemical/x-xyz": { + "source": "apache", + "extensions": ["xyz"] + }, + "font/collection": { + "source": "iana", + "extensions": ["ttc"] + }, + "font/otf": { + "source": "iana", + "compressible": true, + "extensions": ["otf"] + }, + "font/sfnt": { + "source": "iana" + }, + "font/ttf": { + "source": "iana", + "compressible": true, + "extensions": ["ttf"] + }, + "font/woff": { + "source": "iana", + "extensions": ["woff"] + }, + "font/woff2": { + "source": "iana", + "extensions": ["woff2"] + }, + "image/aces": { + "source": "iana", + "extensions": ["exr"] + }, + "image/apng": { + "compressible": false, + "extensions": ["apng"] + }, + "image/avci": { + "source": "iana", + "extensions": ["avci"] + }, + "image/avcs": { + "source": "iana", + "extensions": ["avcs"] + }, + "image/avif": { + "source": "iana", + "compressible": false, + "extensions": ["avif"] + }, + "image/bmp": { + "source": "iana", + "compressible": true, + "extensions": ["bmp"] + }, + "image/cgm": { + "source": "iana", + "extensions": ["cgm"] + }, + "image/dicom-rle": { + "source": "iana", + "extensions": ["drle"] + }, + "image/emf": { + "source": "iana", + "extensions": ["emf"] + }, + "image/fits": { + "source": "iana", + "extensions": ["fits"] + }, + "image/g3fax": { + "source": "iana", + "extensions": ["g3"] + }, + "image/gif": { + "source": "iana", + "compressible": false, + "extensions": ["gif"] + }, + "image/heic": { + "source": "iana", + "extensions": ["heic"] + }, + "image/heic-sequence": { + "source": "iana", + "extensions": ["heics"] + }, + "image/heif": { + "source": "iana", + "extensions": ["heif"] + }, + "image/heif-sequence": { + "source": "iana", + "extensions": ["heifs"] + }, + "image/hej2k": { + "source": "iana", + "extensions": ["hej2"] + }, + "image/hsj2": { + "source": "iana", + "extensions": ["hsj2"] + }, + "image/ief": { + "source": "iana", + "extensions": ["ief"] + }, + "image/jls": { + "source": "iana", + "extensions": ["jls"] + }, + "image/jp2": { + "source": "iana", + "compressible": false, + "extensions": ["jp2","jpg2"] + }, + "image/jpeg": { + "source": "iana", + "compressible": false, + "extensions": ["jpeg","jpg","jpe"] + }, + "image/jph": { + "source": "iana", + "extensions": ["jph"] + }, + "image/jphc": { + "source": "iana", + "extensions": ["jhc"] + }, + "image/jpm": { + "source": "iana", + "compressible": false, + "extensions": ["jpm"] + }, + "image/jpx": { + "source": "iana", + "compressible": false, + "extensions": ["jpx","jpf"] + }, + "image/jxr": { + "source": "iana", + "extensions": ["jxr"] + }, + "image/jxra": { + "source": "iana", + "extensions": ["jxra"] + }, + "image/jxrs": { + "source": "iana", + "extensions": ["jxrs"] + }, + "image/jxs": { + "source": "iana", + "extensions": ["jxs"] + }, + "image/jxsc": { + "source": "iana", + "extensions": ["jxsc"] + }, + "image/jxsi": { + "source": "iana", + "extensions": ["jxsi"] + }, + "image/jxss": { + "source": "iana", + "extensions": ["jxss"] + }, + "image/ktx": { + "source": "iana", + "extensions": ["ktx"] + }, + "image/ktx2": { + "source": "iana", + "extensions": ["ktx2"] + }, + "image/naplps": { + "source": "iana" + }, + "image/pjpeg": { + "compressible": false + }, + "image/png": { + "source": "iana", + "compressible": false, + "extensions": ["png"] + }, + "image/prs.btif": { + "source": "iana", + "extensions": ["btif"] + }, + "image/prs.pti": { + "source": "iana", + "extensions": ["pti"] + }, + "image/pwg-raster": { + "source": "iana" + }, + "image/sgi": { + "source": "apache", + "extensions": ["sgi"] + }, + "image/svg+xml": { + "source": "iana", + "compressible": true, + "extensions": ["svg","svgz"] + }, + "image/t38": { + "source": "iana", + "extensions": ["t38"] + }, + "image/tiff": { + "source": "iana", + "compressible": false, + "extensions": ["tif","tiff"] + }, + "image/tiff-fx": { + "source": "iana", + "extensions": ["tfx"] + }, + "image/vnd.adobe.photoshop": { + "source": "iana", + "compressible": true, + "extensions": ["psd"] + }, + "image/vnd.airzip.accelerator.azv": { + "source": "iana", + "extensions": ["azv"] + }, + "image/vnd.cns.inf2": { + "source": "iana" + }, + "image/vnd.dece.graphic": { + "source": "iana", + "extensions": ["uvi","uvvi","uvg","uvvg"] + }, + "image/vnd.djvu": { + "source": "iana", + "extensions": ["djvu","djv"] + }, + "image/vnd.dvb.subtitle": { + "source": "iana", + "extensions": ["sub"] + }, + "image/vnd.dwg": { + "source": "iana", + "extensions": ["dwg"] + }, + "image/vnd.dxf": { + "source": "iana", + "extensions": ["dxf"] + }, + "image/vnd.fastbidsheet": { + "source": "iana", + "extensions": ["fbs"] + }, + "image/vnd.fpx": { + "source": "iana", + "extensions": ["fpx"] + }, + "image/vnd.fst": { + "source": "iana", + "extensions": ["fst"] + }, + "image/vnd.fujixerox.edmics-mmr": { + "source": "iana", + "extensions": ["mmr"] + }, + "image/vnd.fujixerox.edmics-rlc": { + "source": "iana", + "extensions": ["rlc"] + }, + "image/vnd.globalgraphics.pgb": { + "source": "iana" + }, + "image/vnd.microsoft.icon": { + "source": "iana", + "compressible": true, + "extensions": ["ico"] + }, + "image/vnd.mix": { + "source": "iana" + }, + "image/vnd.mozilla.apng": { + "source": "iana" + }, + "image/vnd.ms-dds": { + "compressible": true, + "extensions": ["dds"] + }, + "image/vnd.ms-modi": { + "source": "iana", + "extensions": ["mdi"] + }, + "image/vnd.ms-photo": { + "source": "apache", + "extensions": ["wdp"] + }, + "image/vnd.net-fpx": { + "source": "iana", + "extensions": ["npx"] + }, + "image/vnd.pco.b16": { + "source": "iana", + "extensions": ["b16"] + }, + "image/vnd.radiance": { + "source": "iana" + }, + "image/vnd.sealed.png": { + "source": "iana" + }, + "image/vnd.sealedmedia.softseal.gif": { + "source": "iana" + }, + "image/vnd.sealedmedia.softseal.jpg": { + "source": "iana" + }, + "image/vnd.svf": { + "source": "iana" + }, + "image/vnd.tencent.tap": { + "source": "iana", + "extensions": ["tap"] + }, + "image/vnd.valve.source.texture": { + "source": "iana", + "extensions": ["vtf"] + }, + "image/vnd.wap.wbmp": { + "source": "iana", + "extensions": ["wbmp"] + }, + "image/vnd.xiff": { + "source": "iana", + "extensions": ["xif"] + }, + "image/vnd.zbrush.pcx": { + "source": "iana", + "extensions": ["pcx"] + }, + "image/webp": { + "source": "apache", + "extensions": ["webp"] + }, + "image/wmf": { + "source": "iana", + "extensions": ["wmf"] + }, + "image/x-3ds": { + "source": "apache", + "extensions": ["3ds"] + }, + "image/x-cmu-raster": { + "source": "apache", + "extensions": ["ras"] + }, + "image/x-cmx": { + "source": "apache", + "extensions": ["cmx"] + }, + "image/x-freehand": { + "source": "apache", + "extensions": ["fh","fhc","fh4","fh5","fh7"] + }, + "image/x-icon": { + "source": "apache", + "compressible": true, + "extensions": ["ico"] + }, + "image/x-jng": { + "source": "nginx", + "extensions": ["jng"] + }, + "image/x-mrsid-image": { + "source": "apache", + "extensions": ["sid"] + }, + "image/x-ms-bmp": { + "source": "nginx", + "compressible": true, + "extensions": ["bmp"] + }, + "image/x-pcx": { + "source": "apache", + "extensions": ["pcx"] + }, + "image/x-pict": { + "source": "apache", + "extensions": ["pic","pct"] + }, + "image/x-portable-anymap": { + "source": "apache", + "extensions": ["pnm"] + }, + "image/x-portable-bitmap": { + "source": "apache", + "extensions": ["pbm"] + }, + "image/x-portable-graymap": { + "source": "apache", + "extensions": ["pgm"] + }, + "image/x-portable-pixmap": { + "source": "apache", + "extensions": ["ppm"] + }, + "image/x-rgb": { + "source": "apache", + "extensions": ["rgb"] + }, + "image/x-tga": { + "source": "apache", + "extensions": ["tga"] + }, + "image/x-xbitmap": { + "source": "apache", + "extensions": ["xbm"] + }, + "image/x-xcf": { + "compressible": false + }, + "image/x-xpixmap": { + "source": "apache", + "extensions": ["xpm"] + }, + "image/x-xwindowdump": { + "source": "apache", + "extensions": ["xwd"] + }, + "message/cpim": { + "source": "iana" + }, + "message/delivery-status": { + "source": "iana" + }, + "message/disposition-notification": { + "source": "iana", + "extensions": [ + "disposition-notification" + ] + }, + "message/external-body": { + "source": "iana" + }, + "message/feedback-report": { + "source": "iana" + }, + "message/global": { + "source": "iana", + "extensions": ["u8msg"] + }, + "message/global-delivery-status": { + "source": "iana", + "extensions": ["u8dsn"] + }, + "message/global-disposition-notification": { + "source": "iana", + "extensions": ["u8mdn"] + }, + "message/global-headers": { + "source": "iana", + "extensions": ["u8hdr"] + }, + "message/http": { + "source": "iana", + "compressible": false + }, + "message/imdn+xml": { + "source": "iana", + "compressible": true + }, + "message/news": { + "source": "iana" + }, + "message/partial": { + "source": "iana", + "compressible": false + }, + "message/rfc822": { + "source": "iana", + "compressible": true, + "extensions": ["eml","mime"] + }, + "message/s-http": { + "source": "iana" + }, + "message/sip": { + "source": "iana" + }, + "message/sipfrag": { + "source": "iana" + }, + "message/tracking-status": { + "source": "iana" + }, + "message/vnd.si.simp": { + "source": "iana" + }, + "message/vnd.wfa.wsc": { + "source": "iana", + "extensions": ["wsc"] + }, + "model/3mf": { + "source": "iana", + "extensions": ["3mf"] + }, + "model/e57": { + "source": "iana" + }, + "model/gltf+json": { + "source": "iana", + "compressible": true, + "extensions": ["gltf"] + }, + "model/gltf-binary": { + "source": "iana", + "compressible": true, + "extensions": ["glb"] + }, + "model/iges": { + "source": "iana", + "compressible": false, + "extensions": ["igs","iges"] + }, + "model/mesh": { + "source": "iana", + "compressible": false, + "extensions": ["msh","mesh","silo"] + }, + "model/mtl": { + "source": "iana", + "extensions": ["mtl"] + }, + "model/obj": { + "source": "iana", + "extensions": ["obj"] + }, + "model/step": { + "source": "iana" + }, + "model/step+xml": { + "source": "iana", + "compressible": true, + "extensions": ["stpx"] + }, + "model/step+zip": { + "source": "iana", + "compressible": false, + "extensions": ["stpz"] + }, + "model/step-xml+zip": { + "source": "iana", + "compressible": false, + "extensions": ["stpxz"] + }, + "model/stl": { + "source": "iana", + "extensions": ["stl"] + }, + "model/vnd.collada+xml": { + "source": "iana", + "compressible": true, + "extensions": ["dae"] + }, + "model/vnd.dwf": { + "source": "iana", + "extensions": ["dwf"] + }, + "model/vnd.flatland.3dml": { + "source": "iana" + }, + "model/vnd.gdl": { + "source": "iana", + "extensions": ["gdl"] + }, + "model/vnd.gs-gdl": { + "source": "apache" + }, + "model/vnd.gs.gdl": { + "source": "iana" + }, + "model/vnd.gtw": { + "source": "iana", + "extensions": ["gtw"] + }, + "model/vnd.moml+xml": { + "source": "iana", + "compressible": true + }, + "model/vnd.mts": { + "source": "iana", + "extensions": ["mts"] + }, + "model/vnd.opengex": { + "source": "iana", + "extensions": ["ogex"] + }, + "model/vnd.parasolid.transmit.binary": { + "source": "iana", + "extensions": ["x_b"] + }, + "model/vnd.parasolid.transmit.text": { + "source": "iana", + "extensions": ["x_t"] + }, + "model/vnd.pytha.pyox": { + "source": "iana" + }, + "model/vnd.rosette.annotated-data-model": { + "source": "iana" + }, + "model/vnd.sap.vds": { + "source": "iana", + "extensions": ["vds"] + }, + "model/vnd.usdz+zip": { + "source": "iana", + "compressible": false, + "extensions": ["usdz"] + }, + "model/vnd.valve.source.compiled-map": { + "source": "iana", + "extensions": ["bsp"] + }, + "model/vnd.vtu": { + "source": "iana", + "extensions": ["vtu"] + }, + "model/vrml": { + "source": "iana", + "compressible": false, + "extensions": ["wrl","vrml"] + }, + "model/x3d+binary": { + "source": "apache", + "compressible": false, + "extensions": ["x3db","x3dbz"] + }, + "model/x3d+fastinfoset": { + "source": "iana", + "extensions": ["x3db"] + }, + "model/x3d+vrml": { + "source": "apache", + "compressible": false, + "extensions": ["x3dv","x3dvz"] + }, + "model/x3d+xml": { + "source": "iana", + "compressible": true, + "extensions": ["x3d","x3dz"] + }, + "model/x3d-vrml": { + "source": "iana", + "extensions": ["x3dv"] + }, + "multipart/alternative": { + "source": "iana", + "compressible": false + }, + "multipart/appledouble": { + "source": "iana" + }, + "multipart/byteranges": { + "source": "iana" + }, + "multipart/digest": { + "source": "iana" + }, + "multipart/encrypted": { + "source": "iana", + "compressible": false + }, + "multipart/form-data": { + "source": "iana", + "compressible": false + }, + "multipart/header-set": { + "source": "iana" + }, + "multipart/mixed": { + "source": "iana" + }, + "multipart/multilingual": { + "source": "iana" + }, + "multipart/parallel": { + "source": "iana" + }, + "multipart/related": { + "source": "iana", + "compressible": false + }, + "multipart/report": { + "source": "iana" + }, + "multipart/signed": { + "source": "iana", + "compressible": false + }, + "multipart/vnd.bint.med-plus": { + "source": "iana" + }, + "multipart/voice-message": { + "source": "iana" + }, + "multipart/x-mixed-replace": { + "source": "iana" + }, + "text/1d-interleaved-parityfec": { + "source": "iana" + }, + "text/cache-manifest": { + "source": "iana", + "compressible": true, + "extensions": ["appcache","manifest"] + }, + "text/calendar": { + "source": "iana", + "extensions": ["ics","ifb"] + }, + "text/calender": { + "compressible": true + }, + "text/cmd": { + "compressible": true + }, + "text/coffeescript": { + "extensions": ["coffee","litcoffee"] + }, + "text/cql": { + "source": "iana" + }, + "text/cql-expression": { + "source": "iana" + }, + "text/cql-identifier": { + "source": "iana" + }, + "text/css": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["css"] + }, + "text/csv": { + "source": "iana", + "compressible": true, + "extensions": ["csv"] + }, + "text/csv-schema": { + "source": "iana" + }, + "text/directory": { + "source": "iana" + }, + "text/dns": { + "source": "iana" + }, + "text/ecmascript": { + "source": "iana" + }, + "text/encaprtp": { + "source": "iana" + }, + "text/enriched": { + "source": "iana" + }, + "text/fhirpath": { + "source": "iana" + }, + "text/flexfec": { + "source": "iana" + }, + "text/fwdred": { + "source": "iana" + }, + "text/gff3": { + "source": "iana" + }, + "text/grammar-ref-list": { + "source": "iana" + }, + "text/html": { + "source": "iana", + "compressible": true, + "extensions": ["html","htm","shtml"] + }, + "text/jade": { + "extensions": ["jade"] + }, + "text/javascript": { + "source": "iana", + "compressible": true + }, + "text/jcr-cnd": { + "source": "iana" + }, + "text/jsx": { + "compressible": true, + "extensions": ["jsx"] + }, + "text/less": { + "compressible": true, + "extensions": ["less"] + }, + "text/markdown": { + "source": "iana", + "compressible": true, + "extensions": ["markdown","md"] + }, + "text/mathml": { + "source": "nginx", + "extensions": ["mml"] + }, + "text/mdx": { + "compressible": true, + "extensions": ["mdx"] + }, + "text/mizar": { + "source": "iana" + }, + "text/n3": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["n3"] + }, + "text/parameters": { + "source": "iana", + "charset": "UTF-8" + }, + "text/parityfec": { + "source": "iana" + }, + "text/plain": { + "source": "iana", + "compressible": true, + "extensions": ["txt","text","conf","def","list","log","in","ini"] + }, + "text/provenance-notation": { + "source": "iana", + "charset": "UTF-8" + }, + "text/prs.fallenstein.rst": { + "source": "iana" + }, + "text/prs.lines.tag": { + "source": "iana", + "extensions": ["dsc"] + }, + "text/prs.prop.logic": { + "source": "iana" + }, + "text/raptorfec": { + "source": "iana" + }, + "text/red": { + "source": "iana" + }, + "text/rfc822-headers": { + "source": "iana" + }, + "text/richtext": { + "source": "iana", + "compressible": true, + "extensions": ["rtx"] + }, + "text/rtf": { + "source": "iana", + "compressible": true, + "extensions": ["rtf"] + }, + "text/rtp-enc-aescm128": { + "source": "iana" + }, + "text/rtploopback": { + "source": "iana" + }, + "text/rtx": { + "source": "iana" + }, + "text/sgml": { + "source": "iana", + "extensions": ["sgml","sgm"] + }, + "text/shaclc": { + "source": "iana" + }, + "text/shex": { + "source": "iana", + "extensions": ["shex"] + }, + "text/slim": { + "extensions": ["slim","slm"] + }, + "text/spdx": { + "source": "iana", + "extensions": ["spdx"] + }, + "text/strings": { + "source": "iana" + }, + "text/stylus": { + "extensions": ["stylus","styl"] + }, + "text/t140": { + "source": "iana" + }, + "text/tab-separated-values": { + "source": "iana", + "compressible": true, + "extensions": ["tsv"] + }, + "text/troff": { + "source": "iana", + "extensions": ["t","tr","roff","man","me","ms"] + }, + "text/turtle": { + "source": "iana", + "charset": "UTF-8", + "extensions": ["ttl"] + }, + "text/ulpfec": { + "source": "iana" + }, + "text/uri-list": { + "source": "iana", + "compressible": true, + "extensions": ["uri","uris","urls"] + }, + "text/vcard": { + "source": "iana", + "compressible": true, + "extensions": ["vcard"] + }, + "text/vnd.a": { + "source": "iana" + }, + "text/vnd.abc": { + "source": "iana" + }, + "text/vnd.ascii-art": { + "source": "iana" + }, + "text/vnd.curl": { + "source": "iana", + "extensions": ["curl"] + }, + "text/vnd.curl.dcurl": { + "source": "apache", + "extensions": ["dcurl"] + }, + "text/vnd.curl.mcurl": { + "source": "apache", + "extensions": ["mcurl"] + }, + "text/vnd.curl.scurl": { + "source": "apache", + "extensions": ["scurl"] + }, + "text/vnd.debian.copyright": { + "source": "iana", + "charset": "UTF-8" + }, + "text/vnd.dmclientscript": { + "source": "iana" + }, + "text/vnd.dvb.subtitle": { + "source": "iana", + "extensions": ["sub"] + }, + "text/vnd.esmertec.theme-descriptor": { + "source": "iana", + "charset": "UTF-8" + }, + "text/vnd.familysearch.gedcom": { + "source": "iana", + "extensions": ["ged"] + }, + "text/vnd.ficlab.flt": { + "source": "iana" + }, + "text/vnd.fly": { + "source": "iana", + "extensions": ["fly"] + }, + "text/vnd.fmi.flexstor": { + "source": "iana", + "extensions": ["flx"] + }, + "text/vnd.gml": { + "source": "iana" + }, + "text/vnd.graphviz": { + "source": "iana", + "extensions": ["gv"] + }, + "text/vnd.hans": { + "source": "iana" + }, + "text/vnd.hgl": { + "source": "iana" + }, + "text/vnd.in3d.3dml": { + "source": "iana", + "extensions": ["3dml"] + }, + "text/vnd.in3d.spot": { + "source": "iana", + "extensions": ["spot"] + }, + "text/vnd.iptc.newsml": { + "source": "iana" + }, + "text/vnd.iptc.nitf": { + "source": "iana" + }, + "text/vnd.latex-z": { + "source": "iana" + }, + "text/vnd.motorola.reflex": { + "source": "iana" + }, + "text/vnd.ms-mediapackage": { + "source": "iana" + }, + "text/vnd.net2phone.commcenter.command": { + "source": "iana" + }, + "text/vnd.radisys.msml-basic-layout": { + "source": "iana" + }, + "text/vnd.senx.warpscript": { + "source": "iana" + }, + "text/vnd.si.uricatalogue": { + "source": "iana" + }, + "text/vnd.sosi": { + "source": "iana" + }, + "text/vnd.sun.j2me.app-descriptor": { + "source": "iana", + "charset": "UTF-8", + "extensions": ["jad"] + }, + "text/vnd.trolltech.linguist": { + "source": "iana", + "charset": "UTF-8" + }, + "text/vnd.wap.si": { + "source": "iana" + }, + "text/vnd.wap.sl": { + "source": "iana" + }, + "text/vnd.wap.wml": { + "source": "iana", + "extensions": ["wml"] + }, + "text/vnd.wap.wmlscript": { + "source": "iana", + "extensions": ["wmls"] + }, + "text/vtt": { + "source": "iana", + "charset": "UTF-8", + "compressible": true, + "extensions": ["vtt"] + }, + "text/x-asm": { + "source": "apache", + "extensions": ["s","asm"] + }, + "text/x-c": { + "source": "apache", + "extensions": ["c","cc","cxx","cpp","h","hh","dic"] + }, + "text/x-component": { + "source": "nginx", + "extensions": ["htc"] + }, + "text/x-fortran": { + "source": "apache", + "extensions": ["f","for","f77","f90"] + }, + "text/x-gwt-rpc": { + "compressible": true + }, + "text/x-handlebars-template": { + "extensions": ["hbs"] + }, + "text/x-java-source": { + "source": "apache", + "extensions": ["java"] + }, + "text/x-jquery-tmpl": { + "compressible": true + }, + "text/x-lua": { + "extensions": ["lua"] + }, + "text/x-markdown": { + "compressible": true, + "extensions": ["mkd"] + }, + "text/x-nfo": { + "source": "apache", + "extensions": ["nfo"] + }, + "text/x-opml": { + "source": "apache", + "extensions": ["opml"] + }, + "text/x-org": { + "compressible": true, + "extensions": ["org"] + }, + "text/x-pascal": { + "source": "apache", + "extensions": ["p","pas"] + }, + "text/x-processing": { + "compressible": true, + "extensions": ["pde"] + }, + "text/x-sass": { + "extensions": ["sass"] + }, + "text/x-scss": { + "extensions": ["scss"] + }, + "text/x-setext": { + "source": "apache", + "extensions": ["etx"] + }, + "text/x-sfv": { + "source": "apache", + "extensions": ["sfv"] + }, + "text/x-suse-ymp": { + "compressible": true, + "extensions": ["ymp"] + }, + "text/x-uuencode": { + "source": "apache", + "extensions": ["uu"] + }, + "text/x-vcalendar": { + "source": "apache", + "extensions": ["vcs"] + }, + "text/x-vcard": { + "source": "apache", + "extensions": ["vcf"] + }, + "text/xml": { + "source": "iana", + "compressible": true, + "extensions": ["xml"] + }, + "text/xml-external-parsed-entity": { + "source": "iana" + }, + "text/yaml": { + "compressible": true, + "extensions": ["yaml","yml"] + }, + "video/1d-interleaved-parityfec": { + "source": "iana" + }, + "video/3gpp": { + "source": "iana", + "extensions": ["3gp","3gpp"] + }, + "video/3gpp-tt": { + "source": "iana" + }, + "video/3gpp2": { + "source": "iana", + "extensions": ["3g2"] + }, + "video/av1": { + "source": "iana" + }, + "video/bmpeg": { + "source": "iana" + }, + "video/bt656": { + "source": "iana" + }, + "video/celb": { + "source": "iana" + }, + "video/dv": { + "source": "iana" + }, + "video/encaprtp": { + "source": "iana" + }, + "video/ffv1": { + "source": "iana" + }, + "video/flexfec": { + "source": "iana" + }, + "video/h261": { + "source": "iana", + "extensions": ["h261"] + }, + "video/h263": { + "source": "iana", + "extensions": ["h263"] + }, + "video/h263-1998": { + "source": "iana" + }, + "video/h263-2000": { + "source": "iana" + }, + "video/h264": { + "source": "iana", + "extensions": ["h264"] + }, + "video/h264-rcdo": { + "source": "iana" + }, + "video/h264-svc": { + "source": "iana" + }, + "video/h265": { + "source": "iana" + }, + "video/iso.segment": { + "source": "iana", + "extensions": ["m4s"] + }, + "video/jpeg": { + "source": "iana", + "extensions": ["jpgv"] + }, + "video/jpeg2000": { + "source": "iana" + }, + "video/jpm": { + "source": "apache", + "extensions": ["jpm","jpgm"] + }, + "video/jxsv": { + "source": "iana" + }, + "video/mj2": { + "source": "iana", + "extensions": ["mj2","mjp2"] + }, + "video/mp1s": { + "source": "iana" + }, + "video/mp2p": { + "source": "iana" + }, + "video/mp2t": { + "source": "iana", + "extensions": ["ts"] + }, + "video/mp4": { + "source": "iana", + "compressible": false, + "extensions": ["mp4","mp4v","mpg4"] + }, + "video/mp4v-es": { + "source": "iana" + }, + "video/mpeg": { + "source": "iana", + "compressible": false, + "extensions": ["mpeg","mpg","mpe","m1v","m2v"] + }, + "video/mpeg4-generic": { + "source": "iana" + }, + "video/mpv": { + "source": "iana" + }, + "video/nv": { + "source": "iana" + }, + "video/ogg": { + "source": "iana", + "compressible": false, + "extensions": ["ogv"] + }, + "video/parityfec": { + "source": "iana" + }, + "video/pointer": { + "source": "iana" + }, + "video/quicktime": { + "source": "iana", + "compressible": false, + "extensions": ["qt","mov"] + }, + "video/raptorfec": { + "source": "iana" + }, + "video/raw": { + "source": "iana" + }, + "video/rtp-enc-aescm128": { + "source": "iana" + }, + "video/rtploopback": { + "source": "iana" + }, + "video/rtx": { + "source": "iana" + }, + "video/scip": { + "source": "iana" + }, + "video/smpte291": { + "source": "iana" + }, + "video/smpte292m": { + "source": "iana" + }, + "video/ulpfec": { + "source": "iana" + }, + "video/vc1": { + "source": "iana" + }, + "video/vc2": { + "source": "iana" + }, + "video/vnd.cctv": { + "source": "iana" + }, + "video/vnd.dece.hd": { + "source": "iana", + "extensions": ["uvh","uvvh"] + }, + "video/vnd.dece.mobile": { + "source": "iana", + "extensions": ["uvm","uvvm"] + }, + "video/vnd.dece.mp4": { + "source": "iana" + }, + "video/vnd.dece.pd": { + "source": "iana", + "extensions": ["uvp","uvvp"] + }, + "video/vnd.dece.sd": { + "source": "iana", + "extensions": ["uvs","uvvs"] + }, + "video/vnd.dece.video": { + "source": "iana", + "extensions": ["uvv","uvvv"] + }, + "video/vnd.directv.mpeg": { + "source": "iana" + }, + "video/vnd.directv.mpeg-tts": { + "source": "iana" + }, + "video/vnd.dlna.mpeg-tts": { + "source": "iana" + }, + "video/vnd.dvb.file": { + "source": "iana", + "extensions": ["dvb"] + }, + "video/vnd.fvt": { + "source": "iana", + "extensions": ["fvt"] + }, + "video/vnd.hns.video": { + "source": "iana" + }, + "video/vnd.iptvforum.1dparityfec-1010": { + "source": "iana" + }, + "video/vnd.iptvforum.1dparityfec-2005": { + "source": "iana" + }, + "video/vnd.iptvforum.2dparityfec-1010": { + "source": "iana" + }, + "video/vnd.iptvforum.2dparityfec-2005": { + "source": "iana" + }, + "video/vnd.iptvforum.ttsavc": { + "source": "iana" + }, + "video/vnd.iptvforum.ttsmpeg2": { + "source": "iana" + }, + "video/vnd.motorola.video": { + "source": "iana" + }, + "video/vnd.motorola.videop": { + "source": "iana" + }, + "video/vnd.mpegurl": { + "source": "iana", + "extensions": ["mxu","m4u"] + }, + "video/vnd.ms-playready.media.pyv": { + "source": "iana", + "extensions": ["pyv"] + }, + "video/vnd.nokia.interleaved-multimedia": { + "source": "iana" + }, + "video/vnd.nokia.mp4vr": { + "source": "iana" + }, + "video/vnd.nokia.videovoip": { + "source": "iana" + }, + "video/vnd.objectvideo": { + "source": "iana" + }, + "video/vnd.radgamettools.bink": { + "source": "iana" + }, + "video/vnd.radgamettools.smacker": { + "source": "iana" + }, + "video/vnd.sealed.mpeg1": { + "source": "iana" + }, + "video/vnd.sealed.mpeg4": { + "source": "iana" + }, + "video/vnd.sealed.swf": { + "source": "iana" + }, + "video/vnd.sealedmedia.softseal.mov": { + "source": "iana" + }, + "video/vnd.uvvu.mp4": { + "source": "iana", + "extensions": ["uvu","uvvu"] + }, + "video/vnd.vivo": { + "source": "iana", + "extensions": ["viv"] + }, + "video/vnd.youtube.yt": { + "source": "iana" + }, + "video/vp8": { + "source": "iana" + }, + "video/vp9": { + "source": "iana" + }, + "video/webm": { + "source": "apache", + "compressible": false, + "extensions": ["webm"] + }, + "video/x-f4v": { + "source": "apache", + "extensions": ["f4v"] + }, + "video/x-fli": { + "source": "apache", + "extensions": ["fli"] + }, + "video/x-flv": { + "source": "apache", + "compressible": false, + "extensions": ["flv"] + }, + "video/x-m4v": { + "source": "apache", + "extensions": ["m4v"] + }, + "video/x-matroska": { + "source": "apache", + "compressible": false, + "extensions": ["mkv","mk3d","mks"] + }, + "video/x-mng": { + "source": "apache", + "extensions": ["mng"] + }, + "video/x-ms-asf": { + "source": "apache", + "extensions": ["asf","asx"] + }, + "video/x-ms-vob": { + "source": "apache", + "extensions": ["vob"] + }, + "video/x-ms-wm": { + "source": "apache", + "extensions": ["wm"] + }, + "video/x-ms-wmv": { + "source": "apache", + "compressible": false, + "extensions": ["wmv"] + }, + "video/x-ms-wmx": { + "source": "apache", + "extensions": ["wmx"] + }, + "video/x-ms-wvx": { + "source": "apache", + "extensions": ["wvx"] + }, + "video/x-msvideo": { + "source": "apache", + "extensions": ["avi"] + }, + "video/x-sgi-movie": { + "source": "apache", + "extensions": ["movie"] + }, + "video/x-smv": { + "source": "apache", + "extensions": ["smv"] + }, + "x-conference/x-cooltalk": { + "source": "apache", + "extensions": ["ice"] + }, + "x-shader/x-fragment": { + "compressible": true + }, + "x-shader/x-vertex": { + "compressible": true + } +} diff --git a/node_modules/mime-db/index.js b/node_modules/mime-db/index.js new file mode 100644 index 0000000..ec2be30 --- /dev/null +++ b/node_modules/mime-db/index.js @@ -0,0 +1,12 @@ +/*! + * mime-db + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015-2022 Douglas Christopher Wilson + * MIT Licensed + */ + +/** + * Module exports. + */ + +module.exports = require('./db.json') diff --git a/node_modules/mime-db/package.json b/node_modules/mime-db/package.json new file mode 100644 index 0000000..32c14b8 --- /dev/null +++ b/node_modules/mime-db/package.json @@ -0,0 +1,60 @@ +{ + "name": "mime-db", + "description": "Media Type Database", + "version": "1.52.0", + "contributors": [ + "Douglas Christopher Wilson ", + "Jonathan Ong (http://jongleberry.com)", + "Robert Kieffer (http://github.com/broofa)" + ], + "license": "MIT", + "keywords": [ + "mime", + "db", + "type", + "types", + "database", + "charset", + "charsets" + ], + "repository": "jshttp/mime-db", + "devDependencies": { + "bluebird": "3.7.2", + "co": "4.6.0", + "cogent": "1.0.1", + "csv-parse": "4.16.3", + "eslint": "7.32.0", + "eslint-config-standard": "15.0.1", + "eslint-plugin-import": "2.25.4", + "eslint-plugin-markdown": "2.2.1", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-promise": "5.1.1", + "eslint-plugin-standard": "4.1.0", + "gnode": "0.1.2", + "media-typer": "1.1.0", + "mocha": "9.2.1", + "nyc": "15.1.0", + "raw-body": "2.5.0", + "stream-to-array": "2.3.0" + }, + "files": [ + "HISTORY.md", + "LICENSE", + "README.md", + "db.json", + "index.js" + ], + "engines": { + "node": ">= 0.6" + }, + "scripts": { + "build": "node scripts/build", + "fetch": "node scripts/fetch-apache && gnode scripts/fetch-iana && node scripts/fetch-nginx", + "lint": "eslint .", + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-ci": "nyc --reporter=lcov --reporter=text npm test", + "test-cov": "nyc --reporter=html --reporter=text npm test", + "update": "npm run fetch && npm run build", + "version": "node scripts/version-history.js && git add HISTORY.md" + } +} diff --git a/node_modules/mime-types/HISTORY.md b/node_modules/mime-types/HISTORY.md new file mode 100644 index 0000000..c5043b7 --- /dev/null +++ b/node_modules/mime-types/HISTORY.md @@ -0,0 +1,397 @@ +2.1.35 / 2022-03-12 +=================== + + * deps: mime-db@1.52.0 + - Add extensions from IANA for more `image/*` types + - Add extension `.asc` to `application/pgp-keys` + - Add extensions to various XML types + - Add new upstream MIME types + +2.1.34 / 2021-11-08 +=================== + + * deps: mime-db@1.51.0 + - Add new upstream MIME types + +2.1.33 / 2021-10-01 +=================== + + * deps: mime-db@1.50.0 + - Add deprecated iWorks mime types and extensions + - Add new upstream MIME types + +2.1.32 / 2021-07-27 +=================== + + * deps: mime-db@1.49.0 + - Add extension `.trig` to `application/trig` + - Add new upstream MIME types + +2.1.31 / 2021-06-01 +=================== + + * deps: mime-db@1.48.0 + - Add extension `.mvt` to `application/vnd.mapbox-vector-tile` + - Add new upstream MIME types + +2.1.30 / 2021-04-02 +=================== + + * deps: mime-db@1.47.0 + - Add extension `.amr` to `audio/amr` + - Remove ambigious extensions from IANA for `application/*+xml` types + - Update primary extension to `.es` for `application/ecmascript` + +2.1.29 / 2021-02-17 +=================== + + * deps: mime-db@1.46.0 + - Add extension `.amr` to `audio/amr` + - Add extension `.m4s` to `video/iso.segment` + - Add extension `.opus` to `audio/ogg` + - Add new upstream MIME types + +2.1.28 / 2021-01-01 +=================== + + * deps: mime-db@1.45.0 + - Add `application/ubjson` with extension `.ubj` + - Add `image/avif` with extension `.avif` + - Add `image/ktx2` with extension `.ktx2` + - Add extension `.dbf` to `application/vnd.dbf` + - Add extension `.rar` to `application/vnd.rar` + - Add extension `.td` to `application/urc-targetdesc+xml` + - Add new upstream MIME types + - Fix extension of `application/vnd.apple.keynote` to be `.key` + +2.1.27 / 2020-04-23 +=================== + + * deps: mime-db@1.44.0 + - Add charsets from IANA + - Add extension `.cjs` to `application/node` + - Add new upstream MIME types + +2.1.26 / 2020-01-05 +=================== + + * deps: mime-db@1.43.0 + - Add `application/x-keepass2` with extension `.kdbx` + - Add extension `.mxmf` to `audio/mobile-xmf` + - Add extensions from IANA for `application/*+xml` types + - Add new upstream MIME types + +2.1.25 / 2019-11-12 +=================== + + * deps: mime-db@1.42.0 + - Add new upstream MIME types + - Add `application/toml` with extension `.toml` + - Add `image/vnd.ms-dds` with extension `.dds` + +2.1.24 / 2019-04-20 +=================== + + * deps: mime-db@1.40.0 + - Add extensions from IANA for `model/*` types + - Add `text/mdx` with extension `.mdx` + +2.1.23 / 2019-04-17 +=================== + + * deps: mime-db@~1.39.0 + - Add extensions `.siv` and `.sieve` to `application/sieve` + - Add new upstream MIME types + +2.1.22 / 2019-02-14 +=================== + + * deps: mime-db@~1.38.0 + - Add extension `.nq` to `application/n-quads` + - Add extension `.nt` to `application/n-triples` + - Add new upstream MIME types + +2.1.21 / 2018-10-19 +=================== + + * deps: mime-db@~1.37.0 + - Add extensions to HEIC image types + - Add new upstream MIME types + +2.1.20 / 2018-08-26 +=================== + + * deps: mime-db@~1.36.0 + - Add Apple file extensions from IANA + - Add extensions from IANA for `image/*` types + - Add new upstream MIME types + +2.1.19 / 2018-07-17 +=================== + + * deps: mime-db@~1.35.0 + - Add extension `.csl` to `application/vnd.citationstyles.style+xml` + - Add extension `.es` to `application/ecmascript` + - Add extension `.owl` to `application/rdf+xml` + - Add new upstream MIME types + - Add UTF-8 as default charset for `text/turtle` + +2.1.18 / 2018-02-16 +=================== + + * deps: mime-db@~1.33.0 + - Add `application/raml+yaml` with extension `.raml` + - Add `application/wasm` with extension `.wasm` + - Add `text/shex` with extension `.shex` + - Add extensions for JPEG-2000 images + - Add extensions from IANA for `message/*` types + - Add new upstream MIME types + - Update font MIME types + - Update `text/hjson` to registered `application/hjson` + +2.1.17 / 2017-09-01 +=================== + + * deps: mime-db@~1.30.0 + - Add `application/vnd.ms-outlook` + - Add `application/x-arj` + - Add extension `.mjs` to `application/javascript` + - Add glTF types and extensions + - Add new upstream MIME types + - Add `text/x-org` + - Add VirtualBox MIME types + - Fix `source` records for `video/*` types that are IANA + - Update `font/opentype` to registered `font/otf` + +2.1.16 / 2017-07-24 +=================== + + * deps: mime-db@~1.29.0 + - Add `application/fido.trusted-apps+json` + - Add extension `.wadl` to `application/vnd.sun.wadl+xml` + - Add extension `.gz` to `application/gzip` + - Add new upstream MIME types + - Update extensions `.md` and `.markdown` to be `text/markdown` + +2.1.15 / 2017-03-23 +=================== + + * deps: mime-db@~1.27.0 + - Add new mime types + - Add `image/apng` + +2.1.14 / 2017-01-14 +=================== + + * deps: mime-db@~1.26.0 + - Add new mime types + +2.1.13 / 2016-11-18 +=================== + + * deps: mime-db@~1.25.0 + - Add new mime types + +2.1.12 / 2016-09-18 +=================== + + * deps: mime-db@~1.24.0 + - Add new mime types + - Add `audio/mp3` + +2.1.11 / 2016-05-01 +=================== + + * deps: mime-db@~1.23.0 + - Add new mime types + +2.1.10 / 2016-02-15 +=================== + + * deps: mime-db@~1.22.0 + - Add new mime types + - Fix extension of `application/dash+xml` + - Update primary extension for `audio/mp4` + +2.1.9 / 2016-01-06 +================== + + * deps: mime-db@~1.21.0 + - Add new mime types + +2.1.8 / 2015-11-30 +================== + + * deps: mime-db@~1.20.0 + - Add new mime types + +2.1.7 / 2015-09-20 +================== + + * deps: mime-db@~1.19.0 + - Add new mime types + +2.1.6 / 2015-09-03 +================== + + * deps: mime-db@~1.18.0 + - Add new mime types + +2.1.5 / 2015-08-20 +================== + + * deps: mime-db@~1.17.0 + - Add new mime types + +2.1.4 / 2015-07-30 +================== + + * deps: mime-db@~1.16.0 + - Add new mime types + +2.1.3 / 2015-07-13 +================== + + * deps: mime-db@~1.15.0 + - Add new mime types + +2.1.2 / 2015-06-25 +================== + + * deps: mime-db@~1.14.0 + - Add new mime types + +2.1.1 / 2015-06-08 +================== + + * perf: fix deopt during mapping + +2.1.0 / 2015-06-07 +================== + + * Fix incorrectly treating extension-less file name as extension + - i.e. `'path/to/json'` will no longer return `application/json` + * Fix `.charset(type)` to accept parameters + * Fix `.charset(type)` to match case-insensitive + * Improve generation of extension to MIME mapping + * Refactor internals for readability and no argument reassignment + * Prefer `application/*` MIME types from the same source + * Prefer any type over `application/octet-stream` + * deps: mime-db@~1.13.0 + - Add nginx as a source + - Add new mime types + +2.0.14 / 2015-06-06 +=================== + + * deps: mime-db@~1.12.0 + - Add new mime types + +2.0.13 / 2015-05-31 +=================== + + * deps: mime-db@~1.11.0 + - Add new mime types + +2.0.12 / 2015-05-19 +=================== + + * deps: mime-db@~1.10.0 + - Add new mime types + +2.0.11 / 2015-05-05 +=================== + + * deps: mime-db@~1.9.1 + - Add new mime types + +2.0.10 / 2015-03-13 +=================== + + * deps: mime-db@~1.8.0 + - Add new mime types + +2.0.9 / 2015-02-09 +================== + + * deps: mime-db@~1.7.0 + - Add new mime types + - Community extensions ownership transferred from `node-mime` + +2.0.8 / 2015-01-29 +================== + + * deps: mime-db@~1.6.0 + - Add new mime types + +2.0.7 / 2014-12-30 +================== + + * deps: mime-db@~1.5.0 + - Add new mime types + - Fix various invalid MIME type entries + +2.0.6 / 2014-12-30 +================== + + * deps: mime-db@~1.4.0 + - Add new mime types + - Fix various invalid MIME type entries + - Remove example template MIME types + +2.0.5 / 2014-12-29 +================== + + * deps: mime-db@~1.3.1 + - Fix missing extensions + +2.0.4 / 2014-12-10 +================== + + * deps: mime-db@~1.3.0 + - Add new mime types + +2.0.3 / 2014-11-09 +================== + + * deps: mime-db@~1.2.0 + - Add new mime types + +2.0.2 / 2014-09-28 +================== + + * deps: mime-db@~1.1.0 + - Add new mime types + - Update charsets + +2.0.1 / 2014-09-07 +================== + + * Support Node.js 0.6 + +2.0.0 / 2014-09-02 +================== + + * Use `mime-db` + * Remove `.define()` + +1.0.2 / 2014-08-04 +================== + + * Set charset=utf-8 for `text/javascript` + +1.0.1 / 2014-06-24 +================== + + * Add `text/jsx` type + +1.0.0 / 2014-05-12 +================== + + * Return `false` for unknown types + * Set charset=utf-8 for `application/json` + +0.1.0 / 2014-05-02 +================== + + * Initial release diff --git a/node_modules/mime-types/LICENSE b/node_modules/mime-types/LICENSE new file mode 100644 index 0000000..0616607 --- /dev/null +++ b/node_modules/mime-types/LICENSE @@ -0,0 +1,23 @@ +(The MIT License) + +Copyright (c) 2014 Jonathan Ong +Copyright (c) 2015 Douglas Christopher Wilson + +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. diff --git a/node_modules/mime-types/README.md b/node_modules/mime-types/README.md new file mode 100644 index 0000000..48d2fb4 --- /dev/null +++ b/node_modules/mime-types/README.md @@ -0,0 +1,113 @@ +# mime-types + +[![NPM Version][npm-version-image]][npm-url] +[![NPM Downloads][npm-downloads-image]][npm-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][ci-image]][ci-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +The ultimate javascript content-type utility. + +Similar to [the `mime@1.x` module](https://www.npmjs.com/package/mime), except: + +- __No fallbacks.__ Instead of naively returning the first available type, + `mime-types` simply returns `false`, so do + `var type = mime.lookup('unrecognized') || 'application/octet-stream'`. +- No `new Mime()` business, so you could do `var lookup = require('mime-types').lookup`. +- No `.define()` functionality +- Bug fixes for `.lookup(path)` + +Otherwise, the API is compatible with `mime` 1.x. + +## Install + +This is a [Node.js](https://nodejs.org/en/) module available through the +[npm registry](https://www.npmjs.com/). Installation is done using the +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): + +```sh +$ npm install mime-types +``` + +## Adding Types + +All mime types are based on [mime-db](https://www.npmjs.com/package/mime-db), +so open a PR there if you'd like to add mime types. + +## API + +```js +var mime = require('mime-types') +``` + +All functions return `false` if input is invalid or not found. + +### mime.lookup(path) + +Lookup the content-type associated with a file. + +```js +mime.lookup('json') // 'application/json' +mime.lookup('.md') // 'text/markdown' +mime.lookup('file.html') // 'text/html' +mime.lookup('folder/file.js') // 'application/javascript' +mime.lookup('folder/.htaccess') // false + +mime.lookup('cats') // false +``` + +### mime.contentType(type) + +Create a full content-type header given a content-type or extension. +When given an extension, `mime.lookup` is used to get the matching +content-type, otherwise the given content-type is used. Then if the +content-type does not already have a `charset` parameter, `mime.charset` +is used to get the default charset and add to the returned content-type. + +```js +mime.contentType('markdown') // 'text/x-markdown; charset=utf-8' +mime.contentType('file.json') // 'application/json; charset=utf-8' +mime.contentType('text/html') // 'text/html; charset=utf-8' +mime.contentType('text/html; charset=iso-8859-1') // 'text/html; charset=iso-8859-1' + +// from a full path +mime.contentType(path.extname('/path/to/file.json')) // 'application/json; charset=utf-8' +``` + +### mime.extension(type) + +Get the default extension for a content-type. + +```js +mime.extension('application/octet-stream') // 'bin' +``` + +### mime.charset(type) + +Lookup the implied default charset of a content-type. + +```js +mime.charset('text/markdown') // 'UTF-8' +``` + +### var type = mime.types[extension] + +A map of content-types by extension. + +### [extensions...] = mime.extensions[type] + +A map of extensions by content-type. + +## License + +[MIT](LICENSE) + +[ci-image]: https://badgen.net/github/checks/jshttp/mime-types/master?label=ci +[ci-url]: https://github.com/jshttp/mime-types/actions/workflows/ci.yml +[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/mime-types/master +[coveralls-url]: https://coveralls.io/r/jshttp/mime-types?branch=master +[node-version-image]: https://badgen.net/npm/node/mime-types +[node-version-url]: https://nodejs.org/en/download +[npm-downloads-image]: https://badgen.net/npm/dm/mime-types +[npm-url]: https://npmjs.org/package/mime-types +[npm-version-image]: https://badgen.net/npm/v/mime-types diff --git a/node_modules/mime-types/index.js b/node_modules/mime-types/index.js new file mode 100644 index 0000000..b9f34d5 --- /dev/null +++ b/node_modules/mime-types/index.js @@ -0,0 +1,188 @@ +/*! + * mime-types + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var db = require('mime-db') +var extname = require('path').extname + +/** + * Module variables. + * @private + */ + +var EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/ +var TEXT_TYPE_REGEXP = /^text\//i + +/** + * Module exports. + * @public + */ + +exports.charset = charset +exports.charsets = { lookup: charset } +exports.contentType = contentType +exports.extension = extension +exports.extensions = Object.create(null) +exports.lookup = lookup +exports.types = Object.create(null) + +// Populate the extensions/types maps +populateMaps(exports.extensions, exports.types) + +/** + * Get the default charset for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function charset (type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) + var mime = match && db[match[1].toLowerCase()] + + if (mime && mime.charset) { + return mime.charset + } + + // default text/* to utf-8 + if (match && TEXT_TYPE_REGEXP.test(match[1])) { + return 'UTF-8' + } + + return false +} + +/** + * Create a full Content-Type header given a MIME type or extension. + * + * @param {string} str + * @return {boolean|string} + */ + +function contentType (str) { + // TODO: should this even be in this module? + if (!str || typeof str !== 'string') { + return false + } + + var mime = str.indexOf('/') === -1 + ? exports.lookup(str) + : str + + if (!mime) { + return false + } + + // TODO: use content-type or other module + if (mime.indexOf('charset') === -1) { + var charset = exports.charset(mime) + if (charset) mime += '; charset=' + charset.toLowerCase() + } + + return mime +} + +/** + * Get the default extension for a MIME type. + * + * @param {string} type + * @return {boolean|string} + */ + +function extension (type) { + if (!type || typeof type !== 'string') { + return false + } + + // TODO: use media-typer + var match = EXTRACT_TYPE_REGEXP.exec(type) + + // get extensions + var exts = match && exports.extensions[match[1].toLowerCase()] + + if (!exts || !exts.length) { + return false + } + + return exts[0] +} + +/** + * Lookup the MIME type for a file path/extension. + * + * @param {string} path + * @return {boolean|string} + */ + +function lookup (path) { + if (!path || typeof path !== 'string') { + return false + } + + // get the extension ("ext" or ".ext" or full path) + var extension = extname('x.' + path) + .toLowerCase() + .substr(1) + + if (!extension) { + return false + } + + return exports.types[extension] || false +} + +/** + * Populate the extensions and types maps. + * @private + */ + +function populateMaps (extensions, types) { + // source preference (least -> most) + var preference = ['nginx', 'apache', undefined, 'iana'] + + Object.keys(db).forEach(function forEachMimeType (type) { + var mime = db[type] + var exts = mime.extensions + + if (!exts || !exts.length) { + return + } + + // mime -> extensions + extensions[type] = exts + + // extension -> mime + for (var i = 0; i < exts.length; i++) { + var extension = exts[i] + + if (types[extension]) { + var from = preference.indexOf(db[types[extension]].source) + var to = preference.indexOf(mime.source) + + if (types[extension] !== 'application/octet-stream' && + (from > to || (from === to && types[extension].substr(0, 12) === 'application/'))) { + // skip the remapping + continue + } + } + + // set the extension -> mime + types[extension] = type + } + }) +} diff --git a/node_modules/mime-types/package.json b/node_modules/mime-types/package.json new file mode 100644 index 0000000..bbef696 --- /dev/null +++ b/node_modules/mime-types/package.json @@ -0,0 +1,44 @@ +{ + "name": "mime-types", + "description": "The ultimate javascript content-type utility.", + "version": "2.1.35", + "contributors": [ + "Douglas Christopher Wilson ", + "Jeremiah Senkpiel (https://searchbeam.jit.su)", + "Jonathan Ong (http://jongleberry.com)" + ], + "license": "MIT", + "keywords": [ + "mime", + "types" + ], + "repository": "jshttp/mime-types", + "dependencies": { + "mime-db": "1.52.0" + }, + "devDependencies": { + "eslint": "7.32.0", + "eslint-config-standard": "14.1.1", + "eslint-plugin-import": "2.25.4", + "eslint-plugin-markdown": "2.2.1", + "eslint-plugin-node": "11.1.0", + "eslint-plugin-promise": "5.2.0", + "eslint-plugin-standard": "4.1.0", + "mocha": "9.2.2", + "nyc": "15.1.0" + }, + "files": [ + "HISTORY.md", + "LICENSE", + "index.js" + ], + "engines": { + "node": ">= 0.6" + }, + "scripts": { + "lint": "eslint .", + "test": "mocha --reporter spec test/test.js", + "test-ci": "nyc --reporter=lcov --reporter=text npm test", + "test-cov": "nyc --reporter=html --reporter=text npm test" + } +} diff --git a/node_modules/once/LICENSE b/node_modules/once/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/once/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/once/README.md b/node_modules/once/README.md new file mode 100644 index 0000000..1f1ffca --- /dev/null +++ b/node_modules/once/README.md @@ -0,0 +1,79 @@ +# once + +Only call a function once. + +## usage + +```javascript +var once = require('once') + +function load (file, cb) { + cb = once(cb) + loader.load('file') + loader.once('load', cb) + loader.once('error', cb) +} +``` + +Or add to the Function.prototype in a responsible way: + +```javascript +// only has to be done once +require('once').proto() + +function load (file, cb) { + cb = cb.once() + loader.load('file') + loader.once('load', cb) + loader.once('error', cb) +} +``` + +Ironically, the prototype feature makes this module twice as +complicated as necessary. + +To check whether you function has been called, use `fn.called`. Once the +function is called for the first time the return value of the original +function is saved in `fn.value` and subsequent calls will continue to +return this value. + +```javascript +var once = require('once') + +function load (cb) { + cb = once(cb) + var stream = createStream() + stream.once('data', cb) + stream.once('end', function () { + if (!cb.called) cb(new Error('not found')) + }) +} +``` + +## `once.strict(func)` + +Throw an error if the function is called twice. + +Some functions are expected to be called only once. Using `once` for them would +potentially hide logical errors. + +In the example below, the `greet` function has to call the callback only once: + +```javascript +function greet (name, cb) { + // return is missing from the if statement + // when no name is passed, the callback is called twice + if (!name) cb('Hello anonymous') + cb('Hello ' + name) +} + +function log (msg) { + console.log(msg) +} + +// this will print 'Hello anonymous' but the logical error will be missed +greet(null, once(msg)) + +// once.strict will print 'Hello anonymous' and throw an error when the callback will be called the second time +greet(null, once.strict(msg)) +``` diff --git a/node_modules/once/once.js b/node_modules/once/once.js new file mode 100644 index 0000000..2354067 --- /dev/null +++ b/node_modules/once/once.js @@ -0,0 +1,42 @@ +var wrappy = require('wrappy') +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} diff --git a/node_modules/once/package.json b/node_modules/once/package.json new file mode 100644 index 0000000..16815b2 --- /dev/null +++ b/node_modules/once/package.json @@ -0,0 +1,33 @@ +{ + "name": "once", + "version": "1.4.0", + "description": "Run a function exactly one time", + "main": "once.js", + "directories": { + "test": "test" + }, + "dependencies": { + "wrappy": "1" + }, + "devDependencies": { + "tap": "^7.0.1" + }, + "scripts": { + "test": "tap test/*.js" + }, + "files": [ + "once.js" + ], + "repository": { + "type": "git", + "url": "git://github.com/isaacs/once" + }, + "keywords": [ + "once", + "function", + "one", + "single" + ], + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC" +} diff --git a/node_modules/precond/README.md b/node_modules/precond/README.md new file mode 100644 index 0000000..47e467c --- /dev/null +++ b/node_modules/precond/README.md @@ -0,0 +1,171 @@ +# Preconditions for Node.js +[![Build Status](https://secure.travis-ci.org/MathieuTurcotte/node-precond.png?branch=master)](https://travis-ci.org/MathieuTurcotte/node-precond) +[![NPM version](https://badge.fury.io/js/precond.png)](http://badge.fury.io/js/precond) + +Precondition checks for Node.js inspired by [Guava's precondition checking +utilities](https://code.google.com/p/guava-libraries/wiki/PreconditionsExplained). + +## Installation + +``` +npm install precond +``` + +## Unit tests + +``` +npm test +``` + +## Overview + +Precond provides a set of functions to verify arguments and state correctness + +It lets you rewrite constructs like the following + +```js +if (!this.isConnected) { + throw new Error('Client should be connected before calling X.'); +} +``` + +into a more compact and declarative check bellow. + +```js +precond.checkState(this.isConnected, 'Client should be ...'); +``` + +**Note that even though the throw statement is wrapped in a function, the call +stack will still start from the calling function. So the previous examples would +both produce the same stack trace.** + +All arguments after the message will be used to format the actual error +message that will be thrown. + +The following precondition checks are provded: + +- checkArgument(value, [messageFormat, [formatArgs, ...]]) +- checkState(value, [messageFormat, [formatArgs, ...]]) +- checkIsDef(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsDefAndNotNull(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsString(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsArray(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsNumber(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsBoolean(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsFunction(value, [messageFormat, [formatArgs, ...]]) -> value +- checkIsObject(value, [messageFormat, [formatArgs, ...]]) -> value + +## API + +### Static functions + +#### precond.checkArgument(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be truthy +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is true. Throws an `IllegalArgumentError` if value +is false. + +#### precond.checkState(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be truthy +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is true. Throws an `IllegalStateError` if value +is false. + +#### precond.checkIsDef(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be defined +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is defined (could be null). Throws an +`IllegalArgumentError` if value is undefined. Returns the value of +the value that was validated. + +#### precond.checkIsDefAndNotNull(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be defined and not null +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is defined and not null. Throws an +`IllegalArgumentError` if value is undefined or null. Returns the value of +the value that was validated. + +#### precond.checkIsString(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be a string +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is a string or a String object. Throws an +`IllegalArgumentError` if value isn't a string. Returns the value of +the value that was validated. + +#### precond.checkIsArray(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be an array +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is an array. Throws an `IllegalArgumentError` if +value isn't an array. Returns the value of the value that was +validated. + +#### precond.checkIsNumber(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be a number +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is a number. Throws an `IllegalArgumentError` if +value isn't a number. Returns the value of the value that was +validated. + +#### precond.checkIsBoolean(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be a boolean +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is a boolean. Throws an `IllegalArgumentError` if +value isn't a boolean. Returns the value of the value that was +validated. + +#### precond.checkIsFunction(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be a function +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is a function. Throws an `IllegalArgumentError` if +value isn't a function. Returns the value of the value that was +validated. + +#### precond.checkIsObject(value, [messageFormat, [formatArgs, ...]]) + +- value: the value that is required to be an object +- messageFormat: error message format template +- formatArgs: arguments to be substituted into the message template + +Ensures that value is an object. Throws an `IllegalArgumentError` if +value isn't an object. Returns the value of the value that was +validated. + +### Class precond.IllegalArgumentError + +Extends `Error` and is thrown to signal illegal arguments. + +### Class precond.IllegalStateError + +Extends `Error` and is thrown to signal that the program or object has reached +an illegal state. + +## License + +This code is free to use under the terms of the [MIT license](http://mturcotte.mit-license.org/). diff --git a/node_modules/precond/index.js b/node_modules/precond/index.js new file mode 100644 index 0000000..4a1f47d --- /dev/null +++ b/node_modules/precond/index.js @@ -0,0 +1,6 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +module.exports = require('./lib/checks'); \ No newline at end of file diff --git a/node_modules/precond/lib/checks.js b/node_modules/precond/lib/checks.js new file mode 100644 index 0000000..6f5123d --- /dev/null +++ b/node_modules/precond/lib/checks.js @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var util = require('util'); + +var errors = module.exports = require('./errors'); + +function failCheck(ExceptionConstructor, callee, messageFormat, formatArgs) { + messageFormat = messageFormat || ''; + var message = util.format.apply(this, [messageFormat].concat(formatArgs)); + var error = new ExceptionConstructor(message); + Error.captureStackTrace(error, callee); + throw error; +} + +function failArgumentCheck(callee, message, formatArgs) { + failCheck(errors.IllegalArgumentError, callee, message, formatArgs); +} + +function failStateCheck(callee, message, formatArgs) { + failCheck(errors.IllegalStateError, callee, message, formatArgs); +} + +module.exports.checkArgument = function(value, message) { + if (!value) { + failArgumentCheck(arguments.callee, message, + Array.prototype.slice.call(arguments, 2)); + } +}; + +module.exports.checkState = function(value, message) { + if (!value) { + failStateCheck(arguments.callee, message, + Array.prototype.slice.call(arguments, 2)); + } +}; + +module.exports.checkIsDef = function(value, message) { + if (value !== undefined) { + return value; + } + + failArgumentCheck(arguments.callee, message || + 'Expected value to be defined but was undefined.', + Array.prototype.slice.call(arguments, 2)); +}; + +module.exports.checkIsDefAndNotNull = function(value, message) { + // Note that undefined == null. + if (value != null) { + return value; + } + + failArgumentCheck(arguments.callee, message || + 'Expected value to be defined and not null but got "' + + typeOf(value) + '".', Array.prototype.slice.call(arguments, 2)); +}; + +// Fixed version of the typeOf operator which returns 'null' for null values +// and 'array' for arrays. +function typeOf(value) { + var s = typeof value; + if (s == 'object') { + if (!value) { + return 'null'; + } else if (value instanceof Array) { + return 'array'; + } + } + return s; +} + +function typeCheck(expect) { + return function(value, message) { + var type = typeOf(value); + + if (type == expect) { + return value; + } + + failArgumentCheck(arguments.callee, message || + 'Expected "' + expect + '" but got "' + type + '".', + Array.prototype.slice.call(arguments, 2)); + }; +} + +module.exports.checkIsString = typeCheck('string'); +module.exports.checkIsArray = typeCheck('array'); +module.exports.checkIsNumber = typeCheck('number'); +module.exports.checkIsBoolean = typeCheck('boolean'); +module.exports.checkIsFunction = typeCheck('function'); +module.exports.checkIsObject = typeCheck('object'); diff --git a/node_modules/precond/lib/errors.js b/node_modules/precond/lib/errors.js new file mode 100644 index 0000000..dee7e7c --- /dev/null +++ b/node_modules/precond/lib/errors.js @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2012 Mathieu Turcotte + * Licensed under the MIT license. + */ + +var util = require('util'); + +function IllegalArgumentError(message) { + Error.call(this, message); + this.message = message; +} +util.inherits(IllegalArgumentError, Error); + +IllegalArgumentError.prototype.name = 'IllegalArgumentError'; + +function IllegalStateError(message) { + Error.call(this, message); + this.message = message; +} +util.inherits(IllegalStateError, Error); + +IllegalStateError.prototype.name = 'IllegalStateError'; + +module.exports.IllegalStateError = IllegalStateError; +module.exports.IllegalArgumentError = IllegalArgumentError; \ No newline at end of file diff --git a/node_modules/precond/package.json b/node_modules/precond/package.json new file mode 100644 index 0000000..eaec5dd --- /dev/null +++ b/node_modules/precond/package.json @@ -0,0 +1,26 @@ +{ + "name": "precond", + "description": "Precondition checking utilities.", + "version": "0.2.3", + "author": "Mathieu Turcotte ", + "keywords": ["precondition", "assert", "invariant", "contract", "condition"], + "repository": { + "type": "git", + "url": "https://github.com/MathieuTurcotte/node-precond.git" + }, + "devDependencies": { + "nodeunit": "0.9", + "jshint": "2.5" + }, + "scripts": { + "pretest": "node_modules/.bin/jshint lib/ examples/ index.js", + "test": "node_modules/.bin/nodeunit tests/" + }, + "engines": { + "node": ">= 0.6" + }, + "files": [ + "index.js", + "lib" + ] +} diff --git a/node_modules/process-warning/.gitattributes b/node_modules/process-warning/.gitattributes new file mode 100644 index 0000000..a0e7df9 --- /dev/null +++ b/node_modules/process-warning/.gitattributes @@ -0,0 +1,2 @@ +# Set default behavior to automatically convert line endings +* text=auto eol=lf diff --git a/node_modules/process-warning/.github/dependabot.yml b/node_modules/process-warning/.github/dependabot.yml new file mode 100644 index 0000000..dfa7fa6 --- /dev/null +++ b/node_modules/process-warning/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + open-pull-requests-limit: 10 + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 diff --git a/node_modules/process-warning/.github/workflows/ci.yml b/node_modules/process-warning/.github/workflows/ci.yml new file mode 100644 index 0000000..7b00276 --- /dev/null +++ b/node_modules/process-warning/.github/workflows/ci.yml @@ -0,0 +1,23 @@ +name: CI + +on: + push: + branches: + - main + - master + - next + - 'v*' + paths-ignore: + - 'docs/**' + - '*.md' + pull_request: + paths-ignore: + - 'docs/**' + - '*.md' + +jobs: + test: + uses: fastify/workflows/.github/workflows/plugins-ci.yml@v3 + with: + license-check: true + lint: true diff --git a/node_modules/process-warning/.taprc b/node_modules/process-warning/.taprc new file mode 100644 index 0000000..aeac425 --- /dev/null +++ b/node_modules/process-warning/.taprc @@ -0,0 +1,2 @@ +files: + - test/**/*[!jest].test.js diff --git a/node_modules/process-warning/LICENSE b/node_modules/process-warning/LICENSE new file mode 100644 index 0000000..24f78a7 --- /dev/null +++ b/node_modules/process-warning/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Fastify + +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. diff --git a/node_modules/process-warning/README.md b/node_modules/process-warning/README.md new file mode 100644 index 0000000..92bdda7 --- /dev/null +++ b/node_modules/process-warning/README.md @@ -0,0 +1,105 @@ +# process-warning + +![CI](https://github.com/fastify/process-warning/workflows/CI/badge.svg) +[![NPM version](https://img.shields.io/npm/v/process-warning.svg?style=flat)](https://www.npmjs.com/package/process-warning) +[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://standardjs.com/) + +A small utility for generating consistent warning objects across your codebase. +It also exposes a utility for emitting those warnings, guaranteeing that they are issued only once (unless configured otherwise). + +This module is used by the [Fastify](https://fastify.io) framework and it was called `fastify-warning` prior to version 1.0.0. + +### Install + +``` +npm i process-warning +``` + +### Usage + +The module exports a builder function that returns a utility for creating warnings and emitting them. + +```js +const warning = require('process-warning')() +``` + +#### Methods + +##### `warning.create(name, code, message[, options])` + +- `name` (`string`, required) - The error name, you can access it later with +`error.name`. For consistency, we recommend prefixing module error names +with `{YourModule}Warning` +- `code` (`string`, required) - The warning code, you can access it later with +`error.code`. For consistency, we recommend prefixing plugin error codes with +`{ThreeLetterModuleName}_`, e.g. `FST_`. NOTE: codes should be all uppercase. +- `message` (`string`, required) - The warning message. You can also use +interpolated strings for formatting the message. +- `options` (`object`, optional) - Optional options with the following +properties: + + `unlimited` (`boolean`, optional) - Should the warning be emitted more than + once? Defaults to `false`. + + +##### `warning.createDeprecation(code, message[, options])` + +This is a wrapper for `warning.create`. It is equivalent to invoking +`warning.create` with the `name` parameter set to "DeprecationWarning". + +Deprecation warnings have extended support for the Node.js CLI options: +`--throw-deprecation`, `--no-deprecation`, and `--trace-deprecation`. + +##### `warning.emit(code [, a [, b [, c]]])` + +The utility also contains an `emit` function that you can use for emitting the +warnings you have previously created by passing their respective code. +A warning is guaranteed to be emitted at least once. + +- `code` (`string`, required) - The warning code you intend to emit. +- `[, a [, b [, c]]]` (`any`, optional) - Parameters for string interpolation. + +```js +const warning = require('process-warning')() +warning.create('FastifyWarning', 'FST_ERROR_CODE', 'message') +warning.emit('FST_ERROR_CODE') +``` + +How to use an interpolated string: +```js +const warning = require('process-warning')() +warning.create('FastifyWarning', 'FST_ERROR_CODE', 'Hello %s') +warning.emit('FST_ERROR_CODE', 'world') +``` + +The module also exports an `warning.emitted` [Map](https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Map), which contains all the warnings already emitted. Useful for testing. +```js +const warning = require('process-warning')() +warning.create('FastifyWarning', 'FST_ERROR_CODE', 'Hello %s') +console.log(warning.emitted.get('FST_ERROR_CODE')) // false +warning.emit('FST_ERROR_CODE', 'world') +console.log(warning.emitted.get('FST_ERROR_CODE')) // true +``` + +How to use an unlimited warning: +```js +const warning = require('process-warning')() +warning.create('FastifyWarning', 'FST_ERROR_CODE', 'Hello %s', { unlimited: true }) +warning.emit('FST_ERROR_CODE', 'world') // will be emitted +warning.emit('FST_ERROR_CODE', 'world') // will be emitted again +``` + +#### Suppressing warnings + +It is possible to suppress warnings by utilizing one of node's built-in warning suppression mechanisms. + +Warnings can be suppressed: + +- by setting the `NODE_NO_WARNINGS` environment variable to `1` +- by passing the `--no-warnings` flag to the node process +- by setting 'no-warnings' in the `NODE_OPTIONS` environment variable + +For more information see [node's documentation](https://nodejs.org/api/cli.html). + +## License + +Licensed under [MIT](./LICENSE). diff --git a/node_modules/process-warning/benchmarks/warn.js b/node_modules/process-warning/benchmarks/warn.js new file mode 100644 index 0000000..8a191b4 --- /dev/null +++ b/node_modules/process-warning/benchmarks/warn.js @@ -0,0 +1,17 @@ +'use strict' + +const { Suite } = require('benchmark') +const warning = require('..')() + +warning.create('FastifyWarning', 'FST_ERROR_CODE_1', 'message') +warning.create('FastifyWarning', 'FST_ERROR_CODE_2', 'message') +warning.create('FastifyWarning', 'FST_ERROR_CODE_3', 'message') +new Suite() + .add('warn', function () { + warning.emit('FST_ERROR_CODE_1') + warning.emit('FST_ERROR_CODE_3') + }) + .on('cycle', function (event) { + console.log(String(event.target)) + }) + .run() diff --git a/node_modules/process-warning/examples/example.js b/node_modules/process-warning/examples/example.js new file mode 100644 index 0000000..d6733fd --- /dev/null +++ b/node_modules/process-warning/examples/example.js @@ -0,0 +1,7 @@ +'use strict' + +const warning = require('..')() + +warning.create('DeprecationWarning', 'CUSTDEP001', 'This is a deprecation warning') + +warning.emit('CUSTDEP001') diff --git a/node_modules/process-warning/index.js b/node_modules/process-warning/index.js new file mode 100644 index 0000000..1e7f87f --- /dev/null +++ b/node_modules/process-warning/index.js @@ -0,0 +1,158 @@ +'use strict' + +const { format } = require('node:util') + +/** + * An object that provides methods for creating process warning, emitting them, + * and inspecting/managing the emission state of warning. + * + * @typedef {object} ProcessWarningManager + */ + +/** + * @typedef {object} CreateOptions + * @property {boolean} [unlimited=false] Indicates if the warning should be + * emitted every time (`true`) or only the first time (`false`). + */ + +/** + * An error instance representing a process warning. This is what will be + * emitted to listeners when the warning is emitted. + * + * @typedef {Error} ProcessWarning + * @property {string} code + * @property {string} name + * @property {string} message + */ + +/** + * A function used to create new {@link ProcessWarning} instances. + * + * @callback ProcessWarningBuilder + * @param {*} [param1] First possible string interpolation value. + * @param {*} [param2] Second possible string interpolation value. + * @param {*} [param3] Third possible string interpolation value. + * @returns ProcessWarning + */ + +/** + * Factory that builds a new {@link ProcessWarningManager} and returns it. + * + * @returns ProcessWarningManager + */ +function processWarning () { + const codes = {} + const emitted = new Map() + const opts = Object.create(null) + + /** + * Builds a new {@link ProcessWarning} and adds it to the + * {@link ProcessWarningManager} such that it can be emitted through the + * {@link ProcessWarningManager#emit} method. + * + * @memberof! ProcessWarningManager + * @instance + * + * @param {string} name Warning name, e.g. `'MyCustomWarning'`. + * @param {string} code A unique code for the warning, e.g. `'WARN_001'`. + * @param {string} message The body of the warning. + * @param {CreateOptions} [options] + * @returns {ProcessWarningBuilder} + */ + function create (name, code, message, { unlimited = false } = {}) { + if (!name) throw new Error('Warning name must not be empty') + if (!code) throw new Error('Warning code must not be empty') + if (!message) throw new Error('Warning message must not be empty') + if (typeof unlimited !== 'boolean') throw new Error('Warning opts.unlimited must be a boolean') + + code = code.toUpperCase() + + if (codes[code] !== undefined) { + throw new Error(`The code '${code}' already exist`) + } + + function buildWarnOpts (a, b, c) { + // more performant than spread (...) operator + let formatted + if (a && b && c) { + formatted = format(message, a, b, c) + } else if (a && b) { + formatted = format(message, a, b) + } else if (a) { + formatted = format(message, a) + } else { + formatted = message + } + + return { + code, + name, + message: formatted + } + } + + Object.assign(opts, { unlimited }) + emitted.set(code, unlimited) + codes[code] = buildWarnOpts + + return codes[code] + } + + /** + * A wrapper for {@link ProcessWarningManager#create} that builds a new + * deprecation warning. This method is equivalent to passing + * `name = 'DeprecationWarning'` to the create method. + * + * Deprecation warnings have extended support for the Node.js CLI options: + * `--throw-deprecation`, `--no-deprecation`, and `--trace-deprecation`. + * + * @memberof! ProcessWarningManager + * @instance + * + * @param {string} code + * @param {string} message + * @param {CreateOptions} opts + * @returns {ProcessWarningBuilder} + */ + function createDeprecation (code, message, opts = {}) { + return create('DeprecationWarning', code, message, opts) + } + + /** + * Emits a registered warning associated with the given `code`. If the + * warning message has interpolation strings present, up to the first three + * of them can be supplied values with the optional interpolation value + * parameters. + * + * If a warning is set to `unlimited: false`, and has already been emitted + * once, invoking this method is a no-operation. + * + * @memberof! ProcessWarningManager + * @instance + * + * @param {string} code The code for the error to emit, e.g. `'WARN_001'`. + * This is the same code that was provided to {@link ProcessWarningManager#create}. + * @param {*} [a] Possible message interpolation value. + * @param {*} [b] Possible message interpolation value. + * @param {*} [c] Possible message interpolation value. + */ + function emit (code, a, b, c) { + if (emitted.get(code) === true && opts.unlimited === false) return + if (codes[code] === undefined) throw new Error(`The code '${code}' does not exist`) + emitted.set(code, true) + + const warning = codes[code](a, b, c) + process.emitWarning(warning.message, warning.name, warning.code) + } + + return { + create, + createDeprecation, + emit, + emitted + } +} + +module.exports = processWarning +module.exports.default = processWarning +module.exports.processWarning = processWarning diff --git a/node_modules/process-warning/package.json b/node_modules/process-warning/package.json new file mode 100644 index 0000000..b536c0f --- /dev/null +++ b/node_modules/process-warning/package.json @@ -0,0 +1,42 @@ +{ + "name": "process-warning", + "version": "2.3.2", + "description": "A small utility for creating warnings and emitting them.", + "main": "index.js", + "type": "commonjs", + "types": "types/index.d.ts", + "scripts": { + "lint": "standard", + "lint:fix": "standard --fix", + "test": "npm run test:unit && npm run test:jest && npm run test:typescript", + "test:jest": "jest jest.test.js", + "test:unit": "tap", + "test:typescript": "tsd" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/fastify/process-warning.git" + }, + "keywords": [ + "fastify", + "error", + "warning", + "utility", + "plugin", + "emit", + "once" + ], + "author": "Tomas Della Vedova", + "license": "MIT", + "bugs": { + "url": "https://github.com/fastify/fastify-warning/issues" + }, + "homepage": "https://github.com/fastify/fastify-warning#readme", + "devDependencies": { + "benchmark": "^2.1.4", + "jest": "^29.0.1", + "standard": "^17.0.0", + "tap": "^16.3.0", + "tsd": "^0.29.0" + } +} diff --git a/node_modules/process-warning/test/emit-interpolated-string.test.js b/node_modules/process-warning/test/emit-interpolated-string.test.js new file mode 100644 index 0000000..c282a3c --- /dev/null +++ b/node_modules/process-warning/test/emit-interpolated-string.test.js @@ -0,0 +1,26 @@ +'use strict' + +const test = require('tap').test +const build = require('..') + +test('emit with interpolated string', t => { + t.plan(4) + const { create, emit, emitted } = build() + + process.on('warning', onWarning) + function onWarning (warning) { + t.equal(warning.name, 'FastifyDeprecation') + t.equal(warning.code, 'CODE') + t.equal(warning.message, 'Hello world') + t.ok(emitted.get('CODE')) + } + + create('FastifyDeprecation', 'CODE', 'Hello %s') + emit('CODE', 'world') + emit('CODE', 'world') + + setImmediate(() => { + process.removeListener('warning', onWarning) + t.end() + }) +}) diff --git a/node_modules/process-warning/test/emit-once-only.test.js b/node_modules/process-warning/test/emit-once-only.test.js new file mode 100644 index 0000000..e1d8a30 --- /dev/null +++ b/node_modules/process-warning/test/emit-once-only.test.js @@ -0,0 +1,26 @@ +'use strict' + +const test = require('tap').test +const build = require('..') + +test('emit should emit a given code only once', t => { + t.plan(4) + + const { create, emit, emitted } = build() + + process.on('warning', onWarning) + function onWarning (warning) { + t.equal(warning.name, 'FastifyDeprecation') + t.equal(warning.code, 'CODE') + t.equal(warning.message, 'Hello world') + t.ok(emitted.get('CODE')) + } + + create('FastifyDeprecation', 'CODE', 'Hello world') + emit('CODE') + emit('CODE') + setImmediate(() => { + process.removeListener('warning', onWarning) + t.end() + }) +}) diff --git a/node_modules/process-warning/test/emit-unlimited.test.js b/node_modules/process-warning/test/emit-unlimited.test.js new file mode 100644 index 0000000..b5ff28b --- /dev/null +++ b/node_modules/process-warning/test/emit-unlimited.test.js @@ -0,0 +1,34 @@ +'use strict' + +const test = require('tap').test +const build = require('..') + +test('emit should emit a given code unlimited times', t => { + t.plan(50) + + const { create, emit, emitted } = build() + + let runs = 0 + const expectedRun = [] + const times = 10 + + process.on('warning', onWarning) + function onWarning (warning) { + t.equal(warning.name, 'FastifyDeprecation') + t.equal(warning.code, 'CODE') + t.equal(warning.message, 'Hello world') + t.ok(emitted.get('CODE')) + t.equal(runs++, expectedRun.shift()) + } + + create('FastifyDeprecation', 'CODE', 'Hello world', { unlimited: true }) + + for (let i = 0; i < times; i++) { + expectedRun.push(i) + emit('CODE') + } + setImmediate(() => { + process.removeListener('warning', onWarning) + t.end() + }) +}) diff --git a/node_modules/process-warning/test/index.test.js b/node_modules/process-warning/test/index.test.js new file mode 100644 index 0000000..4765b12 --- /dev/null +++ b/node_modules/process-warning/test/index.test.js @@ -0,0 +1,110 @@ +'use strict' + +const test = require('tap').test +const build = require('..') + +process.removeAllListeners('warning') + +test('Create warning with zero parameter', t => { + t.plan(3) + + const { create } = build() + const buildWarnOpts = create('FastifyWarning', 'CODE', 'Not available') + const opts = buildWarnOpts() + t.equal(opts.name, 'FastifyWarning') + t.equal(opts.message, 'Not available') + t.equal(opts.code, 'CODE') +}) + +test('Create error with 1 parameter', t => { + t.plan(3) + + const { create } = build() + const buildWarningOpts = create('FastifyWarning', 'CODE', 'hey %s') + const opts = buildWarningOpts('alice') + t.equal(opts.name, 'FastifyWarning') + t.equal(opts.message, 'hey alice') + t.equal(opts.code, 'CODE') +}) + +test('Create error with 2 parameters', t => { + t.plan(3) + + const { create } = build() + const buildWarnOpts = create('FastifyWarning', 'CODE', 'hey %s, I like your %s') + const opts = buildWarnOpts('alice', 'attitude') + t.equal(opts.name, 'FastifyWarning') + t.equal(opts.message, 'hey alice, I like your attitude') + t.equal(opts.code, 'CODE') +}) + +test('Create error with 3 parameters', t => { + t.plan(3) + + const { create } = build() + const buildWarnOpts = create('FastifyWarning', 'CODE', 'hey %s, I like your %s %s') + const opts = buildWarnOpts('alice', 'attitude', 'see you') + t.equal(opts.name, 'FastifyWarning') + t.equal(opts.message, 'hey alice, I like your attitude see you') + t.equal(opts.code, 'CODE') +}) + +test('Creates a deprecation warning', t => { + t.plan(3) + + const manager = build() + const builder = manager.createDeprecation('CODE', 'hello %s') + const warning = builder('world') + t.equal(warning.name, 'DeprecationWarning') + t.equal(warning.message, 'hello world') + t.equal(warning.code, 'CODE') +}) + +test('Should throw when error code has no fastify name', t => { + t.plan(1) + + const { create } = build() + + t.throws(() => create(), new Error('Warning name must not be empty')) +}) + +test('Should throw when error has no code', t => { + t.plan(1) + + const { create } = build() + + t.throws(() => create('name'), new Error('Warning code must not be empty')) +}) + +test('Should throw when error has no message', t => { + t.plan(1) + + const { create } = build() + + t.throws(() => create('name', 'code'), new Error('Warning message must not be empty')) +}) + +test('Should throw if emit is called with unknown code ', t => { + t.plan(1) + + const { emit } = build() + + t.throws(() => emit('CODE'), new Error('The code \'CODE\' does not exist')) +}) + +test('Cannot reuse the same code more than once', t => { + t.plan(1) + + const { create } = build() + create('FastifyWarning', 'CODE', 'Not available') + + t.throws(() => create('FastifyWarning', 'CODE', 'Not available'), new Error("The code 'CODE' already exist")) +}) + +test('Cannot set unlimited other than boolean', t => { + t.plan(1) + + const { create } = build() + + t.throws(() => create('FastifyWarning', 'CODE', 'Msg', { unlimited: 42 }), new Error('Warning opts.unlimited must be a boolean')) +}) diff --git a/node_modules/process-warning/test/jest.test.js b/node_modules/process-warning/test/jest.test.js new file mode 100644 index 0000000..b02660d --- /dev/null +++ b/node_modules/process-warning/test/jest.test.js @@ -0,0 +1,20 @@ +/* global test, expect */ +'use strict' + +const build = require('..') + +test('works with jest', done => { + const { create, emit, emitted } = build() + + create('FastifyDeprecation', 'CODE', 'Hello %s') + emit('CODE', 'world') + + // we cannot actually listen to process warning event + // because jest messes with it (that's the point of this test) + // we can only test it was emitted indirectly + // and test no exception is raised + setImmediate(() => { + expect(emitted.get('CODE')).toBeTruthy() + done() + }) +}) diff --git a/node_modules/process-warning/test/no-warnings.test.js b/node_modules/process-warning/test/no-warnings.test.js new file mode 100644 index 0000000..4622cf0 --- /dev/null +++ b/node_modules/process-warning/test/no-warnings.test.js @@ -0,0 +1,80 @@ +'use strict' + +const { test } = require('tap') +const { spawnSync } = require('child_process') +const { resolve } = require('path') + +const entry = resolve(__dirname, '../examples', 'example.js') + +test('--no-warnings is set in cli', t => { + t.plan(1) + const child = spawnSync(process.execPath, [ + '--no-warnings', + entry + ]) + + const stderr = child.stderr.toString() + t.equal(stderr, '') +}) + +test('--no-warnings is not set in cli', t => { + t.plan(1) + const child = spawnSync(process.execPath, [ + entry + ]) + + const stderr = child.stderr.toString() + t.match(stderr, /\[CUSTDEP001\] DeprecationWarning: This is a deprecation warning/) +}) + +test('NODE_NO_WARNINGS is set to 1', t => { + t.plan(1) + const child = spawnSync(process.execPath, [ + entry + ], { + env: { + NODE_NO_WARNINGS: '1' + } + }) + + const stderr = child.stderr.toString() + t.equal(stderr, '') +}) + +test('NODE_NO_WARNINGS is set to 0', t => { + t.plan(1) + const child = spawnSync(process.execPath, [ + entry + ], { + env: { + NODE_NO_WARNINGS: '0' + } + }) + + const stderr = child.stderr.toString() + t.match(stderr, /\[CUSTDEP001\] DeprecationWarning: This is a deprecation warning/) +}) + +test('NODE_NO_WARNINGS is not set', t => { + t.plan(1) + const child = spawnSync(process.execPath, [ + entry + ]) + + const stderr = child.stderr.toString() + t.match(stderr, /\[CUSTDEP001\] DeprecationWarning: This is a deprecation warning/) +}) + +test('NODE_Options contains --no-warnings', t => { + t.plan(1) + const child = spawnSync(process.execPath, [ + entry + ], { + env: { + NODE_OPTIONS: '--no-warnings' + } + }) + + const stderr = child.stderr.toString() + t.equal(stderr, '') +}) diff --git a/node_modules/process-warning/types/index.d.ts b/node_modules/process-warning/types/index.d.ts new file mode 100644 index 0000000..5ab6754 --- /dev/null +++ b/node_modules/process-warning/types/index.d.ts @@ -0,0 +1,27 @@ +type ProcessWarning = () => processWarning.Warning + +declare namespace processWarning { + export interface Warning { + create(name: string, code: string, message: string, opts?: ProcessWarningOptions): BuildWarnOptsFn, + emit(cod: string, a?: any, b?: any, c?: any): void, + emitted: Map + } + + export type BuildWarnOptsFn = (a?: any, b?: any, c?: any) => WarnOpts + + export type ProcessWarningOptions = { + unlimited?: boolean, + } + + export interface WarnOpts { + code: string; + name: string; + message: string; + } + + export const processWarning: ProcessWarning + export { processWarning as default } +} + +declare function processWarning(...params: Parameters): ReturnType +export = processWarning diff --git a/node_modules/process-warning/types/index.test-d.ts b/node_modules/process-warning/types/index.test-d.ts new file mode 100644 index 0000000..b229039 --- /dev/null +++ b/node_modules/process-warning/types/index.test-d.ts @@ -0,0 +1,17 @@ +import { expectType } from 'tsd' +import Warinig, { BuildWarnOptsFn, WarnOpts } from '..' + +const warning = Warinig() +const buildWarnOpts = warning.create('FastifyWarning', 'CODE', 'message') +expectType(buildWarnOpts) +const opts = buildWarnOpts() +expectType(opts) +expectType(opts.code) +expectType(opts.message) +expectType(opts.name) + +expectType(warning.emit('CODE')) +expectType>(warning.emitted) + +const buildWarnUnlimited = warning.create('FastifyWarning', 'CODE', 'message', { unlimited: true }) +expectType(buildWarnUnlimited) \ No newline at end of file diff --git a/node_modules/proxy-from-env/.eslintrc b/node_modules/proxy-from-env/.eslintrc new file mode 100644 index 0000000..a51449b --- /dev/null +++ b/node_modules/proxy-from-env/.eslintrc @@ -0,0 +1,29 @@ +{ + "env": { + "node": true + }, + "rules": { + "array-bracket-spacing": [2, "never"], + "block-scoped-var": 2, + "brace-style": [2, "1tbs"], + "camelcase": 1, + "computed-property-spacing": [2, "never"], + "curly": 2, + "eol-last": 2, + "eqeqeq": [2, "smart"], + "max-depth": [1, 3], + "max-len": [1, 80], + "max-statements": [1, 15], + "new-cap": 1, + "no-extend-native": 2, + "no-mixed-spaces-and-tabs": 2, + "no-trailing-spaces": 2, + "no-unused-vars": 1, + "no-use-before-define": [2, "nofunc"], + "object-curly-spacing": [2, "never"], + "quotes": [2, "single", "avoid-escape"], + "semi": [2, "always"], + "keyword-spacing": [2, {"before": true, "after": true}], + "space-unary-ops": 2 + } +} diff --git a/node_modules/proxy-from-env/.travis.yml b/node_modules/proxy-from-env/.travis.yml new file mode 100644 index 0000000..64a05f9 --- /dev/null +++ b/node_modules/proxy-from-env/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - node + - lts/* +script: + - npm run lint + # test-coverage will also run the tests, but does not print helpful output upon test failure. + # So we also run the tests separately. + - npm run test + - npm run test-coverage && cat coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf coverage diff --git a/node_modules/proxy-from-env/LICENSE b/node_modules/proxy-from-env/LICENSE new file mode 100644 index 0000000..8f25097 --- /dev/null +++ b/node_modules/proxy-from-env/LICENSE @@ -0,0 +1,20 @@ +The MIT License + +Copyright (C) 2016-2018 Rob Wu + +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. diff --git a/node_modules/proxy-from-env/README.md b/node_modules/proxy-from-env/README.md new file mode 100644 index 0000000..e82520c --- /dev/null +++ b/node_modules/proxy-from-env/README.md @@ -0,0 +1,131 @@ +# proxy-from-env + +[![Build Status](https://travis-ci.org/Rob--W/proxy-from-env.svg?branch=master)](https://travis-ci.org/Rob--W/proxy-from-env) +[![Coverage Status](https://coveralls.io/repos/github/Rob--W/proxy-from-env/badge.svg?branch=master)](https://coveralls.io/github/Rob--W/proxy-from-env?branch=master) + +`proxy-from-env` is a Node.js package that exports a function (`getProxyForUrl`) +that takes an input URL (a string or +[`url.parse`](https://nodejs.org/docs/latest/api/url.html#url_url_parsing)'s +return value) and returns the desired proxy URL (also a string) based on +standard proxy environment variables. If no proxy is set, an empty string is +returned. + +It is your responsibility to actually proxy the request using the given URL. + +Installation: + +```sh +npm install proxy-from-env +``` + +## Example +This example shows how the data for a URL can be fetched via the +[`http` module](https://nodejs.org/api/http.html), in a proxy-aware way. + +```javascript +var http = require('http'); +var parseUrl = require('url').parse; +var getProxyForUrl = require('proxy-from-env').getProxyForUrl; + +var some_url = 'http://example.com/something'; + +// // Example, if there is a proxy server at 10.0.0.1:1234, then setting the +// // http_proxy environment variable causes the request to go through a proxy. +// process.env.http_proxy = 'http://10.0.0.1:1234'; +// +// // But if the host to be proxied is listed in NO_PROXY, then the request is +// // not proxied (but a direct request is made). +// process.env.no_proxy = 'example.com'; + +var proxy_url = getProxyForUrl(some_url); // <-- Our magic. +if (proxy_url) { + // Should be proxied through proxy_url. + var parsed_some_url = parseUrl(some_url); + var parsed_proxy_url = parseUrl(proxy_url); + // A HTTP proxy is quite simple. It is similar to a normal request, except the + // path is an absolute URL, and the proxied URL's host is put in the header + // instead of the server's actual host. + httpOptions = { + protocol: parsed_proxy_url.protocol, + hostname: parsed_proxy_url.hostname, + port: parsed_proxy_url.port, + path: parsed_some_url.href, + headers: { + Host: parsed_some_url.host, // = host name + optional port. + }, + }; +} else { + // Direct request. + httpOptions = some_url; +} +http.get(httpOptions, function(res) { + var responses = []; + res.on('data', function(chunk) { responses.push(chunk); }); + res.on('end', function() { console.log(responses.join('')); }); +}); + +``` + +## Environment variables +The environment variables can be specified in lowercase or uppercase, with the +lowercase name having precedence over the uppercase variant. A variable that is +not set has the same meaning as a variable that is set but has no value. + +### NO\_PROXY + +`NO_PROXY` is a list of host names (optionally with a port). If the input URL +matches any of the entries in `NO_PROXY`, then the input URL should be fetched +by a direct request (i.e. without a proxy). + +Matching follows the following rules: + +- `NO_PROXY=*` disables all proxies. +- Space and commas may be used to separate the entries in the `NO_PROXY` list. +- If `NO_PROXY` does not contain any entries, then proxies are never disabled. +- If a port is added after the host name, then the ports must match. If the URL + does not have an explicit port name, the protocol's default port is used. +- Generally, the proxy is only disabled if the host name is an exact match for + an entry in the `NO_PROXY` list. The only exceptions are entries that start + with a dot or with a wildcard; then the proxy is disabled if the host name + ends with the entry. + +See `test.js` for examples of what should match and what does not. + +### \*\_PROXY + +The environment variable used for the proxy depends on the protocol of the URL. +For example, `https://example.com` uses the "https" protocol, and therefore the +proxy to be used is `HTTPS_PROXY` (_NOT_ `HTTP_PROXY`, which is _only_ used for +http:-URLs). + +The library is not limited to http(s), other schemes such as +`FTP_PROXY` (ftp:), +`WSS_PROXY` (wss:), +`WS_PROXY` (ws:) +are also supported. + +If present, `ALL_PROXY` is used as fallback if there is no other match. + + +## External resources +The exact way of parsing the environment variables is not codified in any +standard. This library is designed to be compatible with formats as expected by +existing software. +The following resources were used to determine the desired behavior: + +- cURL: + https://curl.haxx.se/docs/manpage.html#ENVIRONMENT + https://github.com/curl/curl/blob/4af40b3646d3b09f68e419f7ca866ff395d1f897/lib/url.c#L4446-L4514 + https://github.com/curl/curl/blob/4af40b3646d3b09f68e419f7ca866ff395d1f897/lib/url.c#L4608-L4638 + +- wget: + https://www.gnu.org/software/wget/manual/wget.html#Proxies + http://git.savannah.gnu.org/cgit/wget.git/tree/src/init.c?id=636a5f9a1c508aa39e35a3a8e9e54520a284d93d#n383 + http://git.savannah.gnu.org/cgit/wget.git/tree/src/retr.c?id=93c1517c4071c4288ba5a4b038e7634e4c6b5482#n1278 + +- W3: + https://www.w3.org/Daemon/User/Proxies/ProxyClients.html + +- Python's urllib: + https://github.com/python/cpython/blob/936135bb97fe04223aa30ca6e98eac8f3ed6b349/Lib/urllib/request.py#L755-L782 + https://github.com/python/cpython/blob/936135bb97fe04223aa30ca6e98eac8f3ed6b349/Lib/urllib/request.py#L2444-L2479 diff --git a/node_modules/proxy-from-env/index.js b/node_modules/proxy-from-env/index.js new file mode 100644 index 0000000..df75004 --- /dev/null +++ b/node_modules/proxy-from-env/index.js @@ -0,0 +1,108 @@ +'use strict'; + +var parseUrl = require('url').parse; + +var DEFAULT_PORTS = { + ftp: 21, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443, +}; + +var stringEndsWith = String.prototype.endsWith || function(s) { + return s.length <= this.length && + this.indexOf(s, this.length - s.length) !== -1; +}; + +/** + * @param {string|object} url - The URL, or the result from url.parse. + * @return {string} The URL of the proxy that should handle the request to the + * given URL. If no proxy is set, this will be an empty string. + */ +function getProxyForUrl(url) { + var parsedUrl = typeof url === 'string' ? parseUrl(url) : url || {}; + var proto = parsedUrl.protocol; + var hostname = parsedUrl.host; + var port = parsedUrl.port; + if (typeof hostname !== 'string' || !hostname || typeof proto !== 'string') { + return ''; // Don't proxy URLs without a valid scheme or host. + } + + proto = proto.split(':', 1)[0]; + // Stripping ports in this way instead of using parsedUrl.hostname to make + // sure that the brackets around IPv6 addresses are kept. + hostname = hostname.replace(/:\d*$/, ''); + port = parseInt(port) || DEFAULT_PORTS[proto] || 0; + if (!shouldProxy(hostname, port)) { + return ''; // Don't proxy URLs that match NO_PROXY. + } + + var proxy = + getEnv('npm_config_' + proto + '_proxy') || + getEnv(proto + '_proxy') || + getEnv('npm_config_proxy') || + getEnv('all_proxy'); + if (proxy && proxy.indexOf('://') === -1) { + // Missing scheme in proxy, default to the requested URL's scheme. + proxy = proto + '://' + proxy; + } + return proxy; +} + +/** + * Determines whether a given URL should be proxied. + * + * @param {string} hostname - The host name of the URL. + * @param {number} port - The effective port of the URL. + * @returns {boolean} Whether the given URL should be proxied. + * @private + */ +function shouldProxy(hostname, port) { + var NO_PROXY = + (getEnv('npm_config_no_proxy') || getEnv('no_proxy')).toLowerCase(); + if (!NO_PROXY) { + return true; // Always proxy if NO_PROXY is not set. + } + if (NO_PROXY === '*') { + return false; // Never proxy if wildcard is set. + } + + return NO_PROXY.split(/[,\s]/).every(function(proxy) { + if (!proxy) { + return true; // Skip zero-length hosts. + } + var parsedProxy = proxy.match(/^(.+):(\d+)$/); + var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy; + var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0; + if (parsedProxyPort && parsedProxyPort !== port) { + return true; // Skip if ports don't match. + } + + if (!/^[.*]/.test(parsedProxyHostname)) { + // No wildcards, so stop proxying if there is an exact match. + return hostname !== parsedProxyHostname; + } + + if (parsedProxyHostname.charAt(0) === '*') { + // Remove leading wildcard. + parsedProxyHostname = parsedProxyHostname.slice(1); + } + // Stop proxying if the hostname ends with the no_proxy host. + return !stringEndsWith.call(hostname, parsedProxyHostname); + }); +} + +/** + * Get the value for an environment variable. + * + * @param {string} key - The name of the environment variable. + * @return {string} The value of the environment variable. + * @private + */ +function getEnv(key) { + return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || ''; +} + +exports.getProxyForUrl = getProxyForUrl; diff --git a/node_modules/proxy-from-env/package.json b/node_modules/proxy-from-env/package.json new file mode 100644 index 0000000..be2b845 --- /dev/null +++ b/node_modules/proxy-from-env/package.json @@ -0,0 +1,34 @@ +{ + "name": "proxy-from-env", + "version": "1.1.0", + "description": "Offers getProxyForUrl to get the proxy URL for a URL, respecting the *_PROXY (e.g. HTTP_PROXY) and NO_PROXY environment variables.", + "main": "index.js", + "scripts": { + "lint": "eslint *.js", + "test": "mocha ./test.js --reporter spec", + "test-coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter spec" + }, + "repository": { + "type": "git", + "url": "https://github.com/Rob--W/proxy-from-env.git" + }, + "keywords": [ + "proxy", + "http_proxy", + "https_proxy", + "no_proxy", + "environment" + ], + "author": "Rob Wu (https://robwu.nl/)", + "license": "MIT", + "bugs": { + "url": "https://github.com/Rob--W/proxy-from-env/issues" + }, + "homepage": "https://github.com/Rob--W/proxy-from-env#readme", + "devDependencies": { + "coveralls": "^3.0.9", + "eslint": "^6.8.0", + "istanbul": "^0.4.5", + "mocha": "^7.1.0" + } +} diff --git a/node_modules/proxy-from-env/test.js b/node_modules/proxy-from-env/test.js new file mode 100644 index 0000000..abf6542 --- /dev/null +++ b/node_modules/proxy-from-env/test.js @@ -0,0 +1,483 @@ +/* eslint max-statements:0 */ +'use strict'; + +var assert = require('assert'); +var parseUrl = require('url').parse; + +var getProxyForUrl = require('./').getProxyForUrl; + +// Runs the callback with process.env temporarily set to env. +function runWithEnv(env, callback) { + var originalEnv = process.env; + process.env = env; + try { + callback(); + } finally { + process.env = originalEnv; + } +} + +// Defines a test case that checks whether getProxyForUrl(input) === expected. +function testProxyUrl(env, expected, input) { + assert(typeof env === 'object' && env !== null); + // Copy object to make sure that the in param does not get modified between + // the call of this function and the use of it below. + env = JSON.parse(JSON.stringify(env)); + + var title = 'getProxyForUrl(' + JSON.stringify(input) + ')' + + ' === ' + JSON.stringify(expected); + + // Save call stack for later use. + var stack = {}; + Error.captureStackTrace(stack, testProxyUrl); + // Only use the last stack frame because that shows where this function is + // called, and that is sufficient for our purpose. No need to flood the logs + // with an uninteresting stack trace. + stack = stack.stack.split('\n', 2)[1]; + + it(title, function() { + var actual; + runWithEnv(env, function() { + actual = getProxyForUrl(input); + }); + if (expected === actual) { + return; // Good! + } + try { + assert.strictEqual(expected, actual); // Create a formatted error message. + // Should not happen because previously we determined expected !== actual. + throw new Error('assert.strictEqual passed. This is impossible!'); + } catch (e) { + // Use the original stack trace, so we can see a helpful line number. + e.stack = e.message + stack; + throw e; + } + }); +} + +describe('getProxyForUrl', function() { + describe('No proxy variables', function() { + var env = {}; + testProxyUrl(env, '', 'http://example.com'); + testProxyUrl(env, '', 'https://example.com'); + testProxyUrl(env, '', 'ftp://example.com'); + }); + + describe('Invalid URLs', function() { + var env = {}; + env.ALL_PROXY = 'http://unexpected.proxy'; + testProxyUrl(env, '', 'bogus'); + testProxyUrl(env, '', '//example.com'); + testProxyUrl(env, '', '://example.com'); + testProxyUrl(env, '', '://'); + testProxyUrl(env, '', '/path'); + testProxyUrl(env, '', ''); + testProxyUrl(env, '', 'http:'); + testProxyUrl(env, '', 'http:/'); + testProxyUrl(env, '', 'http://'); + testProxyUrl(env, '', 'prototype://'); + testProxyUrl(env, '', 'hasOwnProperty://'); + testProxyUrl(env, '', '__proto__://'); + testProxyUrl(env, '', undefined); + testProxyUrl(env, '', null); + testProxyUrl(env, '', {}); + testProxyUrl(env, '', {host: 'x', protocol: 1}); + testProxyUrl(env, '', {host: 1, protocol: 'x'}); + }); + + describe('http_proxy and HTTP_PROXY', function() { + var env = {}; + env.HTTP_PROXY = 'http://http-proxy'; + + testProxyUrl(env, '', 'https://example'); + testProxyUrl(env, 'http://http-proxy', 'http://example'); + testProxyUrl(env, 'http://http-proxy', parseUrl('http://example')); + + // eslint-disable-next-line camelcase + env.http_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'http://example'); + }); + + describe('http_proxy with non-sensical value', function() { + var env = {}; + // Crazy values should be passed as-is. It is the responsibility of the + // one who launches the application that the value makes sense. + // TODO: Should we be stricter and perform validation? + env.HTTP_PROXY = 'Crazy \n!() { ::// }'; + testProxyUrl(env, 'Crazy \n!() { ::// }', 'http://wow'); + + // The implementation assumes that the HTTP_PROXY environment variable is + // somewhat reasonable, and if the scheme is missing, it is added. + // Garbage in, garbage out some would say... + env.HTTP_PROXY = 'crazy without colon slash slash'; + testProxyUrl(env, 'http://crazy without colon slash slash', 'http://wow'); + }); + + describe('https_proxy and HTTPS_PROXY', function() { + var env = {}; + // Assert that there is no fall back to http_proxy + env.HTTP_PROXY = 'http://unexpected.proxy'; + testProxyUrl(env, '', 'https://example'); + + env.HTTPS_PROXY = 'http://https-proxy'; + testProxyUrl(env, 'http://https-proxy', 'https://example'); + + // eslint-disable-next-line camelcase + env.https_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'https://example'); + }); + + describe('ftp_proxy', function() { + var env = {}; + // Something else than http_proxy / https, as a sanity check. + env.FTP_PROXY = 'http://ftp-proxy'; + + testProxyUrl(env, 'http://ftp-proxy', 'ftp://example'); + testProxyUrl(env, '', 'ftps://example'); + }); + + describe('all_proxy', function() { + var env = {}; + env.ALL_PROXY = 'http://catch-all'; + testProxyUrl(env, 'http://catch-all', 'https://example'); + + // eslint-disable-next-line camelcase + env.all_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'https://example'); + }); + + describe('all_proxy without scheme', function() { + var env = {}; + env.ALL_PROXY = 'noscheme'; + testProxyUrl(env, 'http://noscheme', 'http://example'); + testProxyUrl(env, 'https://noscheme', 'https://example'); + + // The module does not impose restrictions on the scheme. + testProxyUrl(env, 'bogus-scheme://noscheme', 'bogus-scheme://example'); + + // But the URL should still be valid. + testProxyUrl(env, '', 'bogus'); + }); + + describe('no_proxy empty', function() { + var env = {}; + env.HTTPS_PROXY = 'http://proxy'; + + // NO_PROXY set but empty. + env.NO_PROXY = ''; + testProxyUrl(env, 'http://proxy', 'https://example'); + + // No entries in NO_PROXY (comma). + env.NO_PROXY = ','; + testProxyUrl(env, 'http://proxy', 'https://example'); + + // No entries in NO_PROXY (whitespace). + env.NO_PROXY = ' '; + testProxyUrl(env, 'http://proxy', 'https://example'); + + // No entries in NO_PROXY (multiple whitespace / commas). + env.NO_PROXY = ',\t,,,\n, ,\r'; + testProxyUrl(env, 'http://proxy', 'https://example'); + }); + + describe('no_proxy=example (single host)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = 'example'; + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, '', 'http://example:80'); + testProxyUrl(env, '', 'http://example:0'); + testProxyUrl(env, '', 'http://example:1337'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, 'http://proxy', 'http://a.b.example'); + testProxyUrl(env, 'http://proxy', 'http://host/example'); + }); + + describe('no_proxy=sub.example (subdomain)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = 'sub.example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://example:80'); + testProxyUrl(env, 'http://proxy', 'http://example:0'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://no.sub.example'); + testProxyUrl(env, 'http://proxy', 'http://sub-example'); + testProxyUrl(env, 'http://proxy', 'http://example.sub'); + }); + + describe('no_proxy=example:80 (host + port)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = 'example:80'; + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, '', 'http://example:80'); + testProxyUrl(env, '', 'http://example:0'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, 'http://proxy', 'http://a.b.example'); + }); + + describe('no_proxy=.example (host suffix)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '.example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://example:80'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, '', 'http://sub.example:80'); + testProxyUrl(env, '', 'http://sub.example:1337'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, '', 'http://a.b.example'); + }); + + describe('no_proxy=*', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + env.NO_PROXY = '*'; + testProxyUrl(env, '', 'http://example.com'); + }); + + describe('no_proxy=*.example (host suffix with *.)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '*.example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://example:80'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, '', 'http://sub.example:80'); + testProxyUrl(env, '', 'http://sub.example:1337'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, '', 'http://a.b.example'); + }); + + describe('no_proxy=*example (substring suffix)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '*example'; + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, '', 'http://example:80'); + testProxyUrl(env, '', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, '', 'http://sub.example:80'); + testProxyUrl(env, '', 'http://sub.example:1337'); + testProxyUrl(env, '', 'http://prefexample'); + testProxyUrl(env, '', 'http://a.b.example'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, 'http://proxy', 'http://host/example'); + }); + + describe('no_proxy=.*example (arbitrary wildcards are NOT supported)', + function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '.*example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://x.prefexample'); + testProxyUrl(env, 'http://proxy', 'http://a.b.example'); + }); + + describe('no_proxy=[::1],[::2]:80,10.0.0.1,10.0.0.2:80 (IP addresses)', + function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '[::1],[::2]:80,10.0.0.1,10.0.0.2:80'; + testProxyUrl(env, '', 'http://[::1]/'); + testProxyUrl(env, '', 'http://[::1]:80/'); + testProxyUrl(env, '', 'http://[::1]:1337/'); + + testProxyUrl(env, '', 'http://[::2]/'); + testProxyUrl(env, '', 'http://[::2]:80/'); + testProxyUrl(env, 'http://proxy', 'http://[::2]:1337/'); + + testProxyUrl(env, '', 'http://10.0.0.1/'); + testProxyUrl(env, '', 'http://10.0.0.1:80/'); + testProxyUrl(env, '', 'http://10.0.0.1:1337/'); + + testProxyUrl(env, '', 'http://10.0.0.2/'); + testProxyUrl(env, '', 'http://10.0.0.2:80/'); + testProxyUrl(env, 'http://proxy', 'http://10.0.0.2:1337/'); + }); + + describe('no_proxy=127.0.0.1/32 (CIDR is NOT supported)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '127.0.0.1/32'; + testProxyUrl(env, 'http://proxy', 'http://127.0.0.1'); + testProxyUrl(env, 'http://proxy', 'http://127.0.0.1/32'); + }); + + describe('no_proxy=127.0.0.1 does NOT match localhost', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '127.0.0.1'; + testProxyUrl(env, '', 'http://127.0.0.1'); + // We're not performing DNS queries, so this shouldn't match. + testProxyUrl(env, 'http://proxy', 'http://localhost'); + }); + + describe('no_proxy with protocols that have a default port', function() { + var env = {}; + env.WS_PROXY = 'http://ws'; + env.WSS_PROXY = 'http://wss'; + env.HTTP_PROXY = 'http://http'; + env.HTTPS_PROXY = 'http://https'; + env.GOPHER_PROXY = 'http://gopher'; + env.FTP_PROXY = 'http://ftp'; + env.ALL_PROXY = 'http://all'; + + env.NO_PROXY = 'xxx:21,xxx:70,xxx:80,xxx:443'; + + testProxyUrl(env, '', 'http://xxx'); + testProxyUrl(env, '', 'http://xxx:80'); + testProxyUrl(env, 'http://http', 'http://xxx:1337'); + + testProxyUrl(env, '', 'ws://xxx'); + testProxyUrl(env, '', 'ws://xxx:80'); + testProxyUrl(env, 'http://ws', 'ws://xxx:1337'); + + testProxyUrl(env, '', 'https://xxx'); + testProxyUrl(env, '', 'https://xxx:443'); + testProxyUrl(env, 'http://https', 'https://xxx:1337'); + + testProxyUrl(env, '', 'wss://xxx'); + testProxyUrl(env, '', 'wss://xxx:443'); + testProxyUrl(env, 'http://wss', 'wss://xxx:1337'); + + testProxyUrl(env, '', 'gopher://xxx'); + testProxyUrl(env, '', 'gopher://xxx:70'); + testProxyUrl(env, 'http://gopher', 'gopher://xxx:1337'); + + testProxyUrl(env, '', 'ftp://xxx'); + testProxyUrl(env, '', 'ftp://xxx:21'); + testProxyUrl(env, 'http://ftp', 'ftp://xxx:1337'); + }); + + describe('no_proxy should not be case-sensitive', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + env.NO_PROXY = 'XXX,YYY,ZzZ'; + + testProxyUrl(env, '', 'http://xxx'); + testProxyUrl(env, '', 'http://XXX'); + testProxyUrl(env, '', 'http://yyy'); + testProxyUrl(env, '', 'http://YYY'); + testProxyUrl(env, '', 'http://ZzZ'); + testProxyUrl(env, '', 'http://zZz'); + }); + + describe('NPM proxy configuration', function() { + describe('npm_config_http_proxy should work', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://http-proxy'; + + testProxyUrl(env, '', 'https://example'); + testProxyUrl(env, 'http://http-proxy', 'http://example'); + + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'http://example'); + }); + // eslint-disable-next-line max-len + describe('npm_config_http_proxy should take precedence over HTTP_PROXY and npm_config_proxy', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://http-proxy'; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://unexpected-proxy'; + env.HTTP_PROXY = 'http://unexpected-proxy'; + + testProxyUrl(env, 'http://http-proxy', 'http://example'); + }); + describe('npm_config_https_proxy should work', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://unexpected.proxy'; + testProxyUrl(env, '', 'https://example'); + + // eslint-disable-next-line camelcase + env.npm_config_https_proxy = 'http://https-proxy'; + testProxyUrl(env, 'http://https-proxy', 'https://example'); + + // eslint-disable-next-line camelcase + env.npm_config_https_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'https://example'); + }); + // eslint-disable-next-line max-len + describe('npm_config_https_proxy should take precedence over HTTPS_PROXY and npm_config_proxy', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_https_proxy = 'http://https-proxy'; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://unexpected-proxy'; + env.HTTPS_PROXY = 'http://unexpected-proxy'; + + testProxyUrl(env, 'http://https-proxy', 'https://example'); + }); + describe('npm_config_proxy should work', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://http-proxy'; + testProxyUrl(env, 'http://http-proxy', 'http://example'); + testProxyUrl(env, 'http://http-proxy', 'https://example'); + + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'http://example'); + testProxyUrl(env, 'http://priority', 'https://example'); + }); + // eslint-disable-next-line max-len + describe('HTTP_PROXY and HTTPS_PROXY should take precedence over npm_config_proxy', function() { + var env = {}; + env.HTTP_PROXY = 'http://http-proxy'; + env.HTTPS_PROXY = 'http://https-proxy'; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://unexpected-proxy'; + testProxyUrl(env, 'http://http-proxy', 'http://example'); + testProxyUrl(env, 'http://https-proxy', 'https://example'); + }); + describe('npm_config_no_proxy should work', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + // eslint-disable-next-line camelcase + env.npm_config_no_proxy = 'example'; + + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://otherwebsite'); + }); + // eslint-disable-next-line max-len + describe('npm_config_no_proxy should take precedence over NO_PROXY', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + env.NO_PROXY = 'otherwebsite'; + // eslint-disable-next-line camelcase + env.npm_config_no_proxy = 'example'; + + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://otherwebsite'); + }); + }); +}); diff --git a/node_modules/vasync/.gitmodules b/node_modules/vasync/.gitmodules new file mode 100644 index 0000000..d2c7b86 --- /dev/null +++ b/node_modules/vasync/.gitmodules @@ -0,0 +1,6 @@ +[submodule "deps/jsstyle"] + path = deps/jsstyle + url = https://github.com/joyent/jsstyle.git +[submodule "deps/javascriptlint"] + path = deps/javascriptlint + url = https://github.com/joyent/javascriptlint.git diff --git a/node_modules/vasync/CHANGES.md b/node_modules/vasync/CHANGES.md new file mode 100644 index 0000000..cd72b86 --- /dev/null +++ b/node_modules/vasync/CHANGES.md @@ -0,0 +1,39 @@ +# Changelog + +## Not yet released + +None yet. + +## v2.2.0 + +* #37 want whilst + +## v2.1.0 + +* #33 want filter, filterLimit, and filterSeries +* #35 pipeline does not pass rv-object to final callback + + +## v2.0.0 + +** WARNING + +Do not use this version (v2.0.0), as it has broken pipeline and forEachPipeline +functions. + +**Breaking Changes:** + +* The `waterfall` function's terminating callback no longer receives a + status-object as its second argument. This is the behavior of `node-async` + and we wish to match it as closely as possible. If you used the second + argument of waterfall's terminating callback (instead of waterfall's return + value) to extract job-statuses, this will break you. More specifically, this + is only true if you called `waterfall` on an empty array of function. + +**Other Changes:** + +* #32 Would like a tryEach function. + +## v1 and earlier + +Major version 1 and earlier did not have their changes logged in a changelog. diff --git a/node_modules/vasync/Jenkinsfile b/node_modules/vasync/Jenkinsfile new file mode 100644 index 0000000..32ae6c6 --- /dev/null +++ b/node_modules/vasync/Jenkinsfile @@ -0,0 +1,86 @@ +@Library('jenkins-joylib@v1.0.8') _ + +pipeline { + + agent none + + options { + buildDiscarder(logRotator(numToKeepStr: '30')) + timestamps() + } + + stages { + stage('top') { + parallel { + stage('v0.10.48-zone') { + agent { + label joyCommonLabels(image_ver: '15.4.1') + } + tools { + nodejs 'sdcnode-v0.10.48-zone' + } + stages { + stage('check') { + steps{ + sh('make check') + } + } + stage('test') { + steps{ + sh('make all test') + } + } + } + } + + stage('v4-zone') { + agent { + label joyCommonLabels(image_ver: '15.4.1') + } + tools { + nodejs 'sdcnode-v4-zone' + } + stages { + stage('check') { + steps{ + sh('make check') + } + } + stage('test') { + steps{ + sh('make all test') + } + } + } + } + + stage('v6-zone64') { + agent { + label joyCommonLabels(image_ver: '18.4.0') + } + tools { + nodejs 'sdcnode-v6-zone64' + } + stages { + stage('check') { + steps{ + sh('make check') + } + } + stage('test') { + steps{ + sh('make all test') + } + } + } + } + } + } + } + + post { + always { + joySlackNotifications() + } + } +} diff --git a/node_modules/vasync/LICENSE b/node_modules/vasync/LICENSE new file mode 100644 index 0000000..dd1ab14 --- /dev/null +++ b/node_modules/vasync/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2014, Joyent, Inc. All rights reserved. +Compatibility tests copyright (c) 2010-2014 Caolan McMahon. + +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 diff --git a/node_modules/vasync/Makefile b/node_modules/vasync/Makefile new file mode 100644 index 0000000..7fb2bc6 --- /dev/null +++ b/node_modules/vasync/Makefile @@ -0,0 +1,25 @@ +# +# Copyright (c) 2021, Joyent, Inc. All rights reserved. +# +# Makefile: top-level Makefile +# +# This Makefile contains only repo-specific logic and uses included makefiles +# to supply common targets (javascriptlint, jsstyle, restdown, etc.), which are +# used by other repos as well. +# + +# +# Files +# +JS_FILES := $(shell find lib tests -name '*.js' -not -name compat\*.js) +JSL_FILES_NODE = $(JS_FILES) +JSSTYLE_FILES = $(JS_FILES) +JSL_CONF_NODE = jsl.node.conf + +all: + npm install + +test: all + npm test + +include ./Makefile.targ diff --git a/node_modules/vasync/Makefile.targ b/node_modules/vasync/Makefile.targ new file mode 100644 index 0000000..caa5ce5 --- /dev/null +++ b/node_modules/vasync/Makefile.targ @@ -0,0 +1,289 @@ +# -*- mode: makefile -*- +# +# Copyright (c) 2021, Joyent, Inc. All rights reserved. +# +# Makefile.targ: common targets. +# +# NOTE: This makefile comes from the "eng" repo. It's designed to be dropped +# into other repos as-is without requiring any modifications. If you find +# yourself changing this file, you should instead update the original copy in +# eng.git and then update your repo to use the new version. +# +# This Makefile defines several useful targets and rules. You can use it by +# including it from a Makefile that specifies some of the variables below. +# +# Targets defined in this Makefile: +# +# check Checks JavaScript files for lint and style +# Checks bash scripts for syntax +# Checks SMF manifests for validity against the SMF DTD +# +# clean Removes built files +# +# docs Builds restdown documentation in docs/ +# +# prepush Depends on "check" and "test" +# +# test Does nothing (you should override this) +# +# xref Generates cscope (source cross-reference index) +# +# For details on what these targets are supposed to do, see the Joyent +# Engineering Guide. +# +# To make use of these targets, you'll need to set some of these variables. Any +# variables left unset will simply not be used. +# +# BASH_FILES Bash scripts to check for syntax +# (paths relative to top-level Makefile) +# +# CLEAN_FILES Files to remove as part of the "clean" target. Note +# that files generated by targets in this Makefile are +# automatically included in CLEAN_FILES. These include +# restdown-generated HTML and JSON files. +# +# DOC_FILES Restdown (documentation source) files. These are +# assumed to be contained in "docs/", and must NOT +# contain the "docs/" prefix. +# +# JSL_CONF_NODE Specify JavaScriptLint configuration files +# JSL_CONF_WEB (paths relative to top-level Makefile) +# +# Node.js and Web configuration files are separate +# because you'll usually want different global variable +# configurations. If no file is specified, none is given +# to jsl, which causes it to use a default configuration, +# which probably isn't what you want. +# +# JSL_FILES_NODE JavaScript files to check with Node config file. +# JSL_FILES_WEB JavaScript files to check with Web config file. +# +# You can also override these variables: +# +# BASH Path to bash (default: bash) +# +# CSCOPE_DIRS Directories to search for source files for the cscope +# index. (default: ".") +# +# JSL Path to JavaScriptLint (default: "jsl") +# +# JSL_FLAGS_NODE Additional flags to pass through to JSL +# JSL_FLAGS_WEB +# JSL_FLAGS +# +# JSSTYLE Path to jsstyle (default: jsstyle) +# +# JSSTYLE_FLAGS Additional flags to pass through to jsstyle +# + +# +# Defaults for the various tools we use. +# +BASH ?= bash +BASHSTYLE ?= tools/bashstyle +CP ?= cp +CSCOPE ?= cscope +CSCOPE_DIRS ?= . +JSL_EXEC ?= deps/javascriptlint/build/install/jsl +JSL ?= $(JSL_EXEC) +JSSTYLE ?= deps/jsstyle/jsstyle +MKDIR ?= mkdir -p +MV ?= mv +RESTDOWN_FLAGS ?= +RMTREE ?= rm -rf +JSL_FLAGS ?= --nologo --nosummary + +ifeq ($(shell uname -s),SunOS) + TAR ?= gtar +else + TAR ?= tar +endif + + +# +# Defaults for other fixed values. +# +BUILD = build +DISTCLEAN_FILES += $(BUILD) +DOC_BUILD = $(BUILD)/docs/public + +# +# Configure JSL_FLAGS_{NODE,WEB} based on JSL_CONF_{NODE,WEB}. +# +ifneq ($(origin JSL_CONF_NODE), undefined) + JSL_FLAGS_NODE += --conf=$(JSL_CONF_NODE) +endif + +ifneq ($(origin JSL_CONF_WEB), undefined) + JSL_FLAGS_WEB += --conf=$(JSL_CONF_WEB) +endif + +# +# Targets. For descriptions on what these are supposed to do, see the +# Joyent Engineering Guide. +# + +# +# Instruct make to keep around temporary files. We have rules below that +# automatically update git submodules as needed, but they employ a deps/*/.git +# temporary file. Without this directive, make tries to remove these .git +# directories after the build has completed. +# +.SECONDARY: $($(wildcard deps/*):%=%/.git) + +# +# This rule enables other rules that use files from a git submodule to have +# those files depend on deps/module/.git and have "make" automatically check +# out the submodule as needed. +# +deps/%/.git: + git submodule update --init deps/$* + +# +# These recipes make heavy use of dynamically-created phony targets. The parent +# Makefile defines a list of input files like BASH_FILES. We then say that each +# of these files depends on a fake target called filename.bashchk, and then we +# define a pattern rule for those targets that runs bash in check-syntax-only +# mode. This mechanism has the nice properties that if you specify zero files, +# the rule becomes a noop (unlike a single rule to check all bash files, which +# would invoke bash with zero files), and you can check individual files from +# the command line with "make filename.bashchk". +# +.PHONY: check-bash +check-bash: $(BASH_FILES:%=%.bashchk) $(BASH_FILES:%=%.bashstyle) + +%.bashchk: % + $(BASH) -n $^ + +%.bashstyle: % + $(BASHSTYLE) $^ + +$(JSL_EXEC): + make -C deps/javascriptlint install + +.PHONY: check-jsl check-jsl-node check-jsl-web +check-jsl: check-jsl-node check-jsl-web + +check-jsl-node: $(JSL_FILES_NODE:%=%.jslnodechk) + +check-jsl-web: $(JSL_FILES_WEB:%=%.jslwebchk) + +%.jslnodechk: % $(JSL_EXEC) + $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_NODE) $< + +%.jslwebchk: % $(JSL_EXEC) + $(JSL) $(JSL_FLAGS) $(JSL_FLAGS_WEB) $< + +.PHONY: check-jsstyle +check-jsstyle: $(JSSTYLE_FILES:%=%.jsstylechk) + +%.jsstylechk: % $(JSSTYLE_EXEC) + $(JSSTYLE) $(JSSTYLE_FLAGS) $< + +.PHONY: check +check: check-jsl check-jsstyle check-bash + @echo check ok + +.PHONY: clean +clean:: + -$(RMTREE) $(CLEAN_FILES) + +.PHONY: distclean +distclean:: clean + -$(RMTREE) $(DISTCLEAN_FILES) + +CSCOPE_FILES = cscope.in.out cscope.out cscope.po.out +CLEAN_FILES += $(CSCOPE_FILES) + +.PHONY: xref +xref: cscope.files + $(CSCOPE) -bqR + +.PHONY: cscope.files +cscope.files: + find $(CSCOPE_DIRS) -name '*.c' -o -name '*.h' -o -name '*.cc' \ + -o -name '*.js' -o -name '*.s' -o -name '*.cpp' > $@ + +# +# The "docs" target is complicated because we do several things here: +# +# (1) Use restdown to build HTML and JSON files from each of DOC_FILES. +# +# (2) Copy these files into $(DOC_BUILD) (build/docs/public), which +# functions as a complete copy of the documentation that could be +# mirrored or served over HTTP. +# +# (3) Then copy any directories and media from docs/media into +# $(DOC_BUILD)/media. This allows projects to include their own media, +# including files that will override same-named files provided by +# restdown. +# +# Step (3) is the surprisingly complex part: in order to do this, we need to +# identify the subdirectories in docs/media, recreate them in +# $(DOC_BUILD)/media, then do the same with the files. +# +DOC_MEDIA_DIRS := $(shell find docs/media -type d 2>/dev/null | grep -v "^docs/media$$") +DOC_MEDIA_DIRS := $(DOC_MEDIA_DIRS:docs/media/%=%) +DOC_MEDIA_DIRS_BUILD := $(DOC_MEDIA_DIRS:%=$(DOC_BUILD)/media/%) + +DOC_MEDIA_FILES := $(shell find docs/media -type f 2>/dev/null) +DOC_MEDIA_FILES := $(DOC_MEDIA_FILES:docs/media/%=%) +DOC_MEDIA_FILES_BUILD := $(DOC_MEDIA_FILES:%=$(DOC_BUILD)/media/%) + +# +# Like the other targets, "docs" just depends on the final files we want to +# create in $(DOC_BUILD), leveraging other targets and recipes to define how +# to get there. +# +.PHONY: docs +docs: \ + $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.html) \ + $(DOC_FILES:%.restdown=$(DOC_BUILD)/%.json) \ + $(DOC_MEDIA_FILES_BUILD) + +# +# We keep the intermediate files so that the next build can see whether the +# files in DOC_BUILD are up to date. +# +.PRECIOUS: \ + $(DOC_FILES:%.restdown=docs/%.html) \ + $(DOC_FILES:%.restdown=docs/%json) + +# +# We do clean those intermediate files, as well as all of DOC_BUILD. +# +CLEAN_FILES += \ + $(DOC_BUILD) \ + $(DOC_FILES:%.restdown=docs/%.html) \ + $(DOC_FILES:%.restdown=docs/%.json) + +# +# Before installing the files, we must make sure the directories exist. The | +# syntax tells make that the dependency need only exist, not be up to date. +# Otherwise, it might try to rebuild spuriously because the directory itself +# appears out of date. +# +$(DOC_MEDIA_FILES_BUILD): | $(DOC_MEDIA_DIRS_BUILD) + +$(DOC_BUILD)/%: docs/% | $(DOC_BUILD) + $(CP) $< $@ + +docs/%.json docs/%.html: docs/%.restdown | $(DOC_BUILD) $(RESTDOWN_EXEC) + $(RESTDOWN) $(RESTDOWN_FLAGS) -m $(DOC_BUILD) $< + +$(DOC_BUILD): + $(MKDIR) $@ + +$(DOC_MEDIA_DIRS_BUILD): + $(MKDIR) $@ + +# +# The default "test" target does nothing. This should usually be overridden by +# the parent Makefile. It's included here so we can define "prepush" without +# requiring the repo to define "test". +# +.PHONY: test +test: + +.PHONY: prepush +prepush: check test diff --git a/node_modules/vasync/README.md b/node_modules/vasync/README.md new file mode 100644 index 0000000..b327fb8 --- /dev/null +++ b/node_modules/vasync/README.md @@ -0,0 +1,773 @@ +# vasync: observable asynchronous control flow + +This module provides several functions for asynchronous control flow. There are +many modules that do this already (notably async.js). This one's claim to fame +is improved debuggability. + + +## Observability is important + +Working with Node's asynchronous, callback-based model is much easier with a +handful of simple control-flow abstractions, like: + +* waterfalls and pipelines (which invoke a list of asynchronous callbacks + sequentially) +* parallel pipelines (which invoke a list of asynchronous callbacks in parallel + and invoke a top-level callback when the last one completes). +* queues +* barriers + +But these structures also introduce new types of programming errors: failing to +invoke the callback can cause the program to hang, and inadvertently invoking it +twice can cause all kinds of mayhem that's very difficult to debug. + +The functions in this module keep track of what's going on so that you can +figure out what happened when your program goes wrong. They generally return an +object describing details of the current state. If your program goes wrong, you +have several ways of getting at this state: + +* On illumos-based systems, use MDB to [find the status object](http://dtrace.org/blogs/bmc/2012/05/05/debugging-node-js-memory-leaks/) + and then [print it out](http://dtrace.org/blogs/dap/2012/01/13/playing-with-nodev8-postmortem-debugging/). +* Provide an HTTP API (or AMQP, or whatever) that returns these pending status + objects as JSON (see [kang](https://github.com/davepacheco/kang)). +* Incorporate a REPL into your program and print out the status object. +* Use the Node debugger to print out the status object. + +## Functions + +* [parallel](#parallel-invoke-n-functions-in-parallel): invoke N functions in + parallel (and merge the results) +* [forEachParallel](#foreachparallel-invoke-the-same-function-on-n-inputs-in-parallel): + invoke the same function on N inputs in parallel +* [pipeline](#pipeline-invoke-n-functions-in-series-and-stop-on-failure): invoke + N functions in series (and stop on failure) +* [tryEach](#tryeach-invoke-n-functions-in-series-and-stop-on-success): invoke + N functions in series (and stop on success) +* [forEachPipeline](#foreachpipeline-invoke-the-same-function-on-n-inputs-in-series-and-stop-on-failure): + invoke the same function on N inputs in series (and stop on failure) +* [filter/filterSeries/filterLimit](#filterfilterlimitfilterseries-filter-n-inputs-serially-or-concurrently): + filter N inputs serially or concurrently +* [whilst](#whilst-invoke-a-function-repeatedly-until-a-stopping-condition-is-met): + invoke a function repeatedly until a stopping condition is met +* [waterfall](#waterfall-invoke-n-functions-in-series-stop-on-failure-and-propagate-results): + like pipeline, but propagating results between stages +* [barrier](#barrier-coordinate-multiple-concurrent-operations): coordinate + multiple concurrent operations +* [queue/queuev](#queuequeuev-fixed-size-worker-queue): fixed-size worker queue + +### parallel: invoke N functions in parallel + +Synopsis: `parallel(args, callback)` + +This function takes a list of input functions (specified by the "funcs" property +of "args") and runs them all. These input functions are expected to be +asynchronous: they get a "callback" argument and should invoke it as +`callback(err, result)`. The error and result will be saved and made available +to the original caller when all of these functions complete. + +This function returns the same "result" object it passes to the callback, and +you can use the fields in this object to debug or observe progress: + +* `operations`: array corresponding to the input functions, with + * `func`: input function, + * `status`: "pending", "ok", or "fail", + * `err`: returned "err" value, if any, and + * `result`: returned "result" value, if any +* `successes`: "result" field for each of "operations" where + "status" == "ok" (in no particular order) +* `ndone`: number of input operations that have completed +* `nerrors`: number of input operations that have failed + +This status object lets you see in a debugger exactly which functions have +completed, what they returned, and which ones are outstanding. + +All errors are combined into a single "err" parameter to the final callback (see +below). + +Example usage: + +```js +console.log(mod_vasync.parallel({ + 'funcs': [ + function f1 (callback) { mod_dns.resolve('joyent.com', callback); }, + function f2 (callback) { mod_dns.resolve('github.com', callback); }, + function f3 (callback) { mod_dns.resolve('asdfaqsdfj.com', callback); } + ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); +``` + +In the first tick, this outputs: + +```js +status: { operations: + [ { func: [Function: f1], status: 'pending' }, + { func: [Function: f2], status: 'pending' }, + { func: [Function: f3], status: 'pending' } ], + successes: [], + ndone: 0, + nerrors: 0 } +``` + +showing that there are three operations pending and none has yet been started. +When the program finishes, it outputs this error: + + error: first of 1 error: queryA ENOTFOUND + +which encapsulates all of the intermediate failures. This model allows you to +write the final callback like you normally would: + +```js +if (err) + return (callback(err)); +``` + +and still propagate useful information to callers that don't deal with multiple +errors (i.e. most callers). + +The example also prints out the detailed final status, including all of the +errors and return values: + +```js +results: { operations: + [ { func: [Function: f1], + funcname: 'f1', + status: 'ok', + err: null, + result: [ '165.225.132.33' ] }, + { func: [Function: f2], + funcname: 'f2', + status: 'ok', + err: null, + result: [ '207.97.227.239' ] }, + { func: [Function: f3], + funcname: 'f3', + status: 'fail', + err: { [Error: queryA ENOTFOUND] code: 'ENOTFOUND', + errno: 'ENOTFOUND', syscall: 'queryA' }, + result: undefined } ], + successes: [ [ '165.225.132.33' ], [ '207.97.227.239' ] ], + ndone: 3, + nerrors: 1 } +``` + +You can use this if you want to handle all of the errors individually or to get +at all of the individual return values. + +Note that "successes" is provided as a convenience and the order of items in +that array may not correspond to the order of the inputs. To consume output in +an ordered manner, you should iterate over "operations" and pick out the result +from each item. + + +### forEachParallel: invoke the same function on N inputs in parallel + +Synopsis: `forEachParallel(args, callback)` + +This function is exactly like `parallel`, except that the input is specified as +a *single* function ("func") and a list of inputs ("inputs"). The function is +invoked on each input in parallel. + +This example is exactly equivalent to the one above: + +```js +console.log(mod_vasync.forEachParallel({ + 'func': mod_dns.resolve, + 'inputs': [ 'joyent.com', 'github.com', 'asdfaqsdfj.com' ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); +``` + +### pipeline: invoke N functions in series (and stop on failure) + +Synopsis: `pipeline(args, callback)` + +The named arguments (that go inside `args`) are: + +* `funcs`: input functions, to be invoked in series +* `arg`: arbitrary argument that will be passed to each function + +The functions are invoked in order as `func(arg, callback)`, where "arg" is the +user-supplied argument from "args" and "callback" should be invoked in the usual +way. If any function emits an error, the whole pipeline stops. + +The return value and the arguments to the final callback are exactly the same as +for `parallel`. The error object for the final callback is just the error +returned by whatever pipeline function failed (if any). + +This example is similar to the one above, except that it runs the steps in +sequence and stops early because `pipeline` stops on the first error: + +```js +console.log(mod_vasync.pipeline({ + 'funcs': [ + function f1 (_, callback) { mod_fs.stat('/tmp', callback); }, + function f2 (_, callback) { mod_fs.stat('/noexist', callback); }, + function f3 (_, callback) { mod_fs.stat('/var', callback); } + ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); +``` + +As a result, the status after the first tick looks like this: + +```js +{ operations: + [ { func: [Function: f1], status: 'pending' }, + { func: [Function: f2], status: 'waiting' }, + { func: [Function: f3], status: 'waiting' } ], + successes: [], + ndone: 0, + nerrors: 0 } +``` + +Note that the second and third stages are now "waiting", rather than "pending" +in the `parallel` case. The error and complete result look just like the +parallel case. + +### tryEach: invoke N functions in series (and stop on success) + +Synopsis: `tryEach(funcs, callback)` + +The `tryEach` function invokes each of the asynchronous functions in `funcs` +serially. Each function takes a single argument: an interstitial-callback. +`tryEach` will keep calling the functions until one of them succeeds (or they +all fail). At the end, the terminating-callback is invoked with the error +and/or results provided by the last function that was called (either the last +one that failed or the first one that succeeded). + +This example is similar to the one above, except that it runs the steps in +sequence and stops early because `tryEach` stops on the first success: + +```js +console.log(mod_vasync.tryEach([ + function f1 (callback) { mod_fs.stat('/notreal', callback); }, + function f2 (callback) { mod_fs.stat('/noexist', callback); }, + function f3 (callback) { mod_fs.stat('/var', callback); }, + function f4 (callback) { mod_fs.stat('/noexist', callback); } + ], + function (err, results) { + console.log('error: %s', err); + console.log('results: %s', mod_util.inspect(results)); +})); + +``` + +The above code will stop when it finishes f3, and we will only print a single +result and no errors: + +```js +error: null +results: { dev: 65760, + mode: 16877, + nlink: 41, + uid: 0, + gid: 3, + rdev: -1, + blksize: 2560, + ino: 11, + size: 41, + blocks: 7, + atime: Thu May 28 2015 16:21:25 GMT+0000 (UTC), + mtime: Thu Jan 21 2016 22:08:50 GMT+0000 (UTC), + ctime: Thu Jan 21 2016 22:08:50 GMT+0000 (UTC) } +``` + +If we comment out `f3`, we get the following output: + +```js +error: Error: ENOENT, stat '/noexist' +results: undefined +``` + +Note that: there is a mismatch (inherited from `async`) between the semantics +of the interstitial callback and the sematics of the terminating callback. See +the following example: + +```js +console.log(mod_vasync.tryEach([ + function f1 (callback) { callback(new Error()); }, + function f2 (callback) { callback(new Error()); }, + function f3 (callback) { callback(null, 1, 2, 3); }, + function f4 (callback) { callback(null, 1); } + ], + function (err, results) { + console.log('error: %s', err); + console.log('results: %s', mod_util.inspect(results)); +})); + +``` + +We pass one or more results to the terminating-callback via the +interstitial-callback's arglist -- `(err, res1, res2, ...)`. From the +callback-implementor's perspective, the results get wrapped up in an array +`(err, [res1, res2, ...])` -- unless there is only one result, which simply +gets passed through as the terminating callback's second argument. This means +that when we call the callback in `f3` above, the terminating callback receives +the list `[1, 2, 3]` as its second argument. If, we comment out `f3`, we will +end up calling the callback in `f4` which will end up invoking the terminating +callback with a single result: `1`, instead of `[1]`. + + +In short, be mindful that there is not always a 1:1 correspondence between the +terminating callback that you define, and the interstitial callback that gets +called from the function. + + + +### forEachPipeline: invoke the same function on N inputs in series (and stop on failure) + +Synopsis: `forEachPipeline(args, callback)` + +This function is exactly like `pipeline`, except that the input is specified as +a *single* function ("func") and a list of inputs ("inputs"). The function is +invoked on each input in series. + +This example is exactly equivalent to the one above: + +```js +console.log(mod_vasync.forEachPipeline({ + 'func': mod_dns.resolve, + 'inputs': [ 'joyent.com', 'github.com', 'asdfaqsdfj.com' ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); +``` + +### waterfall: invoke N functions in series, stop on failure, and propagate results + +Synopsis: `waterfall(funcs, callback)` + +This function works like `pipeline` except for argument passing. + +Each function is passed any values emitted by the previous function (none for +the first function), followed by the callback to invoke upon completion. This +callback must be invoked exactly once, regardless of success or failure. As +conventional in Node, the first argument to the callback indicates an error (if +non-null). Subsequent arguments are passed to the next function in the "funcs" +chain. + +If any function fails (i.e., calls its callback with an Error), then the +remaining functions are not invoked and "callback" is invoked with the error. + +The only difference between waterfall() and pipeline() are the arguments passed +to each function in the chain. pipeline() always passes the same argument +followed by the callback, while waterfall() passes whatever values were emitted +by the previous function followed by the callback. + +Here's an example: + +```js +mod_vasync.waterfall([ + function func1(callback) { + setImmediate(function () { + callback(null, 37); + }); + }, + function func2(extra, callback) { + console.log('func2 got "%s" from func1', extra); + callback(); + } +], function () { + console.log('done'); +}); +``` + +This prints: + +``` +func2 got "37" from func1 +better stop early +``` + +### filter/filterLimit/filterSeries: filter N inputs serially or concurrently + +Synopsis: `filter(inputs, filterFunc, callback)` + +Synopsis: `filterSeries(inputs, filterFunc, callback)` + +Synopsis: `filterLimit(inputs, limit, filterFunc, callback)` + +These functions take an array (of anything) and a function to call on each +element of the array. The function must callback with a true or false value as +the second argument or an error object as the first argument. False values +will result in the element being filtered out of the results array. An error +object passed as the first argument will cause the filter function to stop +processing new elements and callback to the caller with the error immediately. +Original input array order is maintained. + +`filter` and `filterSeries` are analogous to calling `filterLimit` with +a limit of `Infinity` and `1` respectively. + + +```js +var inputs = [ + 'joyent.com', + 'github.com', + 'asdfaqsdfj.com' +]; +function filterFunc(input, cb) { + mod_dns.resolve(input, function (err, results) { + if (err) { + cb(null, false); + } else { + cb(null, true); + } + } +} +mod_vasync.filter(inputs, filterFunc, function (err, results) { + // err => undefined + // results => ['joyent.com', 'github.com'] +}); +``` + +### whilst: invoke a function repeatedly until a stopping condition is met + +Synopsis: `whilst(testFunc, iterateFunc, callback)` + +Repeatedly invoke `iterateFunc` while `testFunc` returns a true value. +`iterateFunc` is an asychronous function that must call its callback (the first +and only argument given to it) when it is finished with an optional error +object as the first argument, and any other arbitrary arguments. If an error +object is given as the first argument, `whilst` will finish and call `callback` +with the error object. `testFunc` is a synchronous function that must return +a value - if the value resolves to true `whilst` will invoke `iterateFunc`, if +it resolves to false `whilst` will finish and invoke `callback` with the last +set of arguments `iterateFunc` called back with. + +`whilst` also returns an object suitable for introspecting the current state of +the specific `whilst` invocation which contains the following properties: + +* `finished`: boolean if this invocation has finished or is in progress +* `iterations`: number of iterations performed (calls to `iterateFunc`) + +Compatible with `async.whilst` + +```js +var n = 0; + +var w = mod_vasync.whilst( + function testFunc() { + return (n < 5); + }, + function iterateFunc(cb) { + n++; + cb(null, {n: n}); + }, + function whilstDone(err, arg) { + // err => undefined + // arg => {n: 5} + // w => {finished: true, iterations: 5} + } +); + +// w => {finished: false, iterations: 0} +``` + +### barrier: coordinate multiple concurrent operations + +Synopsis: `barrier([args])` + +Returns a new barrier object. Like `parallel`, barriers are useful for +coordinating several concurrent operations, but instead of specifying a list of +functions to invoke, you just say how many (and optionally which ones) are +outstanding, and this object emits `'drain'` when they've all completed. This +is syntactically lighter-weight, and more flexible. + +* Methods: + + * start(name): Indicates that the named operation began. The name must not + match an operation which is already ongoing. + * done(name): Indicates that the named operation ended. + + +* Read-only public properties (for debugging): + + * pending: Set of pending operations. Keys are names passed to "start", and + values are timestamps when the operation began. + * recent: Array of recent completed operations. Each element is an object + with a "name", "start", and "done" field. By default, 10 operations are + remembered. + + +* Options: + + * nrecent: number of recent operations to remember (for debugging) + +Example: printing sizes of files in a directory + +```js +var mod_fs = require('fs'); +var mod_path = require('path'); +var mod_vasync = require('../lib/vasync'); + +var barrier = mod_vasync.barrier(); + +barrier.on('drain', function () { + console.log('all files checked'); +}); + +barrier.start('readdir'); + +mod_fs.readdir(__dirname, function (err, files) { + barrier.done('readdir'); + + if (err) + throw (err); + + files.forEach(function (file) { + barrier.start('stat ' + file); + + var path = mod_path.join(__dirname, file); + + mod_fs.stat(path, function (err2, stat) { + barrier.done('stat ' + file); + console.log('%s: %d bytes', file, stat['size']); + }); + }); +}); +``` + +This emits: + + barrier-readdir.js: 602 bytes + foreach-parallel.js: 358 bytes + barrier-basic.js: 552 bytes + nofail.js: 384 bytes + pipeline.js: 490 bytes + parallel.js: 481 bytes + queue-serializer.js: 441 bytes + queue-stat.js: 529 bytes + all files checked + + +### queue/queuev: fixed-size worker queue + +Synopsis: `queue(worker, concurrency)` + +Synopsis: `queuev(args)` + +This function returns an object that allows up to a fixed number of tasks to be +dispatched at any given time. The interface is compatible with that provided +by the "async" Node library, except that the returned object's fields represent +a public interface you can use to introspect what's going on. + +* Arguments + + * worker: a function invoked as `worker(task, callback)`, where `task` is a + task dispatched to this queue and `callback` should be invoked when the + task completes. + * concurrency: a positive integer indicating the maximum number of tasks + that may be dispatched at any time. With concurrency = 1, the queue + serializes all operations. + + +* Methods + + * push(task, [callback]): add a task (or array of tasks) to the queue, with + an optional callback to be invoked when each task completes. If a list of + tasks are added, the callback is invoked for each one. + * length(): for compatibility with node-async. + * close(): signal that no more tasks will be enqueued. Further attempts to + enqueue tasks to this queue will throw. Once all pending and queued + tasks are completed the object will emit the "end" event. The "end" + event is the last event the queue will emit, and it will be emitted even + if no tasks were ever enqueued. + * kill(): clear enqueued tasks and implicitly close the queue. Several + caveats apply when kill() is called: + * The completion callback will _not_ be called for items purged from + the queue. + * The drain handler is cleared (for node-async compatibility) + * Subsequent calls to kill() or close() are no-ops. + * As with close(), it is not legal to call push() after kill(). + + +* Read-only public properties (for debugging): + + * concurrency: for compatibility with node-async + * worker: worker function, as passed into "queue"/"queuev" + * worker\_name: worker function's "name" field + * npending: the number of tasks currently being processed + * pending: an object (*not* an array) describing the tasks currently being + processed + * queued: array of tasks currently queued for processing + * closed: true when close() has been called on the queue + * ended: true when all tasks have completed processing, and no more + processing will occur + * killed: true when kill() has been called on the queue + + +* Hooks (for compatibility with node-async): + + * saturated + * empty + * drain + +* Events + + * 'end': see close() + +If the tasks are themselves simple objects, then the entire queue may be +serialized (as via JSON.stringify) for debugging and monitoring tools. Using +the above fields, you can see what this queue is doing (worker\_name), which +tasks are queued, which tasks are being processed, and so on. + +### Example 1: Stat several files + +Here's an example demonstrating the queue: + +```js +var mod_fs = require('fs'); +var mod_vasync = require('../lib/vasync'); + +var queue; + +function doneOne() +{ + console.log('task completed; queue state:\n%s\n', + JSON.stringify(queue, null, 4)); +} + +queue = mod_vasync.queue(mod_fs.stat, 2); + +console.log('initial queue state:\n%s\n', JSON.stringify(queue, null, 4)); + +queue.push('/tmp/file1', doneOne); +queue.push('/tmp/file2', doneOne); +queue.push('/tmp/file3', doneOne); +queue.push('/tmp/file4', doneOne); + +console.log('all tasks dispatched:\n%s\n', JSON.stringify(queue, null, 4)); +``` + +The initial queue state looks like this: + +```js +initial queue state: +{ + "nextid": 0, + "worker_name": "anon", + "npending": 0, + "pending": {}, + "queued": [], + "concurrency": 2 +} +``` +After four tasks have been pushed, we see that two of them have been dispatched +and the remaining two are queued up: + +```js +all tasks pushed: +{ + "nextid": 4, + "worker_name": "anon", + "npending": 2, + "pending": { + "1": { + "id": 1, + "task": "/tmp/file1" + }, + "2": { + "id": 2, + "task": "/tmp/file2" + } + }, + "queued": [ + { + "id": 3, + "task": "/tmp/file3" + }, + { + "id": 4, + "task": "/tmp/file4" + } + ], + "concurrency": 2 +} +``` + +As they complete, we see tasks moving from "queued" to "pending", and completed +tasks disappear: + +```js +task completed; queue state: +{ + "nextid": 4, + "worker_name": "anon", + "npending": 1, + "pending": { + "3": { + "id": 3, + "task": "/tmp/file3" + } + }, + "queued": [ + { + "id": 4, + "task": "/tmp/file4" + } + ], + "concurrency": 2 +} +``` + +When all tasks have completed, the queue state looks like it started: + +```js +task completed; queue state: +{ + "nextid": 4, + "worker_name": "anon", + "npending": 0, + "pending": {}, + "queued": [], + "concurrency": 2 +} +``` + + +### Example 2: A simple serializer + +You can use a queue with concurrency 1 and where the tasks are themselves +functions to ensure that an arbitrary asynchronous function never runs +concurrently with another one, no matter what each one does. Since the tasks +are the actual functions to be invoked, the worker function just invokes each +one: + +```js +var mod_vasync = require('../lib/vasync'); + +var queue = mod_vasync.queue( + function (task, callback) { task(callback); }, 1); + +queue.push(function (callback) { + console.log('first task begins'); + setTimeout(function () { + console.log('first task ends'); + callback(); + }, 500); +}); + +queue.push(function (callback) { + console.log('second task begins'); + process.nextTick(function () { + console.log('second task ends'); + callback(); + }); +}); +``` + +This example outputs: + + $ node examples/queue-serializer.js + first task begins + first task ends + second task begins + second task ends diff --git a/node_modules/vasync/examples/barrier-basic.js b/node_modules/vasync/examples/barrier-basic.js new file mode 100644 index 0000000..e080038 --- /dev/null +++ b/node_modules/vasync/examples/barrier-basic.js @@ -0,0 +1,29 @@ +var mod_vasync = require('../lib/vasync'); + +var barrier = mod_vasync.barrier(); + +barrier.on('drain', function () { + console.log('barrier drained!'); +}); + +console.log('barrier', barrier); + +barrier.start('op1'); +console.log('op1 started', barrier); + +barrier.start('op2'); +console.log('op2 started', barrier); + +barrier.done('op2'); +console.log('op2 done', barrier); + +barrier.done('op1'); +console.log('op1 done', barrier); + +barrier.start('op3'); +console.log('op3 started'); + +setTimeout(function () { + barrier.done('op3'); + console.log('op3 done'); +}, 10); diff --git a/node_modules/vasync/examples/barrier-readdir.js b/node_modules/vasync/examples/barrier-readdir.js new file mode 100644 index 0000000..0f3557b --- /dev/null +++ b/node_modules/vasync/examples/barrier-readdir.js @@ -0,0 +1,29 @@ +var mod_fs = require('fs'); +var mod_path = require('path'); +var mod_vasync = require('../lib/vasync'); + +var barrier = mod_vasync.barrier(); + +barrier.on('drain', function () { + console.log('all files checked'); +}); + +barrier.start('readdir'); + +mod_fs.readdir(__dirname, function (err, files) { + barrier.done('readdir'); + + if (err) + throw (err); + + files.forEach(function (file) { + barrier.start('stat ' + file); + + var path = mod_path.join(__dirname, file); + + mod_fs.stat(path, function (err2, stat) { + barrier.done('stat ' + file); + console.log('%s: %d bytes', file, stat['size']); + }); + }); +}); diff --git a/node_modules/vasync/examples/foreach-parallel.js b/node_modules/vasync/examples/foreach-parallel.js new file mode 100644 index 0000000..680b099 --- /dev/null +++ b/node_modules/vasync/examples/foreach-parallel.js @@ -0,0 +1,11 @@ +var mod_dns = require('dns'); +var mod_util = require('util'); +var mod_vasync = require('../lib/vasync'); + +console.log(mod_vasync.forEachParallel({ + 'func': mod_dns.resolve, + 'inputs': [ 'joyent.com', 'github.com', 'asdfaqsdfj.com' ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); diff --git a/node_modules/vasync/examples/foreach-pipeline.js b/node_modules/vasync/examples/foreach-pipeline.js new file mode 100644 index 0000000..1bad106 --- /dev/null +++ b/node_modules/vasync/examples/foreach-pipeline.js @@ -0,0 +1,11 @@ +var mod_dns = require('dns'); +var mod_util = require('util'); +var mod_vasync = require('../lib/vasync'); + +console.log(mod_vasync.forEachPipeline({ + 'func': mod_dns.resolve, + 'inputs': [ 'joyent.com', 'github.com', 'asdfaqsdfj.com' ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); diff --git a/node_modules/vasync/examples/nofail.js b/node_modules/vasync/examples/nofail.js new file mode 100644 index 0000000..7d2038b --- /dev/null +++ b/node_modules/vasync/examples/nofail.js @@ -0,0 +1,13 @@ +var mod_vasync = require('../lib/vasync'); +var mod_util = require('util'); +var mod_fs = require('fs'); + +var status = mod_vasync.parallel({ + funcs: [ + function f1 (callback) { mod_fs.stat('/tmp', callback); }, + function f2 (callback) { mod_fs.stat('/var', callback); } + ] +}, function (err, results) { + console.log(err); + console.log(mod_util.inspect(results, false, 8)); +}); diff --git a/node_modules/vasync/examples/parallel.js b/node_modules/vasync/examples/parallel.js new file mode 100644 index 0000000..925f007 --- /dev/null +++ b/node_modules/vasync/examples/parallel.js @@ -0,0 +1,14 @@ +var mod_dns = require('dns'); +var mod_util = require('util'); +var mod_vasync = require('../lib/vasync'); + +console.log(mod_vasync.parallel({ + 'funcs': [ + function f1 (callback) { mod_dns.resolve('joyent.com', callback); }, + function f2 (callback) { mod_dns.resolve('github.com', callback); }, + function f3 (callback) { mod_dns.resolve('asdfaqsdfj.com', callback); } + ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); diff --git a/node_modules/vasync/examples/pipeline.js b/node_modules/vasync/examples/pipeline.js new file mode 100644 index 0000000..2bdbe6e --- /dev/null +++ b/node_modules/vasync/examples/pipeline.js @@ -0,0 +1,14 @@ +var mod_dns = require('dns'); +var mod_util = require('util'); +var mod_vasync = require('../lib/vasync'); + +console.log(mod_vasync.pipeline({ + 'funcs': [ + function f1 (_, callback) { mod_dns.resolve('joyent.com', callback); }, + function f2 (_, callback) { mod_dns.resolve('github.com', callback); }, + function f3 (_, callback) { mod_dns.resolve('asdfaqsdfj.com', callback); } + ] +}, function (err, results) { + console.log('error: %s', err.message); + console.log('results: %s', mod_util.inspect(results, null, 3)); +})); diff --git a/node_modules/vasync/examples/queue-serializer.js b/node_modules/vasync/examples/queue-serializer.js new file mode 100644 index 0000000..5fc6d38 --- /dev/null +++ b/node_modules/vasync/examples/queue-serializer.js @@ -0,0 +1,19 @@ +var mod_vasync = require('../lib/vasync'); + +var queue = mod_vasync.queue(function (task, callback) { task(callback); }, 1); + +queue.push(function (callback) { + console.log('first task begins'); + setTimeout(function () { + console.log('first task ends'); + callback(); + }, 500); +}); + +queue.push(function (callback) { + console.log('second task begins'); + process.nextTick(function () { + console.log('second task ends'); + callback(); + }); +}); diff --git a/node_modules/vasync/examples/queue-stat.js b/node_modules/vasync/examples/queue-stat.js new file mode 100644 index 0000000..c8e9585 --- /dev/null +++ b/node_modules/vasync/examples/queue-stat.js @@ -0,0 +1,21 @@ +var mod_fs = require('fs'); +var mod_vasync = require('../lib/vasync'); + +var queue; + +function doneOne() +{ + console.log('task completed; queue state:\n%s\n', + JSON.stringify(queue, null, 4)); +} + +queue = mod_vasync.queue(mod_fs.stat, 2); + +console.log('initial queue state:\n%s\n', JSON.stringify(queue, null, 4)); + +queue.push('/tmp/file1', doneOne); +queue.push('/tmp/file2', doneOne); +queue.push('/tmp/file3', doneOne); +queue.push('/tmp/file4', doneOne); + +console.log('all tasks pushed:\n%s\n', JSON.stringify(queue, null, 4)); diff --git a/node_modules/vasync/examples/waterfall.js b/node_modules/vasync/examples/waterfall.js new file mode 100644 index 0000000..1526cb0 --- /dev/null +++ b/node_modules/vasync/examples/waterfall.js @@ -0,0 +1,17 @@ +/* + * examples/waterfall.js: simple waterfall example + */ +var mod_vasync = require('..'); +mod_vasync.waterfall([ + function func1(callback) { + setImmediate(function () { + callback(null, 37); + }); + }, + function func2(extra, callback) { + console.log('func2 got "%s" from func1', extra); + callback(); + } +], function () { + console.log('done'); +}); diff --git a/node_modules/vasync/examples/whilst.js b/node_modules/vasync/examples/whilst.js new file mode 100644 index 0000000..a0aa9e2 --- /dev/null +++ b/node_modules/vasync/examples/whilst.js @@ -0,0 +1,20 @@ +var mod_vasync = require('../lib/vasync'); + +var n = 0; + +var w = mod_vasync.whilst( + function testFunc() { + return (n < 5); + }, + function iterateFunc(cb) { + n++; + cb(null, {n: n}); + }, + function whilstDone(err, arg) { + console.log('err: %j', err); + console.log('arg: %j', arg); + console.log('w (end): %j', w); + } +); + +console.log('w (start): %j', w); diff --git a/node_modules/vasync/jsl.node.conf b/node_modules/vasync/jsl.node.conf new file mode 100644 index 0000000..a4f5ef5 --- /dev/null +++ b/node_modules/vasync/jsl.node.conf @@ -0,0 +1,138 @@ +# +# Configuration File for JavaScript Lint +# +# This configuration file can be used to lint a collection of scripts, or to enable +# or disable warnings for scripts that are linted via the command line. +# + +### Warnings +# Enable or disable warnings based on requirements. +# Use "+WarningName" to display or "-WarningName" to suppress. +# ++ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent ++ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity ++ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement ++anon_no_return_value # anonymous function does not always return value ++assign_to_function_call # assignment to a function call +-block_without_braces # block statement without curly braces ++comma_separated_stmts # multiple statements separated by commas (use semicolons?) ++comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) ++default_not_at_end # the default case is not at the end of the switch statement ++dup_option_explicit # duplicate "option explicit" control comment ++duplicate_case_in_switch # duplicate case in switch statement ++duplicate_formal # duplicate formal argument {name} ++empty_statement # empty statement or extra semicolon ++identifier_hides_another # identifer {name} hides an identifier in a parent scope +-inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement ++incorrect_version # Expected /*jsl:content-type*/ control comment. The script was parsed with the wrong version. ++invalid_fallthru # unexpected "fallthru" control comment ++invalid_pass # unexpected "pass" control comment ++jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax ++leading_decimal_point # leading decimal point may indicate a number or an object member ++legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax ++meaningless_block # meaningless block; curly braces have no impact ++mismatch_ctrl_comments # mismatched control comment; "ignore" and "end" control comments must have a one-to-one correspondence ++misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma ++missing_break # missing break statement ++missing_break_for_last_case # missing break statement for last case in switch ++missing_default_case # missing default case in switch statement ++missing_option_explicit # the "option explicit" control comment is missing ++missing_semicolon # missing semicolon ++missing_semicolon_for_lambda # missing semicolon for lambda assignment ++multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs ++nested_comment # nested comment ++no_return_value # function {name} does not always return a value ++octal_number # leading zeros make an octal number ++parseint_missing_radix # parseInt missing radix parameter ++partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag ++redeclared_var # redeclaration of {name} ++trailing_comma_in_array # extra comma is not recommended in array initializers ++trailing_decimal_point # trailing decimal point may indicate a number or an object member ++undeclared_identifier # undeclared identifier: {name} ++unreachable_code # unreachable code +-unreferenced_argument # argument declared but never referenced: {name} +-unreferenced_function # function is declared but never referenced: {name} ++unreferenced_variable # variable is declared but never referenced: {name} ++unsupported_version # JavaScript {version} is not supported ++use_of_label # use of label ++useless_assign # useless assignment ++useless_comparison # useless comparison; comparing identical expressions +-useless_quotes # the quotation marks are unnecessary ++useless_void # use of the void type may be unnecessary (void is always undefined) ++var_hides_arg # variable {name} hides argument ++want_assign_or_call # expected an assignment or function call ++with_statement # with statement hides undeclared variables; use temporary variable instead + + +### Output format +# Customize the format of the error message. +# __FILE__ indicates current file path +# __FILENAME__ indicates current file name +# __LINE__ indicates current line +# __COL__ indicates current column +# __ERROR__ indicates error message (__ERROR_PREFIX__: __ERROR_MSG__) +# __ERROR_NAME__ indicates error name (used in configuration file) +# __ERROR_PREFIX__ indicates error prefix +# __ERROR_MSG__ indicates error message +# +# For machine-friendly output, the output format can be prefixed with +# "encode:". If specified, all items will be encoded with C-slashes. +# +# Visual Studio syntax (default): ++output-format __FILE__(__LINE__): __ERROR__ +# Alternative syntax: +#+output-format __FILE__:__LINE__: __ERROR__ + + +### Context +# Show the in-line position of the error. +# Use "+context" to display or "-context" to suppress. +# ++context + + +### Control Comments +# Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for +# the /*@keyword@*/ control comments and JScript conditional comments. (The latter is +# enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason, +# although legacy control comments are enabled by default for backward compatibility. +# +-legacy_control_comments + + +### Defining identifiers +# By default, "option explicit" is enabled on a per-file basis. +# To enable this for all files, use "+always_use_option_explicit" +-always_use_option_explicit + +# Define certain identifiers of which the lint is not aware. +# (Use this in conjunction with the "undeclared identifier" warning.) +# +# Common uses for webpages might be: ++define __dirname ++define clearInterval ++define clearTimeout ++define console ++define exports ++define global ++define process ++define require ++define setImmediate ++define setInterval ++define setTimeout ++define Buffer ++define JSON ++define Math + +### JavaScript Version +# To change the default JavaScript version: +#+default-type text/javascript;version=1.5 +#+default-type text/javascript;e4x=1 + +### Files +# Specify which files to lint +# Use "+recurse" to enable recursion (disabled by default). +# To add a set of files, use "+process FileName", "+process Folder\Path\*.js", +# or "+process Folder\Path\*.htm". +# + diff --git a/node_modules/vasync/lib/vasync.js b/node_modules/vasync/lib/vasync.js new file mode 100644 index 0000000..1b7b564 --- /dev/null +++ b/node_modules/vasync/lib/vasync.js @@ -0,0 +1,891 @@ +/* + * vasync.js: utilities for observable asynchronous control flow + */ + +var mod_assert = require('assert'); +var mod_events = require('events'); +var mod_util = require('util'); +var mod_verror = require('verror'); + +/* + * Public interface + */ +exports.parallel = parallel; +exports.forEachParallel = forEachParallel; +exports.pipeline = pipeline; +exports.tryEach = tryEach; +exports.forEachPipeline = forEachPipeline; +exports.filter = filter; +exports.filterLimit = filterLimit; +exports.filterSeries = filterSeries; +exports.whilst = whilst; +exports.queue = queue; +exports.queuev = queuev; +exports.barrier = barrier; +exports.waterfall = waterfall; + +if (!global.setImmediate) { + global.setImmediate = function (func) { + var args = Array.prototype.slice.call(arguments, 1); + args.unshift(0); + args.unshift(func); + setTimeout.apply(this, args); + }; +} + +/* + * This is incorporated here from jsprim because jsprim ends up pulling in a lot + * of dependencies. If we end up needing more from jsprim, though, we should + * add it back and rip out this function. + */ +function isEmpty(obj) +{ + var key; + for (key in obj) + return (false); + return (true); +} + +/* + * Given a set of functions that complete asynchronously using the standard + * callback(err, result) pattern, invoke them all and merge the results. See + * README.md for details. + */ +function parallel(args, callback) +{ + var funcs, rv, doneOne, i; + + mod_assert.equal(typeof (args), 'object', '"args" must be an object'); + mod_assert.ok(Array.isArray(args['funcs']), + '"args.funcs" must be specified and must be an array'); + mod_assert.equal(typeof (callback), 'function', + 'callback argument must be specified and must be a function'); + + funcs = args['funcs'].slice(0); + + rv = { + 'operations': new Array(funcs.length), + 'successes': [], + 'ndone': 0, + 'nerrors': 0 + }; + + if (funcs.length === 0) { + setImmediate(function () { callback(null, rv); }); + return (rv); + } + + doneOne = function (entry) { + return (function (err, result) { + mod_assert.equal(entry['status'], 'pending'); + + entry['err'] = err; + entry['result'] = result; + entry['status'] = err ? 'fail' : 'ok'; + + if (err) + rv['nerrors']++; + else + rv['successes'].push(result); + + if (++rv['ndone'] < funcs.length) + return; + + var errors = rv['operations'].filter(function (ent) { + return (ent['status'] == 'fail'); + }).map(function (ent) { return (ent['err']); }); + + if (errors.length > 0) + callback(new mod_verror.MultiError(errors), rv); + else + callback(null, rv); + }); + }; + + for (i = 0; i < funcs.length; i++) { + rv['operations'][i] = { + 'func': funcs[i], + 'funcname': funcs[i].name || '(anon)', + 'status': 'pending' + }; + + funcs[i](doneOne(rv['operations'][i])); + } + + return (rv); +} + +/* + * Exactly like parallel, except that the input is specified as a single + * function to invoke on N different inputs (rather than N functions). "args" + * must have the following fields: + * + * func asynchronous function to invoke on each input value + * + * inputs array of input values + */ +function forEachParallel(args, callback) +{ + var func, funcs; + + mod_assert.equal(typeof (args), 'object', '"args" must be an object'); + mod_assert.equal(typeof (args['func']), 'function', + '"args.func" must be specified and must be a function'); + mod_assert.ok(Array.isArray(args['inputs']), + '"args.inputs" must be specified and must be an array'); + + func = args['func']; + funcs = args['inputs'].map(function (input) { + return (function (subcallback) { + return (func(input, subcallback)); + }); + }); + + return (parallel({ 'funcs': funcs }, callback)); +} + +/* + * Like parallel, but invokes functions in sequence rather than in parallel + * and aborts if any function exits with failure. Arguments include: + * + * funcs invoke the functions in parallel + * + * arg first argument to each pipeline function + */ +function pipeline(args, callback) +{ + mod_assert.equal(typeof (args), 'object', '"args" must be an object'); + mod_assert.ok(Array.isArray(args['funcs']), + '"args.funcs" must be specified and must be an array'); + + var opts = { + 'funcs': args['funcs'].slice(0), + 'callback': callback, + 'args': { impl: 'pipeline', uarg: args['arg'] }, + 'stop_when': 'error', + 'res_type': 'rv' + }; + return (waterfall_impl(opts)); +} + +function tryEach(funcs, callback) +{ + mod_assert.ok(Array.isArray(funcs), + '"funcs" must be specified and must be an array'); + mod_assert.ok(arguments.length == 1 || typeof (callback) == 'function', + '"callback" must be a function'); + var opts = { + 'funcs': funcs.slice(0), + 'callback': callback, + 'args': { impl: 'tryEach' }, + 'stop_when': 'success', + 'res_type': 'array' + }; + return (waterfall_impl(opts)); +} + +/* + * Exactly like pipeline, except that the input is specified as a single + * function to invoke on N different inputs (rather than N functions). "args" + * must have the following fields: + * + * func asynchronous function to invoke on each input value + * + * inputs array of input values + */ +function forEachPipeline(args, callback) { + mod_assert.equal(typeof (args), 'object', '"args" must be an object'); + mod_assert.equal(typeof (args['func']), 'function', + '"args.func" must be specified and must be a function'); + mod_assert.ok(Array.isArray(args['inputs']), + '"args.inputs" must be specified and must be an array'); + mod_assert.equal(typeof (callback), 'function', + 'callback argument must be specified and must be a function'); + + var func = args['func']; + + var funcs = args['inputs'].map(function (input) { + return (function (_, subcallback) { + return (func(input, subcallback)); + }); + }); + + return (pipeline({'funcs': funcs}, callback)); +} + +/* + * async.js compatible filter, filterLimit, and filterSeries. Takes an input + * array, optionally a limit, and a single function to filter an array and will + * callback with a new filtered array. This is effectively an asynchronous + * version of Array.prototype.filter. + */ +function filter(inputs, filterFunc, callback) { + return (filterLimit(inputs, Infinity, filterFunc, callback)); +} + +function filterSeries(inputs, filterFunc, callback) { + return (filterLimit(inputs, 1, filterFunc, callback)); +} + +function filterLimit(inputs, limit, filterFunc, callback) { + mod_assert.ok(Array.isArray(inputs), + '"inputs" must be specified and must be an array'); + mod_assert.equal(typeof (limit), 'number', + '"limit" must be a number'); + mod_assert.equal(isNaN(limit), false, + '"limit" must be a number'); + mod_assert.equal(typeof (filterFunc), 'function', + '"filterFunc" must be specified and must be a function'); + mod_assert.equal(typeof (callback), 'function', + '"callback" argument must be specified as a function'); + + var errors = []; + var q = queue(processInput, limit); + var results = []; + + function processInput(input, cb) { + /* + * If the errors array has any members, an error was + * encountered in a previous invocation of filterFunc, so all + * future filtering will be skipped. + */ + if (errors.length > 0) { + cb(); + return; + } + + filterFunc(input.elem, function inputFiltered(err, ans) { + /* + * We ensure here that a filterFunc callback is only + * ever invoked once. + */ + if (results.hasOwnProperty(input.idx)) { + throw (new mod_verror.VError( + 'vasync.filter*: filterFunc idx %d ' + + 'invoked its callback twice', input.idx)); + } + + /* + * The original element, as well as the answer "ans" + * (truth value) is stored to later be filtered when + * all outstanding jobs are finished. + */ + results[input.idx] = { + elem: input.elem, + ans: !!ans + }; + + /* + * Any error encountered while filtering will result in + * all future operations being skipped, and the error + * object being returned in the users callback. + */ + if (err) { + errors.push(err); + cb(); + return; + } + + cb(); + }); + } + + q.once('end', function queueDrained() { + if (errors.length > 0) { + callback(mod_verror.errorFromList(errors)); + return; + } + + /* + * results is now an array of objects in the same order of the + * inputs array, where each object looks like: + * + * { + * "ans": , + * "elem": + * } + * + * we filter out elements that have a false "ans" value, and + * then map the array to contain only the input elements. + */ + results = results.filter(function filterFalseInputs(input) { + return (input.ans); + }).map(function mapInputElements(input) { + return (input.elem); + }); + callback(null, results); + }); + + inputs.forEach(function iterateInput(elem, idx) { + /* + * We retain the array index to ensure that order is + * maintained. + */ + q.push({ + elem: elem, + idx: idx + }); + }); + + q.close(); + + return (q); +} + +/* + * async-compatible "whilst" function, with a few notable exceptions/addons. + * + * 1. More strict typing of arguments (functions *must* be supplied). + * 2. A callback function is required, not optional. + * 3. An object is returned, not undefined. + */ +function whilst(testFunc, iterateFunc, callback) { + mod_assert.equal(typeof (testFunc), 'function', + '"testFunc" must be specified and must be a function'); + mod_assert.equal(typeof (iterateFunc), 'function', + '"iterateFunc" must be specified and must be a function'); + mod_assert.equal(typeof (callback), 'function', + '"callback" argument must be specified as a function'); + + /* + * The object returned to the caller that provides a read-only + * interface to introspect this specific invocation of "whilst". + */ + var o = { + 'finished': false, + 'iterations': 0 + }; + + /* + * Store the last set of arguments from the final call to "iterateFunc". + * The arguments will be passed to the final callback when an error is + * encountered or when the testFunc returns false. + */ + var args = []; + + function iterate() { + var shouldContinue = testFunc(); + + if (!shouldContinue) { + /* + * The test condition is false - break out of the loop. + */ + done(); + return; + } + + /* Bump iterations after testFunc but before iterateFunc. */ + o.iterations++; + + iterateFunc(function whilstIteration(err) { + /* Store the latest set of arguments seen. */ + args = Array.prototype.slice.call(arguments); + + /* Any error with iterateFunc will break the loop. */ + if (err) { + done(); + return; + } + + /* Try again. */ + setImmediate(iterate); + }); + } + + function done() { + mod_assert.ok(!o.finished, 'whilst already finished'); + o.finished = true; + callback.apply(this, args); + } + + setImmediate(iterate); + + return (o); +} + +/* + * async-compatible "queue" function. + */ +function queue(worker, concurrency) +{ + return (new WorkQueue({ + 'worker': worker, + 'concurrency': concurrency + })); +} + +function queuev(args) +{ + return (new WorkQueue(args)); +} + +function WorkQueue(args) +{ + mod_assert.ok(args.hasOwnProperty('worker')); + mod_assert.equal(typeof (args['worker']), 'function'); + mod_assert.ok(args.hasOwnProperty('concurrency')); + mod_assert.equal(typeof (args['concurrency']), 'number'); + mod_assert.equal(Math.floor(args['concurrency']), args['concurrency']); + mod_assert.ok(args['concurrency'] > 0); + + mod_events.EventEmitter.call(this); + + this.nextid = 0; + this.worker = args['worker']; + this.worker_name = args['worker'].name || 'anon'; + this.npending = 0; + this.pending = {}; + this.queued = []; + this.closed = false; + this.ended = false; + + /* user-settable fields inherited from "async" interface */ + this.concurrency = args['concurrency']; + this.saturated = undefined; + this.empty = undefined; + this.drain = undefined; +} + +mod_util.inherits(WorkQueue, mod_events.EventEmitter); + +WorkQueue.prototype.push = function (tasks, callback) +{ + if (!Array.isArray(tasks)) + return (this.pushOne(tasks, callback)); + + var wq = this; + return (tasks.map(function (task) { + return (wq.pushOne(task, callback)); + })); +}; + +WorkQueue.prototype.updateConcurrency = function (concurrency) +{ + if (this.closed) + throw new mod_verror.VError( + 'update concurrency invoked after queue closed'); + this.concurrency = concurrency; + this.dispatchNext(); +}; + +WorkQueue.prototype.close = function () +{ + var wq = this; + + if (wq.closed) + return; + wq.closed = true; + + /* + * If the queue is already empty, just fire the "end" event on the + * next tick. + */ + if (wq.npending === 0 && wq.queued.length === 0) { + setImmediate(function () { + if (!wq.ended) { + wq.ended = true; + wq.emit('end'); + } + }); + } +}; + +/* private */ +WorkQueue.prototype.pushOne = function (task, callback) +{ + if (this.closed) + throw new mod_verror.VError('push invoked after queue closed'); + + var id = ++this.nextid; + var entry = { 'id': id, 'task': task, 'callback': callback }; + + this.queued.push(entry); + this.dispatchNext(); + + return (id); +}; + +/* private */ +WorkQueue.prototype.dispatchNext = function () +{ + var wq = this; + if (wq.npending === 0 && wq.queued.length === 0) { + if (wq.drain) + wq.drain(); + wq.emit('drain'); + /* + * The queue is closed; emit the final "end" + * event before we come to rest: + */ + if (wq.closed) { + wq.ended = true; + wq.emit('end'); + } + } else if (wq.queued.length > 0) { + while (wq.queued.length > 0 && wq.npending < wq.concurrency) { + var next = wq.queued.shift(); + wq.dispatch(next); + + if (wq.queued.length === 0) { + if (wq.empty) + wq.empty(); + wq.emit('empty'); + } + } + } +}; + +WorkQueue.prototype.dispatch = function (entry) +{ + var wq = this; + + mod_assert.ok(!this.pending.hasOwnProperty(entry['id'])); + mod_assert.ok(this.npending < this.concurrency); + mod_assert.ok(!this.ended); + + this.npending++; + this.pending[entry['id']] = entry; + + if (this.npending === this.concurrency) { + if (this.saturated) + this.saturated(); + this.emit('saturated'); + } + + /* + * We invoke the worker function on the next tick so that callers can + * always assume that the callback is NOT invoked during the call to + * push() even if the queue is not at capacity. It also avoids O(n) + * stack usage when used with synchronous worker functions. + */ + setImmediate(function () { + wq.worker(entry['task'], function (err) { + --wq.npending; + delete (wq.pending[entry['id']]); + + if (entry['callback']) + entry['callback'].apply(null, arguments); + + wq.dispatchNext(); + }); + }); +}; + +WorkQueue.prototype.length = function () +{ + return (this.queued.length); +}; + +WorkQueue.prototype.kill = function () +{ + this.killed = true; + this.queued = []; + this.drain = undefined; + this.close(); +}; + +/* + * Barriers coordinate multiple concurrent operations. + */ +function barrier(args) +{ + return (new Barrier(args)); +} + +function Barrier(args) +{ + mod_assert.ok(!args || !args['nrecent'] || + typeof (args['nrecent']) == 'number', + '"nrecent" must have type "number"'); + + mod_events.EventEmitter.call(this); + + var nrecent = args && args['nrecent'] ? args['nrecent'] : 10; + + if (nrecent > 0) { + this.nrecent = nrecent; + this.recent = []; + } + + this.pending = {}; + this.scheduled = false; +} + +mod_util.inherits(Barrier, mod_events.EventEmitter); + +Barrier.prototype.start = function (name) +{ + mod_assert.ok(!this.pending.hasOwnProperty(name), + 'operation "' + name + '" is already pending'); + this.pending[name] = Date.now(); +}; + +Barrier.prototype.done = function (name) +{ + mod_assert.ok(this.pending.hasOwnProperty(name), + 'operation "' + name + '" is not pending'); + + if (this.recent) { + this.recent.push({ + 'name': name, + 'start': this.pending[name], + 'done': Date.now() + }); + + if (this.recent.length > this.nrecent) + this.recent.shift(); + } + + delete (this.pending[name]); + + /* + * If we executed at least one operation and we're now empty, we should + * emit "drain". But most code doesn't deal well with events being + * processed while they're executing, so we actually schedule this event + * for the next tick. + * + * We use the "scheduled" flag to avoid emitting multiple "drain" events + * on consecutive ticks if the user starts and ends another task during + * this tick. + */ + if (!isEmpty(this.pending) || this.scheduled) + return; + + this.scheduled = true; + + var self = this; + + setImmediate(function () { + self.scheduled = false; + + /* + * It's also possible that the user has started another task on + * the previous tick, in which case we really shouldn't emit + * "drain". + */ + if (isEmpty(self.pending)) + self.emit('drain'); + }); +}; + +/* + * waterfall([ funcs ], callback): invoke each of the asynchronous functions + * "funcs" in series. Each function is passed any values emitted by the + * previous function (none for the first function), followed by the callback to + * invoke upon completion. This callback must be invoked exactly once, + * regardless of success or failure. As conventional in Node, the first + * argument to the callback indicates an error (if non-null). Subsequent + * arguments are passed to the next function in the "funcs" chain. + * + * If any function fails (i.e., calls its callback with an Error), then the + * remaining functions are not invoked and "callback" is invoked with the error. + * + * The only difference between waterfall() and pipeline() are the arguments + * passed to each function in the chain. pipeline() always passes the same + * argument followed by the callback, while waterfall() passes whatever values + * were emitted by the previous function followed by the callback. + */ +function waterfall(funcs, callback) +{ + mod_assert.ok(Array.isArray(funcs), + '"funcs" must be specified and must be an array'); + mod_assert.ok(arguments.length == 1 || typeof (callback) == 'function', + '"callback" must be a function'); + var opts = { + 'funcs': funcs.slice(0), + 'callback': callback, + 'args': { impl: 'waterfall' }, + 'stop_when': 'error', + 'res_type': 'values' + }; + return (waterfall_impl(opts)); +} + +/* + * This function is used to implement vasync-functions that need to execute a + * list of functions in a sequence, but differ in how they make use of the + * intermediate callbacks and finall callback, as well as under what conditions + * they stop executing the functions in the list. Examples of such functions + * are `pipeline`, `waterfall`, and `tryEach`. See the documentation for those + * functions to see how they operate. + * + * This function's behavior is influenced via the `opts` object that we pass + * in. This object has the following layout: + * + * { + * 'funcs': array of functions + * 'callback': the final callback + * 'args': { + * 'impl': 'pipeline' or 'tryEach' or 'waterfall' + * 'uarg': the arg passed to each func for 'pipeline' + * } + * 'stop_when': 'error' or 'success' + * 'res_type': 'values' or 'arrays' or 'rv' + * } + * + * In the object, 'res_type' is used to indicate what the type of the result + * values(s) is that we pass to the final callback. We secondarily use + * 'args.impl' to adjust this behavior in an implementation-specific way. For + * example, 'tryEach' only returns an array if it has more than 1 result passed + * to the final callback. Otherwise, it passes a solitary value to the final + * callback. + * + * In case it's not clear, 'rv' in the `res_type` member, is just the + * result-value that we also return. This is the convention in functions that + * originated in `vasync` (pipeline), but not in functions that originated in + * `async` (waterfall, tryEach). + */ +function waterfall_impl(opts) +{ + mod_assert.ok(typeof (opts) === 'object'); + var rv, current, next; + var funcs = opts.funcs; + var callback = opts.callback; + + mod_assert.ok(Array.isArray(funcs), + '"opts.funcs" must be specified and must be an array'); + mod_assert.ok(arguments.length == 1, + 'Function "waterfall_impl" must take only 1 arg'); + mod_assert.ok(opts.res_type === 'values' || + opts.res_type === 'array' || opts.res_type == 'rv', + '"opts.res_type" must either be "values", "array", or "rv"'); + mod_assert.ok(opts.stop_when === 'error' || + opts.stop_when === 'success', + '"opts.stop_when" must either be "error" or "success"'); + mod_assert.ok(opts.args.impl === 'pipeline' || + opts.args.impl === 'waterfall' || opts.args.impl === 'tryEach', + '"opts.args.impl" must be "pipeline", "waterfall", or "tryEach"'); + if (opts.args.impl === 'pipeline') { + mod_assert.ok(typeof (opts.args.uarg) !== undefined, + '"opts.args.uarg" should be defined when pipeline is used'); + } + + rv = { + 'operations': funcs.map(function (func) { + return ({ + 'func': func, + 'funcname': func.name || '(anon)', + 'status': 'waiting' + }); + }), + 'successes': [], + 'ndone': 0, + 'nerrors': 0 + }; + + if (funcs.length === 0) { + if (callback) + setImmediate(function () { + var res = (opts.args.impl === 'pipeline') ? rv + : undefined; + callback(null, res); + }); + return (rv); + } + + next = function (idx, err) { + /* + * Note that nfunc_args contains the args we will pass to the + * next func in the func-list the user gave us. Except for + * 'tryEach', which passes cb's. However, it will pass + * 'nfunc_args' to its final callback -- see below. + */ + var res_key, nfunc_args, entry, nextentry; + + if (err === undefined) + err = null; + + if (idx != current) { + throw (new mod_verror.VError( + 'vasync.waterfall: function %d ("%s") invoked ' + + 'its callback twice', idx, + rv['operations'][idx].funcname)); + } + + mod_assert.equal(idx, rv['ndone'], + 'idx should be equal to ndone'); + entry = rv['operations'][rv['ndone']++]; + if (opts.args.impl === 'tryEach' || + opts.args.impl === 'waterfall') { + nfunc_args = Array.prototype.slice.call(arguments, 2); + res_key = 'results'; + entry['results'] = nfunc_args; + } else if (opts.args.impl === 'pipeline') { + nfunc_args = [ opts.args.uarg ]; + res_key = 'result'; + entry['result'] = arguments[2]; + } + + mod_assert.equal(entry['status'], 'pending', + 'status should be pending'); + entry['status'] = err ? 'fail' : 'ok'; + entry['err'] = err; + + if (err) { + rv['nerrors']++; + } else { + rv['successes'].push(entry[res_key]); + } + + if ((opts.stop_when === 'error' && err) || + (opts.stop_when === 'success' && + rv['successes'].length > 0) || + rv['ndone'] == funcs.length) { + if (callback) { + if (opts.res_type === 'values' || + (opts.res_type === 'array' && + nfunc_args.length <= 1)) { + nfunc_args.unshift(err); + callback.apply(null, nfunc_args); + } else if (opts.res_type === 'array') { + callback(err, nfunc_args); + } else if (opts.res_type === 'rv') { + callback(err, rv); + } + } + } else { + nextentry = rv['operations'][rv['ndone']]; + nextentry['status'] = 'pending'; + current++; + nfunc_args.push(next.bind(null, current)); + setImmediate(function () { + var nfunc = nextentry['func']; + /* + * At first glance it may seem like this branch + * is superflous with the code above that + * branches on `opts.args.impl`. It may also + * seem like calling `nfunc.apply` is + * sufficient for both cases (after all we + * pushed `next.bind(null, current)` to the + * `nfunc_args` array), before we call + * `setImmediate()`. However, this is not the + * case, because the interface exposed by + * tryEach is different from the others. The + * others pass argument(s) from task to task. + * tryEach passes nothing but a callback + * (`next.bind` below). However, the callback + * itself _can_ be called with one or more + * results, which we collect into `nfunc_args` + * using the aformentioned `opts.args.impl` + * branch above, and which we pass to the + * callback via the `opts.res_type` branch + * above (where res_type is set to 'array'). + */ + if (opts.args.impl !== 'tryEach') { + nfunc.apply(null, nfunc_args); + } else { + nfunc(next.bind(null, current)); + } + }); + } + }; + + rv['operations'][0]['status'] = 'pending'; + current = 0; + if (opts.args.impl !== 'pipeline') { + funcs[0](next.bind(null, current)); + } else { + funcs[0](opts.args.uarg, next.bind(null, current)); + } + return (rv); +} diff --git a/node_modules/vasync/node_modules/verror/.npmignore b/node_modules/vasync/node_modules/verror/.npmignore new file mode 100644 index 0000000..f14aec8 --- /dev/null +++ b/node_modules/vasync/node_modules/verror/.npmignore @@ -0,0 +1,9 @@ +.gitignore +.gitmodules +deps +examples +experiments +jsl.node.conf +Makefile +Makefile.targ +test diff --git a/node_modules/vasync/node_modules/verror/CHANGES.md b/node_modules/vasync/node_modules/verror/CHANGES.md new file mode 100644 index 0000000..bbb745a --- /dev/null +++ b/node_modules/vasync/node_modules/verror/CHANGES.md @@ -0,0 +1,28 @@ +# Changelog + +## Not yet released + +None yet. + +## v1.10.0 + +* #49 want convenience functions for MultiErrors + +## v1.9.0 + +* #47 could use VError.hasCauseWithName() + +## v1.8.1 + +* #39 captureStackTrace lost when inheriting from WError + +## v1.8.0 + +* #23 Preserve original stack trace(s) + +## v1.7.0 + +* #10 better support for extra properties on Errors +* #11 make it easy to find causes of a particular kind +* #29 No documentation on how to Install this package +* #36 elide development-only files from npm package diff --git a/node_modules/vasync/node_modules/verror/CONTRIBUTING.md b/node_modules/vasync/node_modules/verror/CONTRIBUTING.md new file mode 100644 index 0000000..750cef8 --- /dev/null +++ b/node_modules/vasync/node_modules/verror/CONTRIBUTING.md @@ -0,0 +1,19 @@ +# Contributing + +This repository uses [cr.joyent.us](https://cr.joyent.us) (Gerrit) for new +changes. Anyone can submit changes. To get started, see the [cr.joyent.us user +guide](https://github.com/joyent/joyent-gerrit/blob/master/docs/user/README.md). +This repo does not use GitHub pull requests. + +See the [Joyent Engineering +Guidelines](https://github.com/joyent/eng/blob/master/docs/index.md) for general +best practices expected in this repository. + +Contributions should be "make prepush" clean. The "prepush" target runs the +"check" target, which requires these separate tools: + +* https://github.com/davepacheco/jsstyle +* https://github.com/davepacheco/javascriptlint + +If you're changing something non-trivial or user-facing, you may want to submit +an issue first. diff --git a/node_modules/vasync/node_modules/verror/LICENSE b/node_modules/vasync/node_modules/verror/LICENSE new file mode 100644 index 0000000..82a5cb8 --- /dev/null +++ b/node_modules/vasync/node_modules/verror/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016, Joyent, Inc. All rights reserved. + +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 diff --git a/node_modules/vasync/node_modules/verror/README.md b/node_modules/vasync/node_modules/verror/README.md new file mode 100644 index 0000000..c1f0635 --- /dev/null +++ b/node_modules/vasync/node_modules/verror/README.md @@ -0,0 +1,528 @@ +# verror: rich JavaScript errors + +This module provides several classes in support of Joyent's [Best Practices for +Error Handling in Node.js](http://www.joyent.com/developers/node/design/errors). +If you find any of the behavior here confusing or surprising, check out that +document first. + +The error classes here support: + +* printf-style arguments for the message +* chains of causes +* properties to provide extra information about the error +* creating your own subclasses that support all of these + +The classes here are: + +* **VError**, for chaining errors while preserving each one's error message. + This is useful in servers and command-line utilities when you want to + propagate an error up a call stack, but allow various levels to add their own + context. See examples below. +* **WError**, for wrapping errors while hiding the lower-level messages from the + top-level error. This is useful for API endpoints where you don't want to + expose internal error messages, but you still want to preserve the error chain + for logging and debugging. +* **SError**, which is just like VError but interprets printf-style arguments + more strictly. +* **MultiError**, which is just an Error that encapsulates one or more other + errors. (This is used for parallel operations that return several errors.) + + +# Quick start + +First, install the package: + + npm install verror + +If nothing else, you can use VError as a drop-in replacement for the built-in +JavaScript Error class, with the addition of printf-style messages: + +```javascript +var err = new VError('missing file: "%s"', '/etc/passwd'); +console.log(err.message); +``` + +This prints: + + missing file: "/etc/passwd" + +You can also pass a `cause` argument, which is any other Error object: + +```javascript +var fs = require('fs'); +var filename = '/nonexistent'; +fs.stat(filename, function (err1) { + var err2 = new VError(err1, 'stat "%s"', filename); + console.error(err2.message); +}); +``` + +This prints out: + + stat "/nonexistent": ENOENT, stat '/nonexistent' + +which resembles how Unix programs typically report errors: + + $ sort /nonexistent + sort: open failed: /nonexistent: No such file or directory + +To match the Unixy feel, when you print out the error, just prepend the +program's name to the VError's `message`. Or just call +[node-cmdutil.fail(your_verror)](https://github.com/joyent/node-cmdutil), which +does this for you. + +You can get the next-level Error using `err.cause()`: + +```javascript +console.error(err2.cause().message); +``` + +prints: + + ENOENT, stat '/nonexistent' + +Of course, you can chain these as many times as you want, and it works with any +kind of Error: + +```javascript +var err1 = new Error('No such file or directory'); +var err2 = new VError(err1, 'failed to stat "%s"', '/junk'); +var err3 = new VError(err2, 'request failed'); +console.error(err3.message); +``` + +This prints: + + request failed: failed to stat "/junk": No such file or directory + +The idea is that each layer in the stack annotates the error with a description +of what it was doing. The end result is a message that explains what happened +at each level. + +You can also decorate Error objects with additional information so that callers +can not only handle each kind of error differently, but also construct their own +error messages (e.g., to localize them, format them, group them by type, and so +on). See the example below. + + +# Deeper dive + +The two main goals for VError are: + +* **Make it easy to construct clear, complete error messages intended for + people.** Clear error messages greatly improve both user experience and + debuggability, so we wanted to make it easy to build them. That's why the + constructor takes printf-style arguments. +* **Make it easy to construct objects with programmatically-accessible + metadata** (which we call _informational properties_). Instead of just saying + "connection refused while connecting to 192.168.1.2:80", you can add + properties like `"ip": "192.168.1.2"` and `"tcpPort": 80`. This can be used + for feeding into monitoring systems, analyzing large numbers of Errors (as + from a log file), or localizing error messages. + +To really make this useful, it also needs to be easy to compose Errors: +higher-level code should be able to augment the Errors reported by lower-level +code to provide a more complete description of what happened. Instead of saying +"connection refused", you can say "operation X failed: connection refused". +That's why VError supports `causes`. + +In order for all this to work, programmers need to know that it's generally safe +to wrap lower-level Errors with higher-level ones. If you have existing code +that handles Errors produced by a library, you should be able to wrap those +Errors with a VError to add information without breaking the error handling +code. There are two obvious ways that this could break such consumers: + +* The error's name might change. People typically use `name` to determine what + kind of Error they've got. To ensure compatibility, you can create VErrors + with custom names, but this approach isn't great because it prevents you from + representing complex failures. For this reason, VError provides + `findCauseByName`, which essentially asks: does this Error _or any of its + causes_ have this specific type? If error handling code uses + `findCauseByName`, then subsystems can construct very specific causal chains + for debuggability and still let people handle simple cases easily. There's an + example below. +* The error's properties might change. People often hang additional properties + off of Error objects. If we wrap an existing Error in a new Error, those + properties would be lost unless we copied them. But there are a variety of + both standard and non-standard Error properties that should _not_ be copied in + this way: most obviously `name`, `message`, and `stack`, but also `fileName`, + `lineNumber`, and a few others. Plus, it's useful for some Error subclasses + to have their own private properties -- and there'd be no way to know whether + these should be copied. For these reasons, VError first-classes these + information properties. You have to provide them in the constructor, you can + only fetch them with the `info()` function, and VError takes care of making + sure properties from causes wind up in the `info()` output. + +Let's put this all together with an example from the node-fast RPC library. +node-fast implements a simple RPC protocol for Node programs. There's a server +and client interface, and clients make RPC requests to servers. Let's say the +server fails with an UnauthorizedError with message "user 'bob' is not +authorized". The client wraps all server errors with a FastServerError. The +client also wraps all request errors with a FastRequestError that includes the +name of the RPC call being made. The result of this failed RPC might look like +this: + + name: FastRequestError + message: "request failed: server error: user 'bob' is not authorized" + rpcMsgid: + rpcMethod: GetObject + cause: + name: FastServerError + message: "server error: user 'bob' is not authorized" + cause: + name: UnauthorizedError + message: "user 'bob' is not authorized" + rpcUser: "bob" + +When the caller uses `VError.info()`, the information properties are collapsed +so that it looks like this: + + message: "request failed: server error: user 'bob' is not authorized" + rpcMsgid: + rpcMethod: GetObject + rpcUser: "bob" + +Taking this apart: + +* The error's message is a complete description of the problem. The caller can + report this directly to its caller, which can potentially make its way back to + an end user (if appropriate). It can also be logged. +* The caller can tell that the request failed on the server, rather than as a + result of a client problem (e.g., failure to serialize the request), a + transport problem (e.g., failure to connect to the server), or something else + (e.g., a timeout). They do this using `findCauseByName('FastServerError')` + rather than checking the `name` field directly. +* If the caller logs this error, the logs can be analyzed to aggregate + errors by cause, by RPC method name, by user, or whatever. Or the + error can be correlated with other events for the same rpcMsgid. +* It wasn't very hard for any part of the code to contribute to this Error. + Each part of the stack has just a few lines to provide exactly what it knows, + with very little boilerplate. + +It's not expected that you'd use these complex forms all the time. Despite +supporting the complex case above, you can still just do: + + new VError("my service isn't working"); + +for the simple cases. + + +# Reference: VError, WError, SError + +VError, WError, and SError are convenient drop-in replacements for `Error` that +support printf-style arguments, first-class causes, informational properties, +and other useful features. + + +## Constructors + +The VError constructor has several forms: + +```javascript +/* + * This is the most general form. You can specify any supported options + * (including "cause" and "info") this way. + */ +new VError(options, sprintf_args...) + +/* + * This is a useful shorthand when the only option you need is "cause". + */ +new VError(cause, sprintf_args...) + +/* + * This is a useful shorthand when you don't need any options at all. + */ +new VError(sprintf_args...) +``` + +All of these forms construct a new VError that behaves just like the built-in +JavaScript `Error` class, with some additional methods described below. + +In the first form, `options` is a plain object with any of the following +optional properties: + +Option name | Type | Meaning +---------------- | ---------------- | ------- +`name` | string | Describes what kind of error this is. This is intended for programmatic use to distinguish between different kinds of errors. Note that in modern versions of Node.js, this name is ignored in the `stack` property value, but callers can still use the `name` property to get at it. +`cause` | any Error object | Indicates that the new error was caused by `cause`. See `cause()` below. If unspecified, the cause will be `null`. +`strict` | boolean | If true, then `null` and `undefined` values in `sprintf_args` are passed through to `sprintf()`. Otherwise, these are replaced with the strings `'null'`, and '`undefined`', respectively. +`constructorOpt` | function | If specified, then the stack trace for this error ends at function `constructorOpt`. Functions called by `constructorOpt` will not show up in the stack. This is useful when this class is subclassed. +`info` | object | Specifies arbitrary informational properties that are available through the `VError.info(err)` static class method. See that method for details. + +The second form is equivalent to using the first form with the specified `cause` +as the error's cause. This form is distinguished from the first form because +the first argument is an Error. + +The third form is equivalent to using the first form with all default option +values. This form is distinguished from the other forms because the first +argument is not an object or an Error. + +The `WError` constructor is used exactly the same way as the `VError` +constructor. The `SError` constructor is also used the same way as the +`VError` constructor except that in all cases, the `strict` property is +overriden to `true. + + +## Public properties + +`VError`, `WError`, and `SError` all provide the same public properties as +JavaScript's built-in Error objects. + +Property name | Type | Meaning +------------- | ------ | ------- +`name` | string | Programmatically-usable name of the error. +`message` | string | Human-readable summary of the failure. Programmatically-accessible details are provided through `VError.info(err)` class method. +`stack` | string | Human-readable stack trace where the Error was constructed. + +For all of these classes, the printf-style arguments passed to the constructor +are processed with `sprintf()` to form a message. For `WError`, this becomes +the complete `message` property. For `SError` and `VError`, this message is +prepended to the message of the cause, if any (with a suitable separator), and +the result becomes the `message` property. + +The `stack` property is managed entirely by the underlying JavaScript +implementation. It's generally implemented using a getter function because +constructing the human-readable stack trace is somewhat expensive. + +## Class methods + +The following methods are defined on the `VError` class and as exported +functions on the `verror` module. They're defined this way rather than using +methods on VError instances so that they can be used on Errors not created with +`VError`. + +### `VError.cause(err)` + +The `cause()` function returns the next Error in the cause chain for `err`, or +`null` if there is no next error. See the `cause` argument to the constructor. +Errors can have arbitrarily long cause chains. You can walk the `cause` chain +by invoking `VError.cause(err)` on each subsequent return value. If `err` is +not a `VError`, the cause is `null`. + +### `VError.info(err)` + +Returns an object with all of the extra error information that's been associated +with this Error and all of its causes. These are the properties passed in using +the `info` option to the constructor. Properties not specified in the +constructor for this Error are implicitly inherited from this error's cause. + +These properties are intended to provide programmatically-accessible metadata +about the error. For an error that indicates a failure to resolve a DNS name, +informational properties might include the DNS name to be resolved, or even the +list of resolvers used to resolve it. The values of these properties should +generally be plain objects (i.e., consisting only of null, undefined, numbers, +booleans, strings, and objects and arrays containing only other plain objects). + +### `VError.fullStack(err)` + +Returns a string containing the full stack trace, with all nested errors recursively +reported as `'caused by:' + err.stack`. + +### `VError.findCauseByName(err, name)` + +The `findCauseByName()` function traverses the cause chain for `err`, looking +for an error whose `name` property matches the passed in `name` value. If no +match is found, `null` is returned. + +If all you want is to know _whether_ there's a cause (and you don't care what it +is), you can use `VError.hasCauseWithName(err, name)`. + +If a vanilla error or a non-VError error is passed in, then there is no cause +chain to traverse. In this scenario, the function will check the `name` +property of only `err`. + +### `VError.hasCauseWithName(err, name)` + +Returns true if and only if `VError.findCauseByName(err, name)` would return +a non-null value. This essentially determines whether `err` has any cause in +its cause chain that has name `name`. + +### `VError.errorFromList(errors)` + +Given an array of Error objects (possibly empty), return a single error +representing the whole collection of errors. If the list has: + +* 0 elements, returns `null` +* 1 element, returns the sole error +* more than 1 element, returns a MultiError referencing the whole list + +This is useful for cases where an operation may produce any number of errors, +and you ultimately want to implement the usual `callback(err)` pattern. You can +accumulate the errors in an array and then invoke +`callback(VError.errorFromList(errors))` when the operation is complete. + + +### `VError.errorForEach(err, func)` + +Convenience function for iterating an error that may itself be a MultiError. + +In all cases, `err` must be an Error. If `err` is a MultiError, then `func` is +invoked as `func(errorN)` for each of the underlying errors of the MultiError. +If `err` is any other kind of error, `func` is invoked once as `func(err)`. In +all cases, `func` is invoked synchronously. + +This is useful for cases where an operation may produce any number of warnings +that may be encapsulated with a MultiError -- but may not be. + +This function does not iterate an error's cause chain. + + +## Examples + +The "Demo" section above covers several basic cases. Here's a more advanced +case: + +```javascript +var err1 = new VError('something bad happened'); +/* ... */ +var err2 = new VError({ + 'name': 'ConnectionError', + 'cause': err1, + 'info': { + 'errno': 'ECONNREFUSED', + 'remote_ip': '127.0.0.1', + 'port': 215 + } +}, 'failed to connect to "%s:%d"', '127.0.0.1', 215); + +console.log(err2.message); +console.log(err2.name); +console.log(VError.info(err2)); +console.log(err2.stack); +``` + +This outputs: + + failed to connect to "127.0.0.1:215": something bad happened + ConnectionError + { errno: 'ECONNREFUSED', remote_ip: '127.0.0.1', port: 215 } + ConnectionError: failed to connect to "127.0.0.1:215": something bad happened + at Object. (/home/dap/node-verror/examples/info.js:5:12) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:935:3 + +Information properties are inherited up the cause chain, with values at the top +of the chain overriding same-named values lower in the chain. To continue that +example: + +```javascript +var err3 = new VError({ + 'name': 'RequestError', + 'cause': err2, + 'info': { + 'errno': 'EBADREQUEST' + } +}, 'request failed'); + +console.log(err3.message); +console.log(err3.name); +console.log(VError.info(err3)); +console.log(err3.stack); +``` + +This outputs: + + request failed: failed to connect to "127.0.0.1:215": something bad happened + RequestError + { errno: 'EBADREQUEST', remote_ip: '127.0.0.1', port: 215 } + RequestError: request failed: failed to connect to "127.0.0.1:215": something bad happened + at Object. (/home/dap/node-verror/examples/info.js:20:12) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:935:3 + +You can also print the complete stack trace of combined `Error`s by using +`VError.fullStack(err).` + +```javascript +var err1 = new VError('something bad happened'); +/* ... */ +var err2 = new VError(err1, 'something really bad happened here'); + +console.log(VError.fullStack(err2)); +``` + +This outputs: + + VError: something really bad happened here: something bad happened + at Object. (/home/dap/node-verror/examples/fullStack.js:5:12) + at Module._compile (module.js:409:26) + at Object.Module._extensions..js (module.js:416:10) + at Module.load (module.js:343:32) + at Function.Module._load (module.js:300:12) + at Function.Module.runMain (module.js:441:10) + at startup (node.js:139:18) + at node.js:968:3 + caused by: VError: something bad happened + at Object. (/home/dap/node-verror/examples/fullStack.js:3:12) + at Module._compile (module.js:409:26) + at Object.Module._extensions..js (module.js:416:10) + at Module.load (module.js:343:32) + at Function.Module._load (module.js:300:12) + at Function.Module.runMain (module.js:441:10) + at startup (node.js:139:18) + at node.js:968:3 + +`VError.fullStack` is also safe to use on regular `Error`s, so feel free to use +it whenever you need to extract the stack trace from an `Error`, regardless if +it's a `VError` or not. + +# Reference: MultiError + +MultiError is an Error class that represents a group of Errors. This is used +when you logically need to provide a single Error, but you want to preserve +information about multiple underying Errors. A common case is when you execute +several operations in parallel and some of them fail. + +MultiErrors are constructed as: + +```javascript +new MultiError(error_list) +``` + +`error_list` is an array of at least one `Error` object. + +The cause of the MultiError is the first error provided. None of the other +`VError` options are supported. The `message` for a MultiError consists the +`message` from the first error, prepended with a message indicating that there +were other errors. + +For example: + +```javascript +err = new MultiError([ + new Error('failed to resolve DNS name "abc.example.com"'), + new Error('failed to resolve DNS name "def.example.com"'), +]); + +console.error(err.message); +``` + +outputs: + + first of 2 errors: failed to resolve DNS name "abc.example.com" + +See the convenience function `VError.errorFromList`, which is sometimes simpler +to use than this constructor. + +## Public methods + + +### `errors()` + +Returns an array of the errors used to construct this MultiError. + + +# Contributing + +See separate [contribution guidelines](CONTRIBUTING.md). diff --git a/node_modules/vasync/node_modules/verror/lib/verror.js b/node_modules/vasync/node_modules/verror/lib/verror.js new file mode 100644 index 0000000..8663dde --- /dev/null +++ b/node_modules/vasync/node_modules/verror/lib/verror.js @@ -0,0 +1,451 @@ +/* + * verror.js: richer JavaScript errors + */ + +var mod_assertplus = require('assert-plus'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); +var mod_isError = require('core-util-is').isError; +var sprintf = mod_extsprintf.sprintf; + +/* + * Public interface + */ + +/* So you can 'var VError = require('verror')' */ +module.exports = VError; +/* For compatibility */ +VError.VError = VError; +/* Other exported classes */ +VError.SError = SError; +VError.WError = WError; +VError.MultiError = MultiError; + +/* + * Common function used to parse constructor arguments for VError, WError, and + * SError. Named arguments to this function: + * + * strict force strict interpretation of sprintf arguments, even + * if the options in "argv" don't say so + * + * argv error's constructor arguments, which are to be + * interpreted as described in README.md. For quick + * reference, "argv" has one of the following forms: + * + * [ sprintf_args... ] (argv[0] is a string) + * [ cause, sprintf_args... ] (argv[0] is an Error) + * [ options, sprintf_args... ] (argv[0] is an object) + * + * This function normalizes these forms, producing an object with the following + * properties: + * + * options equivalent to "options" in third form. This will never + * be a direct reference to what the caller passed in + * (i.e., it may be a shallow copy), so it can be freely + * modified. + * + * shortmessage result of sprintf(sprintf_args), taking options.strict + * into account as described in README.md. + */ +function parseConstructorArguments(args) +{ + var argv, options, sprintf_args, shortmessage, k; + + mod_assertplus.object(args, 'args'); + mod_assertplus.bool(args.strict, 'args.strict'); + mod_assertplus.array(args.argv, 'args.argv'); + argv = args.argv; + + /* + * First, figure out which form of invocation we've been given. + */ + if (argv.length === 0) { + options = {}; + sprintf_args = []; + } else if (mod_isError(argv[0])) { + options = { 'cause': argv[0] }; + sprintf_args = argv.slice(1); + } else if (typeof (argv[0]) === 'object') { + options = {}; + for (k in argv[0]) { + options[k] = argv[0][k]; + } + sprintf_args = argv.slice(1); + } else { + mod_assertplus.string(argv[0], + 'first argument to VError, SError, or WError ' + + 'constructor must be a string, object, or Error'); + options = {}; + sprintf_args = argv; + } + + /* + * Now construct the error's message. + * + * extsprintf (which we invoke here with our caller's arguments in order + * to construct this Error's message) is strict in its interpretation of + * values to be processed by the "%s" specifier. The value passed to + * extsprintf must actually be a string or something convertible to a + * String using .toString(). Passing other values (notably "null" and + * "undefined") is considered a programmer error. The assumption is + * that if you actually want to print the string "null" or "undefined", + * then that's easy to do that when you're calling extsprintf; on the + * other hand, if you did NOT want that (i.e., there's actually a bug + * where the program assumes some variable is non-null and tries to + * print it, which might happen when constructing a packet or file in + * some specific format), then it's better to stop immediately than + * produce bogus output. + * + * However, sometimes the bug is only in the code calling VError, and a + * programmer might prefer to have the error message contain "null" or + * "undefined" rather than have the bug in the error path crash the + * program (making the first bug harder to identify). For that reason, + * by default VError converts "null" or "undefined" arguments to their + * string representations and passes those to extsprintf. Programmers + * desiring the strict behavior can use the SError class or pass the + * "strict" option to the VError constructor. + */ + mod_assertplus.object(options); + if (!options.strict && !args.strict) { + sprintf_args = sprintf_args.map(function (a) { + return (a === null ? 'null' : + a === undefined ? 'undefined' : a); + }); + } + + if (sprintf_args.length === 0) { + shortmessage = ''; + } else { + shortmessage = sprintf.apply(null, sprintf_args); + } + + return ({ + 'options': options, + 'shortmessage': shortmessage + }); +} + +/* + * See README.md for reference documentation. + */ +function VError() +{ + var args, obj, parsed, cause, ctor, message, k; + + args = Array.prototype.slice.call(arguments, 0); + + /* + * This is a regrettable pattern, but JavaScript's built-in Error class + * is defined to work this way, so we allow the constructor to be called + * without "new". + */ + if (!(this instanceof VError)) { + obj = Object.create(VError.prototype); + VError.apply(obj, arguments); + return (obj); + } + + /* + * For convenience and backwards compatibility, we support several + * different calling forms. Normalize them here. + */ + parsed = parseConstructorArguments({ + 'argv': args, + 'strict': false + }); + + /* + * If we've been given a name, apply it now. + */ + if (parsed.options.name) { + mod_assertplus.string(parsed.options.name, + 'error\'s "name" must be a string'); + this.name = parsed.options.name; + } + + /* + * For debugging, we keep track of the original short message (attached + * this Error particularly) separately from the complete message (which + * includes the messages of our cause chain). + */ + this.jse_shortmsg = parsed.shortmessage; + message = parsed.shortmessage; + + /* + * If we've been given a cause, record a reference to it and update our + * message appropriately. + */ + cause = parsed.options.cause; + if (cause) { + mod_assertplus.ok(mod_isError(cause), 'cause is not an Error'); + this.jse_cause = cause; + + if (!parsed.options.skipCauseMessage) { + message += ': ' + cause.message; + } + } + + /* + * If we've been given an object with properties, shallow-copy that + * here. We don't want to use a deep copy in case there are non-plain + * objects here, but we don't want to use the original object in case + * the caller modifies it later. + */ + this.jse_info = {}; + if (parsed.options.info) { + for (k in parsed.options.info) { + this.jse_info[k] = parsed.options.info[k]; + } + } + + this.message = message; + Error.call(this, message); + + if (Error.captureStackTrace) { + ctor = parsed.options.constructorOpt || this.constructor; + Error.captureStackTrace(this, ctor); + } + + return (this); +} + +mod_util.inherits(VError, Error); +VError.prototype.name = 'VError'; + +VError.prototype.toString = function ve_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + + return (str); +}; + +/* + * This method is provided for compatibility. New callers should use + * VError.cause() instead. That method also uses the saner `null` return value + * when there is no cause. + */ +VError.prototype.cause = function ve_cause() +{ + var cause = VError.cause(this); + return (cause === null ? undefined : cause); +}; + +/* + * Static methods + * + * These class-level methods are provided so that callers can use them on + * instances of Errors that are not VErrors. New interfaces should be provided + * only using static methods to eliminate the class of programming mistake where + * people fail to check whether the Error object has the corresponding methods. + */ + +VError.cause = function (err) +{ + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + return (mod_isError(err.jse_cause) ? err.jse_cause : null); +}; + +VError.info = function (err) +{ + var rv, cause, k; + + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + cause = VError.cause(err); + if (cause !== null) { + rv = VError.info(cause); + } else { + rv = {}; + } + + if (typeof (err.jse_info) == 'object' && err.jse_info !== null) { + for (k in err.jse_info) { + rv[k] = err.jse_info[k]; + } + } + + return (rv); +}; + +VError.findCauseByName = function (err, name) +{ + var cause; + + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + mod_assertplus.string(name, 'name'); + mod_assertplus.ok(name.length > 0, 'name cannot be empty'); + + for (cause = err; cause !== null; cause = VError.cause(cause)) { + mod_assertplus.ok(mod_isError(cause)); + if (cause.name == name) { + return (cause); + } + } + + return (null); +}; + +VError.hasCauseWithName = function (err, name) +{ + return (VError.findCauseByName(err, name) !== null); +}; + +VError.fullStack = function (err) +{ + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + + var cause = VError.cause(err); + + if (cause) { + return (err.stack + '\ncaused by: ' + VError.fullStack(cause)); + } + + return (err.stack); +}; + +VError.errorFromList = function (errors) +{ + mod_assertplus.arrayOfObject(errors, 'errors'); + + if (errors.length === 0) { + return (null); + } + + errors.forEach(function (e) { + mod_assertplus.ok(mod_isError(e)); + }); + + if (errors.length == 1) { + return (errors[0]); + } + + return (new MultiError(errors)); +}; + +VError.errorForEach = function (err, func) +{ + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + mod_assertplus.func(func, 'func'); + + if (err instanceof MultiError) { + err.errors().forEach(function iterError(e) { func(e); }); + } else { + func(err); + } +}; + + +/* + * SError is like VError, but stricter about types. You cannot pass "null" or + * "undefined" as string arguments to the formatter. + */ +function SError() +{ + var args, obj, parsed, options; + + args = Array.prototype.slice.call(arguments, 0); + if (!(this instanceof SError)) { + obj = Object.create(SError.prototype); + SError.apply(obj, arguments); + return (obj); + } + + parsed = parseConstructorArguments({ + 'argv': args, + 'strict': true + }); + + options = parsed.options; + VError.call(this, options, '%s', parsed.shortmessage); + + return (this); +} + +/* + * We don't bother setting SError.prototype.name because once constructed, + * SErrors are just like VErrors. + */ +mod_util.inherits(SError, VError); + + +/* + * Represents a collection of errors for the purpose of consumers that generally + * only deal with one error. Callers can extract the individual errors + * contained in this object, but may also just treat it as a normal single + * error, in which case a summary message will be printed. + */ +function MultiError(errors) +{ + mod_assertplus.array(errors, 'list of errors'); + mod_assertplus.ok(errors.length > 0, 'must be at least one error'); + this.ase_errors = errors; + + VError.call(this, { + 'cause': errors[0] + }, 'first of %d error%s', errors.length, errors.length == 1 ? '' : 's'); +} + +mod_util.inherits(MultiError, VError); +MultiError.prototype.name = 'MultiError'; + +MultiError.prototype.errors = function me_errors() +{ + return (this.ase_errors.slice(0)); +}; + + +/* + * See README.md for reference details. + */ +function WError() +{ + var args, obj, parsed, options; + + args = Array.prototype.slice.call(arguments, 0); + if (!(this instanceof WError)) { + obj = Object.create(WError.prototype); + WError.apply(obj, args); + return (obj); + } + + parsed = parseConstructorArguments({ + 'argv': args, + 'strict': false + }); + + options = parsed.options; + options['skipCauseMessage'] = true; + VError.call(this, options, '%s', parsed.shortmessage); + + return (this); +} + +mod_util.inherits(WError, VError); +WError.prototype.name = 'WError'; + +WError.prototype.toString = function we_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + if (this.jse_cause && this.jse_cause.message) + str += '; caused by ' + this.jse_cause.toString(); + + return (str); +}; + +/* + * For purely historical reasons, WError's cause() function allows you to set + * the cause. + */ +WError.prototype.cause = function we_cause(c) +{ + if (mod_isError(c)) + this.jse_cause = c; + + return (this.jse_cause); +}; diff --git a/node_modules/vasync/node_modules/verror/package.json b/node_modules/vasync/node_modules/verror/package.json new file mode 100644 index 0000000..79295c5 --- /dev/null +++ b/node_modules/vasync/node_modules/verror/package.json @@ -0,0 +1,22 @@ +{ + "name": "verror", + "version": "1.10.0", + "description": "richer JavaScript errors", + "main": "./lib/verror.js", + "repository": { + "type": "git", + "url": "git://github.com/davepacheco/node-verror.git" + }, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": [ + "node >=0.6.0" + ], + "scripts": { + "test": "make test" + }, + "license": "MIT" +} diff --git a/node_modules/vasync/package.json b/node_modules/vasync/package.json new file mode 100644 index 0000000..1dedbd8 --- /dev/null +++ b/node_modules/vasync/package.json @@ -0,0 +1,24 @@ +{ + "name": "vasync", + "version": "2.2.1", + "description": "utilities for observable asynchronous control flow", + "main": "./lib/vasync.js", + "repository": { + "type": "git", + "url": "https://github.com/joyent/node-vasync.git" + }, + "scripts": { + "test": "./node_modules/.bin/tap --stdout tests/ && ./node_modules/.bin/nodeunit tests/compat.js && ./node_modules/.bin/nodeunit tests/compat_tryEach.js" + }, + "devDependencies": { + "tap": "~0.4.8", + "nodeunit": "0.8.7" + }, + "dependencies": { + "verror": "1.10.0" + }, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" +} diff --git a/node_modules/vasync/tests/compat.js b/node_modules/vasync/tests/compat.js new file mode 100644 index 0000000..8461a82 --- /dev/null +++ b/node_modules/vasync/tests/compat.js @@ -0,0 +1,104 @@ +/* + * tests/compat.js: Some of the APIs provided by vasync are intended to be + * API-compatible with node-async, so we incorporate the tests from node-async + * directly here. These are copied from https://github.com/caolan/async, + * available under the MIT license. To make it easy to update this from the + * source, this file should remain unchanged from the source except for this + * header comment, the change to the "require" line, and deleted lines for + * unimplemented functions. + * + * The following tests are deliberately omitted: + * + * o "waterfall non-array": Per Joyent's Best Practices for Node.js Error + * Handling, we're strict about argument types and throw on these programmer + * errors rather than emitting them asynchronously. + * + * o "waterfall multiple callback calls": We deliberately disallow a waterfall + * function to invoke its callback more than once, so we don't test for that + * here. The behavior that node-async allows can potentially be used to fork + * the waterfall, which may be useful, but it's often used instead as an + * excuse to write code sloppily. And the downside is that it makes it really + * hard to understand bugs where the waterfall was resumed too early. For + * now, we're disallowing it, but if the forking behavior becomes useful, we + * can always make our version less strict. + */ +var async = require('../lib/vasync'); + +exports['waterfall'] = function(test){ + test.expect(6); + var call_order = []; + async.waterfall([ + function(callback){ + call_order.push('fn1'); + setTimeout(function(){callback(null, 'one', 'two');}, 0); + }, + function(arg1, arg2, callback){ + call_order.push('fn2'); + test.equals(arg1, 'one'); + test.equals(arg2, 'two'); + setTimeout(function(){callback(null, arg1, arg2, 'three');}, 25); + }, + function(arg1, arg2, arg3, callback){ + call_order.push('fn3'); + test.equals(arg1, 'one'); + test.equals(arg2, 'two'); + test.equals(arg3, 'three'); + callback(null, 'four'); + }, + function(arg4, callback){ + call_order.push('fn4'); + test.same(call_order, ['fn1','fn2','fn3','fn4']); + callback(null, 'test'); + } + ], function(err){ + test.done(); + }); +}; + +exports['waterfall empty array'] = function(test){ + async.waterfall([], function(err){ + test.done(); + }); +}; + +exports['waterfall no callback'] = function(test){ + async.waterfall([ + function(callback){callback();}, + function(callback){callback(); test.done();} + ]); +}; + +exports['waterfall async'] = function(test){ + var call_order = []; + async.waterfall([ + function(callback){ + call_order.push(1); + callback(); + call_order.push(2); + }, + function(callback){ + call_order.push(3); + callback(); + }, + function(){ + test.same(call_order, [1,2,3]); + test.done(); + } + ]); +}; + +exports['waterfall error'] = function(test){ + test.expect(1); + async.waterfall([ + function(callback){ + callback('error'); + }, + function(callback){ + test.ok(false, 'next function should not be called'); + callback(); + } + ], function(err){ + test.equals(err, 'error'); + }); + setTimeout(test.done, 50); +}; diff --git a/node_modules/vasync/tests/compat_tryEach.js b/node_modules/vasync/tests/compat_tryEach.js new file mode 100644 index 0000000..150210a --- /dev/null +++ b/node_modules/vasync/tests/compat_tryEach.js @@ -0,0 +1,91 @@ +var async = require('../lib/vasync'); + +/* + * tryEach tests, transliterated from mocha to tap. + * + * They are nearly identical except for some details related to vasync. For + * example, we don't support calling the callback more than once from any of + * the given functions. + */ + + +exports['tryEach no callback'] = function (test) { + async.tryEach([]); + test.done(); +}; +exports['tryEach empty'] = function (test) { + async.tryEach([], function (err, results) { + test.equals(err, null); + test.same(results, undefined); + test.done(); + }); +}; +exports['tryEach one task, multiple results'] = function (test) { + var RESULTS = ['something', 'something2']; + async.tryEach([ + function (callback) { + callback(null, RESULTS[0], RESULTS[1]); + } + ], function (err, results) { + test.equals(err, null); + test.same(results, RESULTS); + test.done(); + }); +}; +exports['tryEach one task'] = function (test) { + var RESULT = 'something'; + async.tryEach([ + function (callback) { + callback(null, RESULT); + } + ], function (err, results) { + test.equals(err, null); + test.same(results, RESULT); + test.done(); + }); +}; +exports['tryEach two tasks, one failing'] = function (test) { + var RESULT = 'something'; + async.tryEach([ + function (callback) { + callback(new Error('Failure'), {}); + }, + function (callback) { + callback(null, RESULT); + } + ], function (err, results) { + test.equals(err, null); + test.same(results, RESULT); + test.done(); + }); +}; +exports['tryEach two tasks, both failing'] = function (test) { + var ERROR_RESULT = new Error('Failure2'); + async.tryEach([ + function (callback) { + callback(new Error('Should not stop here')); + }, + function (callback) { + callback(ERROR_RESULT); + } + ], function (err, results) { + test.equals(err, ERROR_RESULT); + test.same(results, undefined); + test.done(); + }); +}; +exports['tryEach two tasks, non failing'] = function (test) { + var RESULT = 'something'; + async.tryEach([ + function (callback) { + callback(null, RESULT); + }, + function () { + test.fail('Should not been called'); + } + ], function (err, results) { + test.equals(err, null); + test.same(results, RESULT); + test.done(); + }); +}; diff --git a/node_modules/vasync/tests/filter.js b/node_modules/vasync/tests/filter.js new file mode 100644 index 0000000..c5ef915 --- /dev/null +++ b/node_modules/vasync/tests/filter.js @@ -0,0 +1,226 @@ +/* + * Tests the "filter", "filterSeries", and "filterLimit" functions + */ + +var mod_util = require('util'); + +var mod_tap = require('tap'); +var mod_vasync = require('..'); + +mod_tap.test('filterSeries', function (test) { + var inputs = [0, 1, 2, 3, 4, 5]; + var curTasks = 0; + var maxTasks = 0; + // filterSeries has an implicit limit of 1 concurrent operation + var limit = 1; + + function filterFunc(input, cb) { + curTasks++; + if (curTasks > maxTasks) { + maxTasks = curTasks; + } + test.ok(curTasks <= limit, mod_util.format( + 'input %d: current tasks %d <= %d', + input, curTasks, limit)); + + setTimeout(function () { + curTasks--; + cb(null, input < 2 || input === 4); + }, 50); + } + + mod_vasync.filterSeries(inputs, filterFunc, + function filterDone(err, results) { + + test.ok(!err, 'error unset'); + test.equal(maxTasks, limit, 'max tasks reached limit'); + test.deepEqual(results, [0, 1, 4], 'results array correct'); + test.end(); + }); +}); + +mod_tap.test('filterLimit', function (test) { + var inputs = [0, 1, 2, 3, 4, 5]; + var curTasks = 0; + var maxTasks = 0; + var limit = 2; + + function filterFunc(input, cb) { + curTasks++; + if (curTasks > maxTasks) { + maxTasks = curTasks; + } + test.ok(curTasks <= limit, mod_util.format( + 'input %d: current tasks %d <= %d', + input, curTasks, limit)); + + setTimeout(function () { + curTasks--; + cb(null, input < 2 || input === 4); + }, 50); + } + + mod_vasync.filterLimit(inputs, limit, filterFunc, + function filterDone(err, results) { + + test.ok(!err, 'error unset'); + test.equal(maxTasks, limit, 'max tasks reached limit'); + test.deepEqual(results, [0, 1, 4], 'results array correct'); + test.end(); + }); +}); + +mod_tap.test('filter (maintain order)', function (test) { + var inputs = [0, 1, 2, 3, 4, 5]; + var limit = inputs.length; + var storedValues = []; + + function filterFunc(input, cb) { + /* + * Hold every callback in an array to be called when all + * filterFunc's have run. This way, we can ensure that all + * tasks have started without waiting for any others to finish. + */ + storedValues.push({ + input: input, + cb: cb + }); + + test.ok(storedValues.length <= limit, mod_util.format( + 'input %d: current tasks %d <= %d', + input, storedValues.length, limit)); + + /* + * When this constraint is true, all filterFunc's have run for + * each input. We now call all callbacks in a pre-determined + * order (out of order of the original) to ensure the final + * array is in the correct order. + */ + if (storedValues.length === inputs.length) { + [5, 2, 0, 1, 4, 3].forEach(function (i) { + var o = storedValues[i]; + o.cb(null, o.input < 2 || o.input === 4); + }); + } + } + + mod_vasync.filter(inputs, filterFunc, + function filterDone(err, results) { + + test.ok(!err, 'error unset'); + test.equal(storedValues.length, inputs.length, + 'max tasks reached limit'); + test.deepEqual(results, [0, 1, 4], 'results array correct'); + test.end(); + }); +}); + +mod_tap.test('filterSeries error handling', function (test) { + /* + * We will error half way through the list of inputs to ensure that + * first half are processed while the second half are ignored. + */ + var inputs = [0, 1, 2, 3, 4, 5]; + + function filterFunc(input, cb) { + switch (input) { + case 0: + case 1: + case 2: + cb(null, true); + break; + case 3: + cb(new Error('error on ' + input)); + break; + case 4: + case 5: + test.ok(false, 'processed too many inputs'); + cb(new Error('processed too many inputs')); + break; + default: + test.ok(false, 'unexpected input: ' + input); + cb(new Error('unexpected input')); + break; + } + } + + mod_vasync.filterSeries(inputs, filterFunc, + function filterDone(err, results) { + + test.ok(err, 'error set'); + test.ok(err.message === 'error on 3', 'error on input 3'); + test.ok(results === undefined, 'results is unset'); + test.end(); + }); +}); + +mod_tap.test('filterSeries double callback', function (test) { + var inputs = [0, 1, 2, 3, 4, 5]; + + function filterFunc(input, cb) { + switch (input) { + case 0: + case 1: + case 2: + cb(null, true); + break; + case 3: + /* + * The first call to cb() should "win" - meaning this + * value will be filtered out of the final array of + * results. + */ + cb(null, false); + test.throws(function () { + cb(null, true); + }); + break; + case 4: + /* + * Like input 3, all subsequent calls to cb() will + * throw an error and not affect the original call to + * cb(). + */ + cb(null, true); + test.throws(function () { + cb(new Error('uh oh')); + }); + break; + case 5: + cb(null, true); + break; + default: + test.ok(false, 'unexpected input: ' + input); + cb(new Error('unexpected input')); + break; + } + } + + mod_vasync.filterSeries(inputs, filterFunc, + function filterDone(err, results) { + + test.ok(!err, 'error not set'); + test.deepEqual(results, [0, 1, 2, 4, 5], + 'results array correct'); + test.end(); + }); +}); + +mod_tap.test('filter push to queue object error', function (test) { + var inputs = [0, 1, 2, 3, 4, 5]; + + function filterFunc(input, cb) { + cb(null, true); + } + + var q = mod_vasync.filterSeries(inputs, filterFunc, + function filterDone(err, results) { + + test.end(); + }); + + test.equal(q.closed, true, 'queue is closed'); + test.throws(function () { + q.push(6); + }); +}); diff --git a/node_modules/vasync/tests/issue-21.js b/node_modules/vasync/tests/issue-21.js new file mode 100644 index 0000000..4cf5329 --- /dev/null +++ b/node_modules/vasync/tests/issue-21.js @@ -0,0 +1,25 @@ +/* + * Tests that if the user modifies the list of functions passed to + * vasync.pipeline, vasync ignores the changes and does not crash. + */ +var assert = require('assert'); +var vasync = require('../lib/vasync'); +var count = 0; +var funcs; + +function doStuff(_, callback) +{ + count++; + setImmediate(callback); +} + +funcs = [ doStuff, doStuff, doStuff ]; + +vasync.pipeline({ + 'funcs': funcs +}, function (err) { + assert.ok(!err); + assert.ok(count === 3); +}); + +funcs.push(doStuff); diff --git a/node_modules/vasync/tests/pipeline.js b/node_modules/vasync/tests/pipeline.js new file mode 100644 index 0000000..96bc8c2 --- /dev/null +++ b/node_modules/vasync/tests/pipeline.js @@ -0,0 +1,132 @@ +/* + * Tests the "pipeline" primitive. + */ + +var mod_tap = require('tap'); +var mod_vasync = require('..'); +var st; + + +mod_tap.test('empty pipeline', function (test) { + var count = 0; + st = mod_vasync.pipeline({'funcs': [], 'arg': null}, + function (err, result) { + + test.ok(err === null); + test.ok(result.ndone === 0); + test.ok(result.nerrors === 0); + test.ok(result.operations.length === 0); + test.ok(result.successes.length === 0); + test.equal(count, 1); + test.end(); + }); + count++; + test.ok(st.ndone === 0); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 0); + test.ok(st.successes.length === 0); +}); + +mod_tap.test('normal 4-stage pipeline', function (test) { + var count = 0; + st = mod_vasync.pipeline({'funcs': [ + function func1(_, cb) { + test.equal(st.successes[0], undefined, + 'func1: successes'); + test.ok(count === 0, 'func1: count === 0'); + test.ok(st.ndone === 0); + count++; + setImmediate(cb, null, count); + }, + function func2(_, cb) { + test.equal(st.successes[0], 1, 'func2: successes'); + test.ok(count == 1, 'func2: count == 1'); + test.ok(st.ndone === 1); + test.ok(st.operations[0].status == 'ok'); + test.ok(st.operations[1].status == 'pending'); + test.ok(st.operations[2].status == 'waiting'); + count++; + setImmediate(cb, null, count); + }, + function (_, cb) { + test.equal(st.successes[0], 1, 'func3: successes'); + test.equal(st.successes[1], 2, 'func3: successes'); + test.ok(count == 2, 'func3: count == 2'); + test.ok(st.ndone === 2); + count++; + setImmediate(cb, null, count); + }, + function func4(_, cb) { + test.equal(st.successes[0], 1, 'func4: successes'); + test.equal(st.successes[1], 2, 'func4: successes'); + test.equal(st.successes[2], 3, 'func4: successes'); + test.ok(count == 3, 'func4: count == 3'); + test.ok(st.ndone === 3); + count++; + setImmediate(cb, null, count); + } + ]}, function (err, result) { + test.ok(count == 4, 'final: count == 4'); + test.ok(err === null, 'no error'); + test.ok(result === st); + test.equal(result, st, 'final-cb: st == result'); + test.equal(st.successes[0], 1, 'final-cb: successes'); + test.equal(st.successes[1], 2, 'final-cb: successes'); + test.equal(st.successes[2], 3, 'final-cb: successes'); + test.equal(st.successes[3], 4, 'final-cb: successes'); + test.ok(st.ndone === 4); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 4); + test.ok(st.successes.length === 4); + test.ok(st.operations[0].status == 'ok'); + test.ok(st.operations[1].status == 'ok'); + test.ok(st.operations[2].status == 'ok'); + test.ok(st.operations[3].status == 'ok'); + test.end(); + }); + test.ok(st.ndone === 0); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 4); + test.ok(st.operations[0].funcname == 'func1', 'func1 name'); + test.ok(st.operations[0].status == 'pending'); + test.ok(st.operations[1].funcname == 'func2', 'func2 name'); + test.ok(st.operations[1].status == 'waiting'); + test.ok(st.operations[2].funcname == '(anon)', 'anon name'); + test.ok(st.operations[2].status == 'waiting'); + test.ok(st.operations[3].funcname == 'func4', 'func4 name'); + test.ok(st.operations[3].status == 'waiting'); + test.ok(st.successes.length === 0); +}); + +mod_tap.test('bailing out early', function (test) { + var count = 0; + st = mod_vasync.pipeline({'funcs': [ + function func1(_, cb) { + test.ok(count === 0, 'func1: count === 0'); + count++; + setImmediate(cb, null, count); + }, + function func2(_, cb) { + test.ok(count == 1, 'func2: count == 1'); + count++; + setImmediate(cb, new Error('boom!')); + }, + function func3(_, cb) { + test.ok(count == 2, 'func3: count == 2'); + count++; + setImmediate(cb, null, count); + } + ]}, function (err, result) { + test.ok(count == 2, 'final: count == 3'); + test.equal(err.message, 'boom!'); + test.ok(result === st); + test.equal(result, st, 'final-cb: st == result'); + test.ok(st.ndone == 2); + test.ok(st.nerrors == 1); + test.ok(st.operations[0].status == 'ok'); + test.ok(st.operations[1].status == 'fail'); + test.ok(st.operations[2].status == 'waiting'); + test.ok(st.successes.length == 1); + test.end(); + }); +}); diff --git a/node_modules/vasync/tests/queue.js b/node_modules/vasync/tests/queue.js new file mode 100644 index 0000000..52030ea --- /dev/null +++ b/node_modules/vasync/tests/queue.js @@ -0,0 +1,284 @@ +/* vim: set ts=8 sts=8 sw=8 noet: */ + +var mod_tap = require('tap'); +var mod_vasync = require('..'); + +function +immediate_worker(task, next) +{ + setImmediate(function () { + next(); + }); +} + +function +sametick_worker(task, next) +{ + next(); +} + +function +random_delay_worker(task, next) +{ + setTimeout(function () { + next(); + }, Math.floor(Math.random() * 250)); +} + +mod_tap.test('must not push after close', function (test) { + test.plan(3); + + var q = mod_vasync.queuev({ + worker: immediate_worker, + concurrency: 10 + }); + test.ok(q); + + test.doesNotThrow(function () { + q.push({}); + }, 'push should not throw _before_ close()'); + + q.close(); + + /* + * If we attempt to add tasks to the queue _after_ calling close(), + * we should get an exception: + */ + test.throws(function () { + q.push({}); + }, 'push should throw _after_ close()'); + + test.end(); +}); + +mod_tap.test('get \'end\' event with close()', function (test) { + var task_count = 45; + var tasks_finished = 0; + var seen_end = false; + var seen_drain = false; + + test.plan(14 + task_count); + + var q = mod_vasync.queuev({ + worker: random_delay_worker, + concurrency: 5 + }); + test.ok(q); + + /* + * Enqueue a bunch of tasks; more than our concurrency: + */ + for (var i = 0; i < 45; i++) { + q.push({}, function () { + tasks_finished++; + test.ok(true); + }); + } + + /* + * Close the queue to signify that we're done now. + */ + test.equal(q.ended, false); + test.equal(q.closed, false); + q.close(); + test.equal(q.closed, true); + test.equal(q.ended, false); + + q.on('drain', function () { + /* + * 'drain' should fire before 'end': + */ + test.notOk(seen_drain); + test.notOk(seen_end); + seen_drain = true; + }); + q.on('end', function () { + /* + * 'end' should fire after 'drain': + */ + test.ok(seen_drain); + test.notOk(seen_end); + seen_end = true; + + /* + * Check the public state: + */ + test.equal(q.closed, true); + test.equal(q.ended, true); + + /* + * We should have fired the callbacks for _all_ enqueued + * tasks by now: + */ + test.equal(task_count, tasks_finished); + test.end(); + }); + + /* + * Check that we see neither the 'drain', nor the 'end' event before + * the end of this tick: + */ + test.notOk(seen_drain); + test.notOk(seen_end); +}); + +mod_tap.test('get \'end\' event with close() and no tasks', function (test) { + var seen_drain = false; + var seen_end = false; + + test.plan(10); + + var q = mod_vasync.queuev({ + worker: immediate_worker, + concurrency: 10 + }); + + setImmediate(function () { + test.notOk(seen_end); + }); + + test.equal(q.ended, false); + test.equal(q.closed, false); + q.close(); + test.equal(q.closed, true); + test.equal(q.ended, false); + test.notOk(seen_end); + + q.on('drain', function () { + seen_drain = true; + }); + q.on('end', function () { + /* + * We do not expect to see a 'drain' event, as there were no + * tasks pushed onto the queue before we closed it. + */ + test.notOk(seen_drain); + test.notOk(seen_end); + test.equal(q.closed, true); + test.equal(q.ended, true); + seen_end = true; + test.end(); + }); +}); + +/* + * We want to ensure that both the 'drain' event and the q.drain() hook are + * called the same number of times: + */ +mod_tap.test('equivalence of on(\'drain\') and q.drain()', function (test) { + var enqcount = 4; + var drains = 4; + var ee_count = 0; + var fn_count = 0; + + test.plan(enqcount + drains + 3); + + var q = mod_vasync.queuev({ + worker: immediate_worker, + concurrency: 10 + }); + + var enq = function () { + if (--enqcount < 0) + return; + + q.push({}, function () { + test.ok(true, 'task completion'); + }); + }; + + var draino = function () { + test.ok(true, 'drain called'); + if (--drains === 0) { + test.equal(q.closed, false, 'not closed'); + test.equal(q.ended, false, 'not ended'); + test.equal(fn_count, ee_count, 'same number of calls'); + test.end(); + } + }; + + enq(); + enq(); + + q.on('drain', function () { + ee_count++; + enq(); + draino(); + }); + q.drain = function () { + fn_count++; + enq(); + draino(); + }; +}); + +/* + * In the past, we've only handed on the _first_ argument to the task completion + * callback. Make sure we hand on _all_ of the arguments now: + */ +mod_tap.test('ensure all arguments passed to push() callback', function (test) { + test.plan(13); + + var q = mod_vasync.queuev({ + worker: function (task, callback) { + if (task.fail) { + callback(new Error('guru meditation')); + return; + } + callback(null, 1, 2, 3, 5, 8); + }, + concurrency: 1 + }); + + q.push({ fail: true }, function (err, a, b, c, d, e) { + test.ok(err, 'got the error'); + test.equal(err.message, 'guru meditation'); + test.type(a, 'undefined'); + test.type(b, 'undefined'); + test.type(c, 'undefined'); + test.type(d, 'undefined'); + test.type(e, 'undefined'); + }); + + q.push({ fail: false }, function (err, a, b, c, d, e) { + test.notOk(err, 'got no error'); + test.equal(a, 1); + test.equal(b, 2); + test.equal(c, 3); + test.equal(d, 5); + test.equal(e, 8); + }); + + q.drain = function () { + test.end(); + }; +}); + +mod_tap.test('queue kill', function (test) { + // Derived from async queue.kill test + var count = 0; + var q = mod_vasync.queuev({ + worker: function (task, callback) { + setImmediate(function () { + test.ok(++count < 2, + 'Function should be called once'); + callback(); + }); + }, + concurrency: 1 + }); + q.drain = function () { + test.ok(false, 'Function should never be called'); + }; + + // Queue twice, the first will exec immediately + q.push(0); + q.push(0); + + q.kill(); + + q.on('end', function () { + test.ok(q.killed); + test.end(); + }); +}); diff --git a/node_modules/vasync/tests/queue_concurrency.js b/node_modules/vasync/tests/queue_concurrency.js new file mode 100644 index 0000000..c9251db --- /dev/null +++ b/node_modules/vasync/tests/queue_concurrency.js @@ -0,0 +1,181 @@ +/* vim: set ts=8 sts=8 sw=8 noet: */ + +var mod_tap = require('tap'); +var mod_vasync = require('..'); + +function +latched_worker(task, cb) +{ + if (task.immediate) { + cb(); + } else { + task.latched = true; + task.unlatch = function () { + task.latched = false; + cb(); + }; + } +} + +function +unlatchAll(tasks) +{ + tasks.forEach(function (t) { + if (t.latched) { + t.unlatch(); + } + }); +} + +function +setAllImmediate(tasks) +{ + tasks.forEach(function (t) { + t.immediate = true; + }); +} + +mod_tap.test('test serial tasks', function (test) { + test.plan(2); + + var q = mod_vasync.queuev({ + worker: latched_worker, + concurrency: 1 + }); + test.ok(q); + + var tasks = []; + for (var i = 0; i < 2; ++i) { + tasks.push({ + 'id': i, + 'latched': false, + 'immediate': false + }); + } + + setTimeout(function () { + var latched = 0; + tasks.forEach(function (t) { + if (t.latched) { + ++latched; + } + }); + test.ok(latched === 1); + unlatchAll(tasks); + setAllImmediate(tasks); + }, 10); + + q.on('drain', function () { + q.close(); + }); + + q.on('end', function () { + test.end(); + }); + + q.push(tasks); +}); + +mod_tap.test('test parallel tasks', function (test) { + test.plan(2); + + var q = mod_vasync.queuev({ + worker: latched_worker, + concurrency: 2 + }); + test.ok(q); + + var tasks = []; + for (var i = 0; i < 3; ++i) { + tasks.push({ + 'id': i, + 'latched': false, + 'immediate': false + }); + } + + setTimeout(function () { + var latched = 0; + tasks.forEach(function (t) { + if (t.latched) { + ++latched; + } + }); + test.ok(latched === 2); + unlatchAll(tasks); + setAllImmediate(tasks); + }, 10); + + q.on('drain', function () { + q.close(); + }); + + q.on('end', function () { + test.end(); + }); + + q.push(tasks); +}); + +mod_tap.test('test ratchet up and down', function (test) { + test.plan(8); + + var q = mod_vasync.queuev({ + worker: latched_worker, + concurrency: 2 + }); + test.ok(q); + + var bounced = 0; + var tasks = []; + for (var i = 0; i < 21; ++i) { + tasks.push({ + 'id': i, + 'latched': false, + 'immediate': false + }); + } + + function count() { + var latched = 0; + tasks.forEach(function (t) { + if (t.latched) { + ++latched; + } + }); + return (latched); + } + + function fiveLatch() { + if (!q.closed) { + ++bounced; + test.ok(count() === 5); + q.updateConcurrency(2); + unlatchAll(tasks); + setTimeout(twoLatch, 10); + } + } + + function twoLatch() { + if (!q.closed) { + ++bounced; + test.ok(count() === 2); + q.updateConcurrency(5); + unlatchAll(tasks); + setTimeout(fiveLatch, 10); + } + } + setTimeout(twoLatch, 10); + + q.on('drain', function () { + q.close(); + }); + + q.on('end', function () { + // 21 tasks === 5 * 3 + 2 * 3 === 6 bounces + test.ok(bounced === 6); + test.end(); + }); + + q.push(tasks); +}); diff --git a/node_modules/vasync/tests/waterfall.js b/node_modules/vasync/tests/waterfall.js new file mode 100644 index 0000000..a16789c --- /dev/null +++ b/node_modules/vasync/tests/waterfall.js @@ -0,0 +1,179 @@ +/* + * Tests the "waterfall" primitive. + */ + +var mod_tap = require('tap'); +var mod_vasync = require('..'); + +var count = 0; +var st; + +mod_tap.test('empty waterfall', function (test) { + st = mod_vasync.waterfall([], function (err) { + test.ok(err === null); + test.ok(st.ndone === 0); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 0); + test.ok(st.successes.length === 0); + test.equal(count, 1); + test.end(); + }); + count++; + test.ok(st.ndone === 0); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 0); + test.ok(st.successes.length === 0); +}); + +mod_tap.test('normal 4-stage waterfall', function (test) { + count = 0; + st = mod_vasync.waterfall([ + function func1(cb) { + test.ok(count === 0, 'func1: count === 0'); + test.ok(st.ndone === 0); + count++; + setTimeout(cb, 20, null, { 'hello': 'world' }); + }, + function func2(extra, cb) { + test.equal(extra.hello, 'world', 'func2: extra arg'); + test.ok(count == 1, 'func2: count == 1'); + test.ok(st.ndone === 1); + test.ok(st.operations[0].status == 'ok'); + test.ok(st.operations[1].status == 'pending'); + test.ok(st.operations[2].status == 'waiting'); + count++; + setTimeout(cb, 20, null, 5, 6, 7); + }, + function (five, six, seven, cb) { + test.equal(five, 5, 'func3: extra arg'); + test.equal(six, 6, 'func3: extra arg'); + test.equal(seven, 7, 'func3: extra arg'); + test.ok(count == 2, 'func3: count == 2'); + test.ok(st.ndone === 2); + count++; + setTimeout(cb, 20); + }, + function func4(cb) { + test.ok(count == 3, 'func4: count == 2'); + test.ok(st.ndone === 3); + count++; + setTimeout(cb, 20, null, 8, 9); + } + ], function (err, eight, nine) { + test.ok(count == 4, 'final: count == 4'); + test.ok(err === null, 'no error'); + test.ok(eight == 8); + test.ok(nine == 9); + test.ok(st.ndone === 4); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 4); + test.ok(st.successes.length === 4); + test.ok(st.operations[0].status == 'ok'); + test.ok(st.operations[1].status == 'ok'); + test.ok(st.operations[2].status == 'ok'); + test.ok(st.operations[3].status == 'ok'); + test.end(); + }); + test.ok(st.ndone === 0); + test.ok(st.nerrors === 0); + test.ok(st.operations.length === 4); + test.ok(st.operations[0].funcname == 'func1', 'func1 name'); + test.ok(st.operations[0].status == 'pending'); + test.ok(st.operations[1].funcname == 'func2', 'func2 name'); + test.ok(st.operations[1].status == 'waiting'); + test.ok(st.operations[2].funcname == '(anon)', 'anon name'); + test.ok(st.operations[2].status == 'waiting'); + test.ok(st.operations[3].funcname == 'func4', 'func4 name'); + test.ok(st.operations[3].status == 'waiting'); + test.ok(st.successes.length === 0); +}); + +mod_tap.test('bailing out early', function (test) { + count = 0; + st = mod_vasync.waterfall([ + function func1(cb) { + test.ok(count === 0, 'func1: count === 0'); + count++; + setTimeout(cb, 20); + }, + function func2(cb) { + test.ok(count == 1, 'func2: count == 1'); + count++; + setTimeout(cb, 20, new Error('boom!')); + }, + function func3(cb) { + test.ok(count == 2, 'func3: count == 2'); + count++; + setTimeout(cb, 20); + } + ], function (err) { + test.ok(count == 2, 'final: count == 3'); + test.equal(err.message, 'boom!'); + test.ok(st.ndone == 2); + test.ok(st.nerrors == 1); + test.ok(st.operations[0].status == 'ok'); + test.ok(st.operations[1].status == 'fail'); + test.ok(st.operations[2].status == 'waiting'); + test.ok(st.successes.length == 1); + test.end(); + }); +}); + +mod_tap.test('bad function', function (test) { + count = 0; + st = mod_vasync.waterfall([ + function func1(cb) { + count++; + cb(); + setTimeout(function () { + test.throws( + function () { cb(); process.abort(); }, + 'vasync.waterfall: ' + + 'function 0 ("func1") invoked its ' + + 'callback twice'); + test.equal(count, 2); + test.end(); + }, 100); + }, + function func2(cb) { + count++; + /* do nothing -- we'll throw an exception first */ + } + ], function (err) { + /* not reached */ + console.error('didn\'t expect to finish'); + process.abort(); + }); +}); + +mod_tap.test('badargs', function (test) { + test.throws(function () { mod_vasync.waterfall(); }); + test.throws(function () { mod_vasync.waterfall([], 'foo'); }); + test.throws(function () { mod_vasync.waterfall('foo', 'bar'); }); + test.end(); +}); + +mod_tap.test('normal waterfall, no callback', function (test) { + count = 0; + st = mod_vasync.waterfall([ + function func1(cb) { + test.ok(count === 0); + count++; + setImmediate(cb); + }, + function func2(cb) { + test.ok(count == 1); + count++; + setImmediate(cb); + setTimeout(function () { + test.ok(count == 2); + test.end(); + }, 100); + } + ]); +}); + +mod_tap.test('empty waterfall, no callback', function (test) { + st = mod_vasync.waterfall([]); + setTimeout(function () { test.end(); }, 100); +}); diff --git a/node_modules/vasync/tests/whilst.js b/node_modules/vasync/tests/whilst.js new file mode 100644 index 0000000..0fa7bef --- /dev/null +++ b/node_modules/vasync/tests/whilst.js @@ -0,0 +1,108 @@ +/* + * Tests the "whilst" function + */ + +var mod_util = require('util'); + +var mod_tap = require('tap'); +var mod_vasync = require('..'); + +mod_tap.test('basic whilst', function (test) { + var n = 0; + + mod_vasync.whilst( + function condition() { + return (n < 5); + }, + function body(cb) { + n++; + cb(null, n); + }, + function done(err, arg) { + test.ok(!err, 'error unset'); + test.equal(n, 5, 'n == 5'); + test.equal(n, arg, 'n == arg'); + test.end(); + }); +}); + +mod_tap.test('whilst return object', function (test) { + var n = 0; + + var w = mod_vasync.whilst( + function condition() { + return (n < 5); + }, + function body(cb) { + n++; + + test.equal(n, w.iterations, 'n == w.iterations: ' + n); + + cb(null, n, 'foo'); + }, + function done(err, arg1, arg2, arg3) { + test.ok(!err, 'error unset'); + test.equal(w.iterations, 5, 'whilst had 5 iterations'); + test.equal(w.finished, true, 'whilst has finished'); + test.equal(arg1, n, 'whilst arg1 == n'); + test.equal(arg2, 'foo', 'whilst arg2 == "foo"'); + test.equal(arg3, undefined, 'whilst arg3 == undefined'); + test.end(); + }); + + test.equal(typeof (w), 'object', 'whilst returns an object'); + test.equal(w.finished, false, 'whilst is not finished'); + test.equal(w.iterations, 0, 'whilst has not started yet'); +}); + +mod_tap.test('whilst false condition', function (test) { + mod_vasync.whilst( + function condition() { + return (false); + }, + function body(cb) { + cb(); + }, + function done(err, arg) { + test.ok(!err, 'error is unset'); + test.ok(!arg, 'arg is unset'); + test.end(); + }); +}); + +mod_tap.test('whilst error', function (test) { + var n = 0; + + var w = mod_vasync.whilst( + function condition() { + return (true); + }, + function body(cb) { + n++; + + if (n > 5) { + cb(new Error('n > 5'), 'bar'); + } else { + cb(null, 'foo'); + } + }, + function done(err, arg) { + test.ok(err, 'error is set'); + test.equal(err.message, 'n > 5'); + test.equal(arg, 'bar'); + + test.equal(w.finished, true, 'whilst is finished'); + + /* + * Iterations is bumped after the test condition is run and + * before the iteration function is run. Because the condition + * in this example is inside the iteration function (the test + * condition always returns true), the iteration count will be + * 1 higher than expected, since it will fail when (n > 5), or + * when iterations is 6. + */ + test.equal(w.iterations, 6, 'whilst had 6 iterations'); + + test.end(); + }); +}); diff --git a/node_modules/verror/CHANGES.md b/node_modules/verror/CHANGES.md new file mode 100644 index 0000000..5d2e0c7 --- /dev/null +++ b/node_modules/verror/CHANGES.md @@ -0,0 +1,28 @@ +# Changelog + +## Not yet released + +* #65 tst.multierror.js failure on Node v8 and later + +## v1.10.0 + +* #49 want convenience functions for MultiErrors + +## v1.9.0 + +* #47 could use VError.hasCauseWithName() + +## v1.8.1 + +* #39 captureStackTrace lost when inheriting from WError + +## v1.8.0 + +* #23 Preserve original stack trace(s) + +## v1.7.0 + +* #10 better support for extra properties on Errors +* #11 make it easy to find causes of a particular kind +* #29 No documentation on how to Install this package +* #36 elide development-only files from npm package diff --git a/node_modules/verror/CONTRIBUTING.md b/node_modules/verror/CONTRIBUTING.md new file mode 100644 index 0000000..ee5bb93 --- /dev/null +++ b/node_modules/verror/CONTRIBUTING.md @@ -0,0 +1,16 @@ +# Contributing + +This repository uses GitHub pull requests for code review. + +See the [Joyent Engineering +Guidelines](https://github.com/joyent/eng/blob/master/docs/index.md) for general +best practices expected in this repository. + +Contributions should be "make prepush" clean. The "prepush" target runs the +"check" target, which requires these separate tools: + +* https://github.com/joyent/jsstyle +* https://github.com/joyent/javascriptlint + +If you're changing something non-trivial or user-facing, you may want to submit +an issue first. diff --git a/node_modules/verror/LICENSE b/node_modules/verror/LICENSE new file mode 100644 index 0000000..82a5cb8 --- /dev/null +++ b/node_modules/verror/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016, Joyent, Inc. All rights reserved. + +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 diff --git a/node_modules/verror/README.md b/node_modules/verror/README.md new file mode 100644 index 0000000..f1896df --- /dev/null +++ b/node_modules/verror/README.md @@ -0,0 +1,528 @@ +# verror: rich JavaScript errors + +This module provides several classes in support of Joyent's [Best Practices for +Error Handling in Node.js](http://www.joyent.com/developers/node/design/errors). +If you find any of the behavior here confusing or surprising, check out that +document first. + +The error classes here support: + +* printf-style arguments for the message +* chains of causes +* properties to provide extra information about the error +* creating your own subclasses that support all of these + +The classes here are: + +* **VError**, for chaining errors while preserving each one's error message. + This is useful in servers and command-line utilities when you want to + propagate an error up a call stack, but allow various levels to add their own + context. See examples below. +* **WError**, for wrapping errors while hiding the lower-level messages from the + top-level error. This is useful for API endpoints where you don't want to + expose internal error messages, but you still want to preserve the error chain + for logging and debugging. +* **SError**, which is just like VError but interprets printf-style arguments + more strictly. +* **MultiError**, which is just an Error that encapsulates one or more other + errors. (This is used for parallel operations that return several errors.) + + +# Quick start + +First, install the package: + + npm install verror + +If nothing else, you can use VError as a drop-in replacement for the built-in +JavaScript Error class, with the addition of printf-style messages: + +```javascript +var err = new VError('missing file: "%s"', '/etc/passwd'); +console.log(err.message); +``` + +This prints: + + missing file: "/etc/passwd" + +You can also pass a `cause` argument, which is any other Error object: + +```javascript +var fs = require('fs'); +var filename = '/nonexistent'; +fs.stat(filename, function (err1) { + var err2 = new VError(err1, 'stat "%s"', filename); + console.error(err2.message); +}); +``` + +This prints out: + + stat "/nonexistent": ENOENT, stat '/nonexistent' + +which resembles how Unix programs typically report errors: + + $ sort /nonexistent + sort: open failed: /nonexistent: No such file or directory + +To match the Unixy feel, when you print out the error, just prepend the +program's name to the VError's `message`. Or just call +[node-cmdutil.fail(your_verror)](https://github.com/joyent/node-cmdutil), which +does this for you. + +You can get the next-level Error using `err.cause()`: + +```javascript +console.error(err2.cause().message); +``` + +prints: + + ENOENT, stat '/nonexistent' + +Of course, you can chain these as many times as you want, and it works with any +kind of Error: + +```javascript +var err1 = new Error('No such file or directory'); +var err2 = new VError(err1, 'failed to stat "%s"', '/junk'); +var err3 = new VError(err2, 'request failed'); +console.error(err3.message); +``` + +This prints: + + request failed: failed to stat "/junk": No such file or directory + +The idea is that each layer in the stack annotates the error with a description +of what it was doing. The end result is a message that explains what happened +at each level. + +You can also decorate Error objects with additional information so that callers +can not only handle each kind of error differently, but also construct their own +error messages (e.g., to localize them, format them, group them by type, and so +on). See the example below. + + +# Deeper dive + +The two main goals for VError are: + +* **Make it easy to construct clear, complete error messages intended for + people.** Clear error messages greatly improve both user experience and + debuggability, so we wanted to make it easy to build them. That's why the + constructor takes printf-style arguments. +* **Make it easy to construct objects with programmatically-accessible + metadata** (which we call _informational properties_). Instead of just saying + "connection refused while connecting to 192.168.1.2:80", you can add + properties like `"ip": "192.168.1.2"` and `"tcpPort": 80`. This can be used + for feeding into monitoring systems, analyzing large numbers of Errors (as + from a log file), or localizing error messages. + +To really make this useful, it also needs to be easy to compose Errors: +higher-level code should be able to augment the Errors reported by lower-level +code to provide a more complete description of what happened. Instead of saying +"connection refused", you can say "operation X failed: connection refused". +That's why VError supports `causes`. + +In order for all this to work, programmers need to know that it's generally safe +to wrap lower-level Errors with higher-level ones. If you have existing code +that handles Errors produced by a library, you should be able to wrap those +Errors with a VError to add information without breaking the error handling +code. There are two obvious ways that this could break such consumers: + +* The error's name might change. People typically use `name` to determine what + kind of Error they've got. To ensure compatibility, you can create VErrors + with custom names, but this approach isn't great because it prevents you from + representing complex failures. For this reason, VError provides + `findCauseByName`, which essentially asks: does this Error _or any of its + causes_ have this specific type? If error handling code uses + `findCauseByName`, then subsystems can construct very specific causal chains + for debuggability and still let people handle simple cases easily. There's an + example below. +* The error's properties might change. People often hang additional properties + off of Error objects. If we wrap an existing Error in a new Error, those + properties would be lost unless we copied them. But there are a variety of + both standard and non-standard Error properties that should _not_ be copied in + this way: most obviously `name`, `message`, and `stack`, but also `fileName`, + `lineNumber`, and a few others. Plus, it's useful for some Error subclasses + to have their own private properties -- and there'd be no way to know whether + these should be copied. For these reasons, VError first-classes these + information properties. You have to provide them in the constructor, you can + only fetch them with the `info()` function, and VError takes care of making + sure properties from causes wind up in the `info()` output. + +Let's put this all together with an example from the node-fast RPC library. +node-fast implements a simple RPC protocol for Node programs. There's a server +and client interface, and clients make RPC requests to servers. Let's say the +server fails with an UnauthorizedError with message "user 'bob' is not +authorized". The client wraps all server errors with a FastServerError. The +client also wraps all request errors with a FastRequestError that includes the +name of the RPC call being made. The result of this failed RPC might look like +this: + + name: FastRequestError + message: "request failed: server error: user 'bob' is not authorized" + rpcMsgid: + rpcMethod: GetObject + cause: + name: FastServerError + message: "server error: user 'bob' is not authorized" + cause: + name: UnauthorizedError + message: "user 'bob' is not authorized" + rpcUser: "bob" + +When the caller uses `VError.info()`, the information properties are collapsed +so that it looks like this: + + message: "request failed: server error: user 'bob' is not authorized" + rpcMsgid: + rpcMethod: GetObject + rpcUser: "bob" + +Taking this apart: + +* The error's message is a complete description of the problem. The caller can + report this directly to its caller, which can potentially make its way back to + an end user (if appropriate). It can also be logged. +* The caller can tell that the request failed on the server, rather than as a + result of a client problem (e.g., failure to serialize the request), a + transport problem (e.g., failure to connect to the server), or something else + (e.g., a timeout). They do this using `findCauseByName('FastServerError')` + rather than checking the `name` field directly. +* If the caller logs this error, the logs can be analyzed to aggregate + errors by cause, by RPC method name, by user, or whatever. Or the + error can be correlated with other events for the same rpcMsgid. +* It wasn't very hard for any part of the code to contribute to this Error. + Each part of the stack has just a few lines to provide exactly what it knows, + with very little boilerplate. + +It's not expected that you'd use these complex forms all the time. Despite +supporting the complex case above, you can still just do: + + new VError("my service isn't working"); + +for the simple cases. + + +# Reference: VError, WError, SError + +VError, WError, and SError are convenient drop-in replacements for `Error` that +support printf-style arguments, first-class causes, informational properties, +and other useful features. + + +## Constructors + +The VError constructor has several forms: + +```javascript +/* + * This is the most general form. You can specify any supported options + * (including "cause" and "info") this way. + */ +new VError(options, sprintf_args...) + +/* + * This is a useful shorthand when the only option you need is "cause". + */ +new VError(cause, sprintf_args...) + +/* + * This is a useful shorthand when you don't need any options at all. + */ +new VError(sprintf_args...) +``` + +All of these forms construct a new VError that behaves just like the built-in +JavaScript `Error` class, with some additional methods described below. + +In the first form, `options` is a plain object with any of the following +optional properties: + +Option name | Type | Meaning +---------------- | ---------------- | ------- +`name` | string | Describes what kind of error this is. This is intended for programmatic use to distinguish between different kinds of errors. Note that in modern versions of Node.js, this name is ignored in the `stack` property value, but callers can still use the `name` property to get at it. +`cause` | any Error object | Indicates that the new error was caused by `cause`. See `cause()` below. If unspecified, the cause will be `null`. +`strict` | boolean | If true, then `null` and `undefined` values in `sprintf_args` are passed through to `sprintf()`. Otherwise, these are replaced with the strings `'null'`, and '`undefined`', respectively. +`constructorOpt` | function | If specified, then the stack trace for this error ends at function `constructorOpt`. Functions called by `constructorOpt` will not show up in the stack. This is useful when this class is subclassed. +`info` | object | Specifies arbitrary informational properties that are available through the `VError.info(err)` static class method. See that method for details. + +The second form is equivalent to using the first form with the specified `cause` +as the error's cause. This form is distinguished from the first form because +the first argument is an Error. + +The third form is equivalent to using the first form with all default option +values. This form is distinguished from the other forms because the first +argument is not an object or an Error. + +The `WError` constructor is used exactly the same way as the `VError` +constructor. The `SError` constructor is also used the same way as the +`VError` constructor except that in all cases, the `strict` property is +overriden to `true. + + +## Public properties + +`VError`, `WError`, and `SError` all provide the same public properties as +JavaScript's built-in Error objects. + +Property name | Type | Meaning +------------- | ------ | ------- +`name` | string | Programmatically-usable name of the error. +`message` | string | Human-readable summary of the failure. Programmatically-accessible details are provided through `VError.info(err)` class method. +`stack` | string | Human-readable stack trace where the Error was constructed. + +For all of these classes, the printf-style arguments passed to the constructor +are processed with `sprintf()` to form a message. For `WError`, this becomes +the complete `message` property. For `SError` and `VError`, this message is +prepended to the message of the cause, if any (with a suitable separator), and +the result becomes the `message` property. + +The `stack` property is managed entirely by the underlying JavaScript +implementation. It's generally implemented using a getter function because +constructing the human-readable stack trace is somewhat expensive. + +## Class methods + +The following methods are defined on the `VError` class and as exported +functions on the `verror` module. They're defined this way rather than using +methods on VError instances so that they can be used on Errors not created with +`VError`. + +### `VError.cause(err)` + +The `cause()` function returns the next Error in the cause chain for `err`, or +`null` if there is no next error. See the `cause` argument to the constructor. +Errors can have arbitrarily long cause chains. You can walk the `cause` chain +by invoking `VError.cause(err)` on each subsequent return value. If `err` is +not a `VError`, the cause is `null`. + +### `VError.info(err)` + +Returns an object with all of the extra error information that's been associated +with this Error and all of its causes. These are the properties passed in using +the `info` option to the constructor. Properties not specified in the +constructor for this Error are implicitly inherited from this error's cause. + +These properties are intended to provide programmatically-accessible metadata +about the error. For an error that indicates a failure to resolve a DNS name, +informational properties might include the DNS name to be resolved, or even the +list of resolvers used to resolve it. The values of these properties should +generally be plain objects (i.e., consisting only of null, undefined, numbers, +booleans, strings, and objects and arrays containing only other plain objects). + +### `VError.fullStack(err)` + +Returns a string containing the full stack trace, with all nested errors recursively +reported as `'caused by:' + err.stack`. + +### `VError.findCauseByName(err, name)` + +The `findCauseByName()` function traverses the cause chain for `err`, looking +for an error whose `name` property matches the passed in `name` value. If no +match is found, `null` is returned. + +If all you want is to know _whether_ there's a cause (and you don't care what it +is), you can use `VError.hasCauseWithName(err, name)`. + +If a vanilla error or a non-VError error is passed in, then there is no cause +chain to traverse. In this scenario, the function will check the `name` +property of only `err`. + +### `VError.hasCauseWithName(err, name)` + +Returns true if and only if `VError.findCauseByName(err, name)` would return +a non-null value. This essentially determines whether `err` has any cause in +its cause chain that has name `name`. + +### `VError.errorFromList(errors)` + +Given an array of Error objects (possibly empty), return a single error +representing the whole collection of errors. If the list has: + +* 0 elements, returns `null` +* 1 element, returns the sole error +* more than 1 element, returns a MultiError referencing the whole list + +This is useful for cases where an operation may produce any number of errors, +and you ultimately want to implement the usual `callback(err)` pattern. You can +accumulate the errors in an array and then invoke +`callback(VError.errorFromList(errors))` when the operation is complete. + + +### `VError.errorForEach(err, func)` + +Convenience function for iterating an error that may itself be a MultiError. + +In all cases, `err` must be an Error. If `err` is a MultiError, then `func` is +invoked as `func(errorN)` for each of the underlying errors of the MultiError. +If `err` is any other kind of error, `func` is invoked once as `func(err)`. In +all cases, `func` is invoked synchronously. + +This is useful for cases where an operation may produce any number of warnings +that may be encapsulated with a MultiError -- but may not be. + +This function does not iterate an error's cause chain. + + +## Examples + +The "Demo" section above covers several basic cases. Here's a more advanced +case: + +```javascript +var err1 = new VError('something bad happened'); +/* ... */ +var err2 = new VError({ + 'name': 'ConnectionError', + 'cause': err1, + 'info': { + 'errno': 'ECONNREFUSED', + 'remote_ip': '127.0.0.1', + 'port': 215 + } +}, 'failed to connect to "%s:%d"', '127.0.0.1', 215); + +console.log(err2.message); +console.log(err2.name); +console.log(VError.info(err2)); +console.log(err2.stack); +``` + +This outputs: + + failed to connect to "127.0.0.1:215": something bad happened + ConnectionError + { errno: 'ECONNREFUSED', remote_ip: '127.0.0.1', port: 215 } + ConnectionError: failed to connect to "127.0.0.1:215": something bad happened + at Object. (/home/dap/node-verror/examples/info.js:5:12) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:935:3 + +Information properties are inherited up the cause chain, with values at the top +of the chain overriding same-named values lower in the chain. To continue that +example: + +```javascript +var err3 = new VError({ + 'name': 'RequestError', + 'cause': err2, + 'info': { + 'errno': 'EBADREQUEST' + } +}, 'request failed'); + +console.log(err3.message); +console.log(err3.name); +console.log(VError.info(err3)); +console.log(err3.stack); +``` + +This outputs: + + request failed: failed to connect to "127.0.0.1:215": something bad happened + RequestError + { errno: 'EBADREQUEST', remote_ip: '127.0.0.1', port: 215 } + RequestError: request failed: failed to connect to "127.0.0.1:215": something bad happened + at Object. (/home/dap/node-verror/examples/info.js:20:12) + at Module._compile (module.js:456:26) + at Object.Module._extensions..js (module.js:474:10) + at Module.load (module.js:356:32) + at Function.Module._load (module.js:312:12) + at Function.Module.runMain (module.js:497:10) + at startup (node.js:119:16) + at node.js:935:3 + +You can also print the complete stack trace of combined `Error`s by using +`VError.fullStack(err).` + +```javascript +var err1 = new VError('something bad happened'); +/* ... */ +var err2 = new VError(err1, 'something really bad happened here'); + +console.log(VError.fullStack(err2)); +``` + +This outputs: + + VError: something really bad happened here: something bad happened + at Object. (/home/dap/node-verror/examples/fullStack.js:5:12) + at Module._compile (module.js:409:26) + at Object.Module._extensions..js (module.js:416:10) + at Module.load (module.js:343:32) + at Function.Module._load (module.js:300:12) + at Function.Module.runMain (module.js:441:10) + at startup (node.js:139:18) + at node.js:968:3 + caused by: VError: something bad happened + at Object. (/home/dap/node-verror/examples/fullStack.js:3:12) + at Module._compile (module.js:409:26) + at Object.Module._extensions..js (module.js:416:10) + at Module.load (module.js:343:32) + at Function.Module._load (module.js:300:12) + at Function.Module.runMain (module.js:441:10) + at startup (node.js:139:18) + at node.js:968:3 + +`VError.fullStack` is also safe to use on regular `Error`s, so feel free to use +it whenever you need to extract the stack trace from an `Error`, regardless if +it's a `VError` or not. + +# Reference: MultiError + +MultiError is an Error class that represents a group of Errors. This is used +when you logically need to provide a single Error, but you want to preserve +information about multiple underlying Errors. A common case is when you execute +several operations in parallel and some of them fail. + +MultiErrors are constructed as: + +```javascript +new MultiError(error_list) +``` + +`error_list` is an array of at least one `Error` object. + +The cause of the MultiError is the first error provided. None of the other +`VError` options are supported. The `message` for a MultiError consists the +`message` from the first error, prepended with a message indicating that there +were other errors. + +For example: + +```javascript +err = new MultiError([ + new Error('failed to resolve DNS name "abc.example.com"'), + new Error('failed to resolve DNS name "def.example.com"'), +]); + +console.error(err.message); +``` + +outputs: + + first of 2 errors: failed to resolve DNS name "abc.example.com" + +See the convenience function `VError.errorFromList`, which is sometimes simpler +to use than this constructor. + +## Public methods + + +### `errors()` + +Returns an array of the errors used to construct this MultiError. + + +# Contributing + +See separate [contribution guidelines](CONTRIBUTING.md). diff --git a/node_modules/verror/lib/verror.js b/node_modules/verror/lib/verror.js new file mode 100644 index 0000000..8663dde --- /dev/null +++ b/node_modules/verror/lib/verror.js @@ -0,0 +1,451 @@ +/* + * verror.js: richer JavaScript errors + */ + +var mod_assertplus = require('assert-plus'); +var mod_util = require('util'); + +var mod_extsprintf = require('extsprintf'); +var mod_isError = require('core-util-is').isError; +var sprintf = mod_extsprintf.sprintf; + +/* + * Public interface + */ + +/* So you can 'var VError = require('verror')' */ +module.exports = VError; +/* For compatibility */ +VError.VError = VError; +/* Other exported classes */ +VError.SError = SError; +VError.WError = WError; +VError.MultiError = MultiError; + +/* + * Common function used to parse constructor arguments for VError, WError, and + * SError. Named arguments to this function: + * + * strict force strict interpretation of sprintf arguments, even + * if the options in "argv" don't say so + * + * argv error's constructor arguments, which are to be + * interpreted as described in README.md. For quick + * reference, "argv" has one of the following forms: + * + * [ sprintf_args... ] (argv[0] is a string) + * [ cause, sprintf_args... ] (argv[0] is an Error) + * [ options, sprintf_args... ] (argv[0] is an object) + * + * This function normalizes these forms, producing an object with the following + * properties: + * + * options equivalent to "options" in third form. This will never + * be a direct reference to what the caller passed in + * (i.e., it may be a shallow copy), so it can be freely + * modified. + * + * shortmessage result of sprintf(sprintf_args), taking options.strict + * into account as described in README.md. + */ +function parseConstructorArguments(args) +{ + var argv, options, sprintf_args, shortmessage, k; + + mod_assertplus.object(args, 'args'); + mod_assertplus.bool(args.strict, 'args.strict'); + mod_assertplus.array(args.argv, 'args.argv'); + argv = args.argv; + + /* + * First, figure out which form of invocation we've been given. + */ + if (argv.length === 0) { + options = {}; + sprintf_args = []; + } else if (mod_isError(argv[0])) { + options = { 'cause': argv[0] }; + sprintf_args = argv.slice(1); + } else if (typeof (argv[0]) === 'object') { + options = {}; + for (k in argv[0]) { + options[k] = argv[0][k]; + } + sprintf_args = argv.slice(1); + } else { + mod_assertplus.string(argv[0], + 'first argument to VError, SError, or WError ' + + 'constructor must be a string, object, or Error'); + options = {}; + sprintf_args = argv; + } + + /* + * Now construct the error's message. + * + * extsprintf (which we invoke here with our caller's arguments in order + * to construct this Error's message) is strict in its interpretation of + * values to be processed by the "%s" specifier. The value passed to + * extsprintf must actually be a string or something convertible to a + * String using .toString(). Passing other values (notably "null" and + * "undefined") is considered a programmer error. The assumption is + * that if you actually want to print the string "null" or "undefined", + * then that's easy to do that when you're calling extsprintf; on the + * other hand, if you did NOT want that (i.e., there's actually a bug + * where the program assumes some variable is non-null and tries to + * print it, which might happen when constructing a packet or file in + * some specific format), then it's better to stop immediately than + * produce bogus output. + * + * However, sometimes the bug is only in the code calling VError, and a + * programmer might prefer to have the error message contain "null" or + * "undefined" rather than have the bug in the error path crash the + * program (making the first bug harder to identify). For that reason, + * by default VError converts "null" or "undefined" arguments to their + * string representations and passes those to extsprintf. Programmers + * desiring the strict behavior can use the SError class or pass the + * "strict" option to the VError constructor. + */ + mod_assertplus.object(options); + if (!options.strict && !args.strict) { + sprintf_args = sprintf_args.map(function (a) { + return (a === null ? 'null' : + a === undefined ? 'undefined' : a); + }); + } + + if (sprintf_args.length === 0) { + shortmessage = ''; + } else { + shortmessage = sprintf.apply(null, sprintf_args); + } + + return ({ + 'options': options, + 'shortmessage': shortmessage + }); +} + +/* + * See README.md for reference documentation. + */ +function VError() +{ + var args, obj, parsed, cause, ctor, message, k; + + args = Array.prototype.slice.call(arguments, 0); + + /* + * This is a regrettable pattern, but JavaScript's built-in Error class + * is defined to work this way, so we allow the constructor to be called + * without "new". + */ + if (!(this instanceof VError)) { + obj = Object.create(VError.prototype); + VError.apply(obj, arguments); + return (obj); + } + + /* + * For convenience and backwards compatibility, we support several + * different calling forms. Normalize them here. + */ + parsed = parseConstructorArguments({ + 'argv': args, + 'strict': false + }); + + /* + * If we've been given a name, apply it now. + */ + if (parsed.options.name) { + mod_assertplus.string(parsed.options.name, + 'error\'s "name" must be a string'); + this.name = parsed.options.name; + } + + /* + * For debugging, we keep track of the original short message (attached + * this Error particularly) separately from the complete message (which + * includes the messages of our cause chain). + */ + this.jse_shortmsg = parsed.shortmessage; + message = parsed.shortmessage; + + /* + * If we've been given a cause, record a reference to it and update our + * message appropriately. + */ + cause = parsed.options.cause; + if (cause) { + mod_assertplus.ok(mod_isError(cause), 'cause is not an Error'); + this.jse_cause = cause; + + if (!parsed.options.skipCauseMessage) { + message += ': ' + cause.message; + } + } + + /* + * If we've been given an object with properties, shallow-copy that + * here. We don't want to use a deep copy in case there are non-plain + * objects here, but we don't want to use the original object in case + * the caller modifies it later. + */ + this.jse_info = {}; + if (parsed.options.info) { + for (k in parsed.options.info) { + this.jse_info[k] = parsed.options.info[k]; + } + } + + this.message = message; + Error.call(this, message); + + if (Error.captureStackTrace) { + ctor = parsed.options.constructorOpt || this.constructor; + Error.captureStackTrace(this, ctor); + } + + return (this); +} + +mod_util.inherits(VError, Error); +VError.prototype.name = 'VError'; + +VError.prototype.toString = function ve_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + + return (str); +}; + +/* + * This method is provided for compatibility. New callers should use + * VError.cause() instead. That method also uses the saner `null` return value + * when there is no cause. + */ +VError.prototype.cause = function ve_cause() +{ + var cause = VError.cause(this); + return (cause === null ? undefined : cause); +}; + +/* + * Static methods + * + * These class-level methods are provided so that callers can use them on + * instances of Errors that are not VErrors. New interfaces should be provided + * only using static methods to eliminate the class of programming mistake where + * people fail to check whether the Error object has the corresponding methods. + */ + +VError.cause = function (err) +{ + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + return (mod_isError(err.jse_cause) ? err.jse_cause : null); +}; + +VError.info = function (err) +{ + var rv, cause, k; + + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + cause = VError.cause(err); + if (cause !== null) { + rv = VError.info(cause); + } else { + rv = {}; + } + + if (typeof (err.jse_info) == 'object' && err.jse_info !== null) { + for (k in err.jse_info) { + rv[k] = err.jse_info[k]; + } + } + + return (rv); +}; + +VError.findCauseByName = function (err, name) +{ + var cause; + + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + mod_assertplus.string(name, 'name'); + mod_assertplus.ok(name.length > 0, 'name cannot be empty'); + + for (cause = err; cause !== null; cause = VError.cause(cause)) { + mod_assertplus.ok(mod_isError(cause)); + if (cause.name == name) { + return (cause); + } + } + + return (null); +}; + +VError.hasCauseWithName = function (err, name) +{ + return (VError.findCauseByName(err, name) !== null); +}; + +VError.fullStack = function (err) +{ + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + + var cause = VError.cause(err); + + if (cause) { + return (err.stack + '\ncaused by: ' + VError.fullStack(cause)); + } + + return (err.stack); +}; + +VError.errorFromList = function (errors) +{ + mod_assertplus.arrayOfObject(errors, 'errors'); + + if (errors.length === 0) { + return (null); + } + + errors.forEach(function (e) { + mod_assertplus.ok(mod_isError(e)); + }); + + if (errors.length == 1) { + return (errors[0]); + } + + return (new MultiError(errors)); +}; + +VError.errorForEach = function (err, func) +{ + mod_assertplus.ok(mod_isError(err), 'err must be an Error'); + mod_assertplus.func(func, 'func'); + + if (err instanceof MultiError) { + err.errors().forEach(function iterError(e) { func(e); }); + } else { + func(err); + } +}; + + +/* + * SError is like VError, but stricter about types. You cannot pass "null" or + * "undefined" as string arguments to the formatter. + */ +function SError() +{ + var args, obj, parsed, options; + + args = Array.prototype.slice.call(arguments, 0); + if (!(this instanceof SError)) { + obj = Object.create(SError.prototype); + SError.apply(obj, arguments); + return (obj); + } + + parsed = parseConstructorArguments({ + 'argv': args, + 'strict': true + }); + + options = parsed.options; + VError.call(this, options, '%s', parsed.shortmessage); + + return (this); +} + +/* + * We don't bother setting SError.prototype.name because once constructed, + * SErrors are just like VErrors. + */ +mod_util.inherits(SError, VError); + + +/* + * Represents a collection of errors for the purpose of consumers that generally + * only deal with one error. Callers can extract the individual errors + * contained in this object, but may also just treat it as a normal single + * error, in which case a summary message will be printed. + */ +function MultiError(errors) +{ + mod_assertplus.array(errors, 'list of errors'); + mod_assertplus.ok(errors.length > 0, 'must be at least one error'); + this.ase_errors = errors; + + VError.call(this, { + 'cause': errors[0] + }, 'first of %d error%s', errors.length, errors.length == 1 ? '' : 's'); +} + +mod_util.inherits(MultiError, VError); +MultiError.prototype.name = 'MultiError'; + +MultiError.prototype.errors = function me_errors() +{ + return (this.ase_errors.slice(0)); +}; + + +/* + * See README.md for reference details. + */ +function WError() +{ + var args, obj, parsed, options; + + args = Array.prototype.slice.call(arguments, 0); + if (!(this instanceof WError)) { + obj = Object.create(WError.prototype); + WError.apply(obj, args); + return (obj); + } + + parsed = parseConstructorArguments({ + 'argv': args, + 'strict': false + }); + + options = parsed.options; + options['skipCauseMessage'] = true; + VError.call(this, options, '%s', parsed.shortmessage); + + return (this); +} + +mod_util.inherits(WError, VError); +WError.prototype.name = 'WError'; + +WError.prototype.toString = function we_toString() +{ + var str = (this.hasOwnProperty('name') && this.name || + this.constructor.name || this.constructor.prototype.name); + if (this.message) + str += ': ' + this.message; + if (this.jse_cause && this.jse_cause.message) + str += '; caused by ' + this.jse_cause.toString(); + + return (str); +}; + +/* + * For purely historical reasons, WError's cause() function allows you to set + * the cause. + */ +WError.prototype.cause = function we_cause(c) +{ + if (mod_isError(c)) + this.jse_cause = c; + + return (this.jse_cause); +}; diff --git a/node_modules/verror/package.json b/node_modules/verror/package.json new file mode 100644 index 0000000..2e67675 --- /dev/null +++ b/node_modules/verror/package.json @@ -0,0 +1,30 @@ +{ + "name": "verror", + "version": "1.10.1", + "description": "richer JavaScript errors", + "main": "./lib/verror.js", + "repository": { + "type": "git", + "url": "https://github.com/joyent/node-verror.git" + }, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + }, + "scripts": { + "test": "make test" + }, + "license": "MIT", + "keywords": [ + "error", + "errors", + "err", + "exception", + "exceptions", + "custom" + ] +} diff --git a/node_modules/wrappy/LICENSE b/node_modules/wrappy/LICENSE new file mode 100644 index 0000000..19129e3 --- /dev/null +++ b/node_modules/wrappy/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/node_modules/wrappy/README.md b/node_modules/wrappy/README.md new file mode 100644 index 0000000..98eab25 --- /dev/null +++ b/node_modules/wrappy/README.md @@ -0,0 +1,36 @@ +# wrappy + +Callback wrapping utility + +## USAGE + +```javascript +var wrappy = require("wrappy") + +// var wrapper = wrappy(wrapperFunction) + +// make sure a cb is called only once +// See also: http://npm.im/once for this specific use case +var once = wrappy(function (cb) { + var called = false + return function () { + if (called) return + called = true + return cb.apply(this, arguments) + } +}) + +function printBoo () { + console.log('boo') +} +// has some rando property +printBoo.iAmBooPrinter = true + +var onlyPrintOnce = once(printBoo) + +onlyPrintOnce() // prints 'boo' +onlyPrintOnce() // does nothing + +// random property is retained! +assert.equal(onlyPrintOnce.iAmBooPrinter, true) +``` diff --git a/node_modules/wrappy/package.json b/node_modules/wrappy/package.json new file mode 100644 index 0000000..1307520 --- /dev/null +++ b/node_modules/wrappy/package.json @@ -0,0 +1,29 @@ +{ + "name": "wrappy", + "version": "1.0.2", + "description": "Callback wrapping utility", + "main": "wrappy.js", + "files": [ + "wrappy.js" + ], + "directories": { + "test": "test" + }, + "dependencies": {}, + "devDependencies": { + "tap": "^2.3.1" + }, + "scripts": { + "test": "tap --coverage test/*.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/npm/wrappy" + }, + "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "license": "ISC", + "bugs": { + "url": "https://github.com/npm/wrappy/issues" + }, + "homepage": "https://github.com/npm/wrappy" +} diff --git a/node_modules/wrappy/wrappy.js b/node_modules/wrappy/wrappy.js new file mode 100644 index 0000000..bb7e7d6 --- /dev/null +++ b/node_modules/wrappy/wrappy.js @@ -0,0 +1,33 @@ +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a754136 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,525 @@ +{ + "name": "ldap-oauth-bridge", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ldap-oauth-bridge", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "axios": "^1.12.2", + "ldapjs": "^3.0.7" + } + }, + "node_modules/@ldapjs/asn1": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-2.0.0.tgz", + "integrity": "sha512-G9+DkEOirNgdPmD0I8nu57ygQJKOOgFEMKknEuQvIHbGLwP3ny1mY+OTUYLCbCaGJP4sox5eYgBJRuSUpnAddA==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT" + }, + "node_modules/@ldapjs/attribute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/attribute/-/attribute-1.0.0.tgz", + "integrity": "sha512-ptMl2d/5xJ0q+RgmnqOi3Zgwk/TMJYG7dYMC0Keko+yZU6n+oFM59MjQOUht5pxJeS4FWrImhu/LebX24vJNRQ==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/change": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@ldapjs/change/-/change-1.0.0.tgz", + "integrity": "sha512-EOQNFH1RIku3M1s0OAJOzGfAohuFYXFY4s73wOhRm4KFGhmQQ7MChOh2YtYu9Kwgvuq1B0xKciXVzHCGkB5V+Q==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/attribute": "1.0.0" + } + }, + "node_modules/@ldapjs/controls": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/controls/-/controls-2.1.0.tgz", + "integrity": "sha512-2pFdD1yRC9V9hXfAWvCCO2RRWK9OdIEcJIos/9cCVP9O4k72BY1bLDQQ4KpUoJnl4y/JoD4iFgM+YWT3IfITWw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "^1.2.0", + "@ldapjs/protocol": "^1.2.1" + } + }, + "node_modules/@ldapjs/controls/node_modules/@ldapjs/asn1": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ldapjs/asn1/-/asn1-1.2.0.tgz", + "integrity": "sha512-KX/qQJ2xxzvO2/WOvr1UdQ+8P5dVvuOLk/C9b1bIkXxZss8BaR28njXdPgFCpj5aHaf1t8PmuVnea+N9YG9YMw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT" + }, + "node_modules/@ldapjs/dn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ldapjs/dn/-/dn-1.1.0.tgz", + "integrity": "sha512-R72zH5ZeBj/Fujf/yBu78YzpJjJXG46YHFo5E4W1EqfNpo1UsVPqdLrRMXeKIsJT3x9dJVIfR6OpzgINlKpi0A==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/filter": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@ldapjs/filter/-/filter-2.1.1.tgz", + "integrity": "sha512-TwPK5eEgNdUO1ABPBUQabcZ+h9heDORE4V9WNZqCtYLKc06+6+UAJ3IAbr0L0bYTnkkWC/JEQD2F+zAFsuikNw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "2.0.0", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.1.0" + } + }, + "node_modules/@ldapjs/messages": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ldapjs/messages/-/messages-1.3.0.tgz", + "integrity": "sha512-K7xZpXJ21bj92jS35wtRbdcNrwmxAtPwy4myeh9duy/eR3xQKvikVycbdWVzkYEAVE5Ce520VXNOwCHjomjCZw==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/protocol": "^1.2.1", + "process-warning": "^2.2.0" + } + }, + "node_modules/@ldapjs/protocol": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ldapjs/protocol/-/protocol-1.2.1.tgz", + "integrity": "sha512-O89xFDLW2gBoZWNXuXpBSM32/KealKCTb3JGtJdtUQc7RjAk8XzrRgyz02cPAwGKwKPxy0ivuC7UP9bmN87egQ==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT" + }, + "node_modules/abstract-logging": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", + "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", + "license": "MIT" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/backoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", + "integrity": "sha512-wC5ihrnUXmR2douXmXLCe5O3zg3GKIyvRi/hi58a/XyRxVI+3/yM0PYueQOZXPXQ9pxBislYkw+sF9b7C/RuMA==", + "license": "MIT", + "dependencies": { + "precond": "0.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ldapjs": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/ldapjs/-/ldapjs-3.0.7.tgz", + "integrity": "sha512-1ky+WrN+4CFMuoekUOv7Y1037XWdjKpu0xAPwSP+9KdvmV9PG+qOKlssDV6a+U32apwxdD3is/BZcWOYzN30cg==", + "deprecated": "This package has been decomissioned. See https://github.com/ldapjs/node-ldapjs/blob/8ffd0bc9c149088a10ec4c1ec6a18450f76ad05d/README.md", + "license": "MIT", + "dependencies": { + "@ldapjs/asn1": "^2.0.0", + "@ldapjs/attribute": "^1.0.0", + "@ldapjs/change": "^1.0.0", + "@ldapjs/controls": "^2.1.0", + "@ldapjs/dn": "^1.1.0", + "@ldapjs/filter": "^2.1.1", + "@ldapjs/messages": "^1.3.0", + "@ldapjs/protocol": "^1.2.1", + "abstract-logging": "^2.0.1", + "assert-plus": "^1.0.0", + "backoff": "^2.5.0", + "once": "^1.4.0", + "vasync": "^2.2.1", + "verror": "^1.10.1" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/precond": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", + "integrity": "sha512-QCYG84SgGyGzqJ/vlMsxeXd/pgL/I94ixdNFyh1PusWmTCyVfPJjZ1K1jvHtsbfnXQs2TSkEP2fR7QiMZAnKFQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process-warning": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.2.tgz", + "integrity": "sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==", + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/vasync": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vasync/-/vasync-2.2.1.tgz", + "integrity": "sha512-Hq72JaTpcTFdWiNA4Y22Amej2GH3BFmBaKPPlDZ4/oC8HNn2ISHLkFrJU4Ds8R3jcUi7oo5Y9jcMHKjES+N9wQ==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "verror": "1.10.0" + } + }, + "node_modules/vasync/node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c058cdd --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "ldap-oauth-bridge", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "dependencies": { + "axios": "^1.12.2", + "ldapjs": "^3.0.7" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..1b9b67b --- /dev/null +++ b/server.js @@ -0,0 +1,115 @@ +const ldap = require('ldapjs'); +const axios = require('axios'); + +// Configuration +const LDAP_PORT = 3893; +const KEYCLOAK_URL = ''; +const KEYCLOAK_REALM = ''; +const KEYCLOAK_CLIENT_ID = ''; +const KEYCLOAK_CLIENT_SECRET = ''; +const BASE_DN = ''; + +// Create LDAP server +const server = ldap.createServer(); + +// Helper function to parse DN and extract username +function extractUsername(dn) { + try { + const parsed = ldap.parseDN(dn); + // rdns is an array in some versions, need to handle it properly + if (parsed.rdns && Array.isArray(parsed.rdns)) { + for (const rdn of parsed.rdns) { + if (rdn.attrs) { + for (const attr of rdn.attrs) { + if (attr.type === 'cn' || attr.type === 'uid') { + return attr.value; + } + } + } + } + } + // Fallback: try to extract from string + const match = dn.match(/(?:cn|uid)=([^,]+)/i); + return match ? match[1] : null; + } catch (error) { + console.error('Error parsing DN:', error); + // Fallback: simple regex extraction + const match = dn.toString().match(/(?:cn|uid)=([^,]+)/i); + return match ? match[1] : null; + } +} + +// Authenticate against Keycloak using Resource Owner Password Credentials flow +async function authenticateWithKeycloak(username, password) { + try { + const tokenUrl = `${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token`; + + const params = new URLSearchParams(); + params.append('grant_type', 'password'); + params.append('client_id', KEYCLOAK_CLIENT_ID); + params.append('client_secret', KEYCLOAK_CLIENT_SECRET); + params.append('username', username); + params.append('password', password); + + const response = await axios.post(tokenUrl, params, { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } + }); + + return response.status === 200 && response.data.access_token; + } catch (error) { + console.error(`Auth failed for ${username}:`, error.response?.data || error.message); + return false; + } +} + +// Handle BIND requests (authentication) +server.bind(BASE_DN, async (req, res, next) => { + const username = extractUsername(req.dn.toString()); + const password = req.credentials; + + console.log(`Bind attempt for: ${username}`); + + if (!username || !password) { + console.log('Missing username or password'); + return next(new ldap.InvalidCredentialsError()); + } + + const authenticated = await authenticateWithKeycloak(username, password); + + if (authenticated) { + console.log(`Successfully authenticated: ${username}`); + res.end(); + return next(); + } else { + console.log(`Authentication failed for: ${username}`); + return next(new ldap.InvalidCredentialsError()); + } +}); + +// Handle SEARCH requests (required by some LDAP clients) +server.search(BASE_DN, (req, res, next) => { + console.log(`Search request: ${req.dn.toString()}, filter: ${req.filter.toString()}`); + + // Return empty results - we only care about authentication + res.end(); + return next(); +}); + +// Handle UNBIND +server.unbind((req, res, next) => { + res.end(); + return next(); +}); + +// Start server +server.listen(LDAP_PORT, '0.0.0.0', () => { + console.log(`LDAP-OAuth2 bridge listening on port ${LDAP_PORT}`); + console.log(`Keycloak URL: ${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}`); +}); + +// Error handling +server.on('error', (err) => { + console.error('Server error:', err); +});