initial commit

This commit is contained in:
Zoe
2023-01-03 09:29:04 -06:00
commit 7851137d88
12889 changed files with 2557443 additions and 0 deletions

21
node_modules/listhen/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Pooya Parsa <pooya@pi0.io>
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.

168
node_modules/listhen/README.md generated vendored Normal file
View File

@@ -0,0 +1,168 @@
![listhen](https://user-images.githubusercontent.com/904724/101662837-46845280-3a4a-11eb-9e9a-d5399e8af753.png)
# 👂 listhen
> Elegant http listener
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![Github Actions][github-actions-src]][github-actions-href]
[![Codecov][codecov-src]][codecov-href]
✔️ Promisified interface for listening and closing server
✔️ Works with express/connect or plain http handle function
✔️ Support HTTP and HTTPS
✔️ Automatically assign a port or fallback to human friendly alternative (with [get-port-please](https://github.com/unjs/get-port-please))
✔️ Automatically generate listening URL and show on console
✔️ Automatically copy URL to clipboard
✔️ Automatically open in browser (opt-in)
✔️ Automatically generate self-signed certificate
✔️ Automatically detect test and production environments
✔️ Automatically close on exit signal
✔️ Gracefully shutdown server with [http-shutdown](https://github.com/thedillonb/http-shutdown)
## Install
Install using npm or yarn:
```bash
npm i listhen
# or
yarn add listhen
```
Import into your Node.js project:
```js
// CommonJS
const { listen } = require('listhen')
// ESM
import { listen } from 'listhen'
```
## Usage
**Function signature:**
```ts
const { url, getURL, server, close } = await listen(handle, options?)
```
**Plain handle function:**
```ts
listen((_req, res) => {
res.end('hi')
})
```
**With express/connect:**
```ts
const express = require('express')
const app = express()
app.use('/', ((_req, res) => {
res.end('hi')
})
listen(app)
```
## Options
### `port`
- Default: `process.env.PORT` or 3000 or memorized random (see [get-port-please](https://github.com/unjs/get-port-please))
Port to listen.
### `hostname`
- Default: `process.env.HOST || '0.0.0.0'`
Default hostname to listen.
### `https`
- Type: Boolean | Object
- Default: `false`
Listen on https with SSL enabled.
#### Self Signed Certificate
By setting `https: true`, listhen will use an auto generated self-signed certificate.
You can set https to an object for custom options. Possible options:
- `domains`: (Array) Default is `['localhost', '127.0.0.1', '::1']`.
- `validityDays`: (Number) Default is `1`.
#### User Provided Certificate
Set `https: { cert, key }` where cert and key are path to the ssl certificates.
You can also provide inline cert and key instead of reading from filesystem. In this case, they should start with `--`.
### `showURL`
- Default: `true` (force disabled on test environment)
Show a CLI message for listening URL.
### `baseURL`
- Default: `/`
### `open`
- Default: `false` (force disabled on test and production environments)
Open URL in browser. Silently ignores errors.
### `clipboard`
- Default: `false` (force disabled on test and production environments)
Copy URL to clipboard. Silently ignores errors.
### `isTest`
- Default: `process.env.NODE_ENV === 'test'`
Detect if running in a test environment to disable some features.
### `autoClose`
- Default: `true`
Automatically close when an exit signal is received on process.
## License
MIT. Made with 💖
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/listhen?style=flat-square
[npm-version-href]: https://npmjs.com/package/listhen
[npm-downloads-src]: https://img.shields.io/npm/dm/listhen?style=flat-square
[npm-downloads-href]: https://npmjs.com/package/listhen
[github-actions-src]: https://img.shields.io/github/workflow/status/unjs/listhen/ci/main?style=flat-square
[github-actions-href]: https://github.com/unjs/listhen/actions?query=workflow%3Aci
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/listhen/main?style=flat-square
[codecov-href]: https://codecov.io/gh/unjs/listhen

78
node_modules/listhen/dist/chunks/cert.cjs generated vendored Normal file
View File

@@ -0,0 +1,78 @@
'use strict';
const node_util = require('node:util');
const forge = require('node-forge');
const ipRegex = require('ip-regex');
async function generateSSLCert(options) {
const attributes = [
{ name: "commonName", value: options.commonName || options.domains[0] }
];
const extensions = [
{ name: "basicConstraints", cA: false, critical: true },
{ name: "keyUsage", digitalSignature: true, keyEncipherment: true, critical: true },
{ name: "extKeyUsage", serverAuth: true, clientAuth: true },
{
name: "subjectAltName",
altNames: options.domains.map((domain) => {
const types = { domain: 2, ip: 7 };
const isIp = ipRegex({ exact: true }).test(domain);
if (isIp) {
return { type: types.ip, ip: domain };
}
return { type: types.domain, value: domain };
})
}
];
const ca = forge.pki.certificateFromPem(options.caCert);
return await generateCert({
subject: attributes,
issuer: ca.subject.attributes,
extensions,
validityDays: options.validityDays,
signWith: options.caKey
});
}
async function generateCA(options = {}) {
const attributes = [
options.commonName && { name: "commonName", value: options.commonName },
options.countryCode && { name: "countryName", value: options.countryCode },
options.state && { name: "stateOrProvinceName", value: options.state },
options.locality && { name: "localityName", value: options.locality },
options.organization && { name: "organizationName", value: options.organization }
].filter(Boolean);
const extensions = [
{ name: "basicConstraints", cA: true, critical: true },
{ name: "keyUsage", keyCertSign: true, critical: true }
];
return await generateCert({
subject: attributes,
issuer: attributes,
extensions,
validityDays: options.validityDays || 365
});
}
async function generateCert(options) {
const serial = Math.floor(Math.random() * 95e3 + 5e4).toString();
const generateKeyPair = node_util.promisify(forge.pki.rsa.generateKeyPair.bind(forge.pki.rsa));
const keyPair = await generateKeyPair({ bits: 2048, workers: 4 });
const cert = forge.pki.createCertificate();
cert.publicKey = keyPair.publicKey;
cert.serialNumber = Buffer.from(serial).toString("hex");
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + options.validityDays);
cert.setSubject(options.subject);
cert.setIssuer(options.issuer);
cert.setExtensions(options.extensions);
const signWith = options.signWith ? forge.pki.privateKeyFromPem(options.signWith) : keyPair.privateKey;
cert.sign(signWith, forge.md.sha256.create());
return {
key: forge.pki.privateKeyToPem(keyPair.privateKey),
cert: forge.pki.certificateToPem(cert)
};
}
exports.generateCA = generateCA;
exports.generateCert = generateCert;
exports.generateSSLCert = generateSSLCert;

74
node_modules/listhen/dist/chunks/cert.mjs generated vendored Normal file
View File

@@ -0,0 +1,74 @@
import { promisify } from 'node:util';
import forge from 'node-forge';
import ipRegex from 'ip-regex';
async function generateSSLCert(options) {
const attributes = [
{ name: "commonName", value: options.commonName || options.domains[0] }
];
const extensions = [
{ name: "basicConstraints", cA: false, critical: true },
{ name: "keyUsage", digitalSignature: true, keyEncipherment: true, critical: true },
{ name: "extKeyUsage", serverAuth: true, clientAuth: true },
{
name: "subjectAltName",
altNames: options.domains.map((domain) => {
const types = { domain: 2, ip: 7 };
const isIp = ipRegex({ exact: true }).test(domain);
if (isIp) {
return { type: types.ip, ip: domain };
}
return { type: types.domain, value: domain };
})
}
];
const ca = forge.pki.certificateFromPem(options.caCert);
return await generateCert({
subject: attributes,
issuer: ca.subject.attributes,
extensions,
validityDays: options.validityDays,
signWith: options.caKey
});
}
async function generateCA(options = {}) {
const attributes = [
options.commonName && { name: "commonName", value: options.commonName },
options.countryCode && { name: "countryName", value: options.countryCode },
options.state && { name: "stateOrProvinceName", value: options.state },
options.locality && { name: "localityName", value: options.locality },
options.organization && { name: "organizationName", value: options.organization }
].filter(Boolean);
const extensions = [
{ name: "basicConstraints", cA: true, critical: true },
{ name: "keyUsage", keyCertSign: true, critical: true }
];
return await generateCert({
subject: attributes,
issuer: attributes,
extensions,
validityDays: options.validityDays || 365
});
}
async function generateCert(options) {
const serial = Math.floor(Math.random() * 95e3 + 5e4).toString();
const generateKeyPair = promisify(forge.pki.rsa.generateKeyPair.bind(forge.pki.rsa));
const keyPair = await generateKeyPair({ bits: 2048, workers: 4 });
const cert = forge.pki.createCertificate();
cert.publicKey = keyPair.publicKey;
cert.serialNumber = Buffer.from(serial).toString("hex");
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setDate(cert.validity.notAfter.getDate() + options.validityDays);
cert.setSubject(options.subject);
cert.setIssuer(options.issuer);
cert.setExtensions(options.extensions);
const signWith = options.signWith ? forge.pki.privateKeyFromPem(options.signWith) : keyPair.privateKey;
cert.sign(signWith, forge.md.sha256.create());
return {
key: forge.pki.privateKeyToPem(keyPair.privateKey),
cert: forge.pki.certificateToPem(cert)
};
}
export { generateCA, generateCert, generateSSLCert };

1071
node_modules/listhen/dist/chunks/xdg-open.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

1069
node_modules/listhen/dist/chunks/xdg-open.mjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

451
node_modules/listhen/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,451 @@
'use strict';
const node_http = require('node:http');
const node_https = require('node:https');
const node_util = require('node:util');
const node_fs = require('node:fs');
const os = require('node:os');
const colorette = require('colorette');
const getPortPlease = require('get-port-please');
const addShutdown = require('http-shutdown');
const defu = require('defu');
const childProcess = require('node:child_process');
const node_path = require('node:path');
const { platform, arch } = process;
const getWslDrivesMountPoint = (() => {
const defaultMountPoint = "/mnt/";
let mountPoint;
return async function() {
if (mountPoint) {
return mountPoint;
}
const configFilePath = "/etc/wsl.conf";
let isConfigFileExists = false;
try {
await node_fs.promises.access(configFilePath, node_fs.constants.F_OK);
isConfigFileExists = true;
} catch {
}
if (!isConfigFileExists) {
return defaultMountPoint;
}
const configContent = await node_fs.promises.readFile(configFilePath, { encoding: "utf8" });
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
if (!configMountPoint) {
return defaultMountPoint;
}
mountPoint = configMountPoint.groups.mountPoint.trim();
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
return mountPoint;
};
})();
const pTryEach = async (array, mapper) => {
let latestError;
for (const item of array) {
try {
return await mapper(item);
} catch (error) {
latestError = error;
}
}
throw latestError;
};
const baseOpen = async (options) => {
options = {
wait: false,
background: false,
newInstance: false,
allowNonzeroExitCode: false,
...options
};
if (Array.isArray(options.app)) {
return pTryEach(options.app, (singleApp) => baseOpen({
...options,
app: singleApp
}));
}
let { name: app, arguments: appArguments = [] } = options.app || {};
appArguments = [...appArguments];
if (Array.isArray(app)) {
return pTryEach(app, (appName) => baseOpen({
...options,
app: {
name: appName,
arguments: appArguments
}
}));
}
let command;
const cliArguments = [];
const childProcessOptions = {};
if (platform === "darwin") {
command = "open";
if (options.wait) {
cliArguments.push("--wait-apps");
}
if (options.background) {
cliArguments.push("--background");
}
if (options.newInstance) {
cliArguments.push("--new");
}
if (app) {
cliArguments.push("-a", app);
}
} else if (platform === "win32" || isWsl() && !isDocker()) {
const mountPoint = await getWslDrivesMountPoint();
command = isWsl() ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
cliArguments.push(
"-NoProfile",
"-NonInteractive",
"\u2013ExecutionPolicy",
"Bypass",
"-EncodedCommand"
);
if (!isWsl()) {
childProcessOptions.windowsVerbatimArguments = true;
}
const encodedArguments = ["Start"];
if (options.wait) {
encodedArguments.push("-Wait");
}
if (app) {
encodedArguments.push(`"\`"${app}\`""`, "-ArgumentList");
if (options.target) {
appArguments.unshift(options.target);
}
} else if (options.target) {
encodedArguments.push(`"${options.target}"`);
}
if (appArguments.length > 0) {
appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
encodedArguments.push(appArguments.join(","));
}
options.target = Buffer.from(encodedArguments.join(" "), "utf16le").toString("base64");
} else {
if (app) {
command = app;
} else {
command = "xdg-open";
const useSystemXdgOpen = process.versions.electron || platform === "android";
if (!useSystemXdgOpen) {
command = node_path.join(os.tmpdir(), "xdg-open");
if (!node_fs.existsSync(command)) {
try {
node_fs.writeFileSync(
node_path.join(os.tmpdir(), "xdg-open"),
await import('./chunks/xdg-open.cjs').then((r) => r.xdgOpenScript()),
"utf8"
);
node_fs.chmodSync(command, 493);
} catch {
command = "xdg-open";
}
}
}
}
if (appArguments.length > 0) {
cliArguments.push(...appArguments);
}
if (!options.wait) {
childProcessOptions.stdio = "ignore";
childProcessOptions.detached = true;
}
}
if (options.target) {
cliArguments.push(options.target);
}
if (platform === "darwin" && appArguments.length > 0) {
cliArguments.push("--args", ...appArguments);
}
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
if (options.wait) {
return new Promise((resolve, reject) => {
subprocess.once("error", reject);
subprocess.once("close", (exitCode) => {
if (options.allowNonzeroExitCode && exitCode > 0) {
reject(new Error(`Exited with code ${exitCode}`));
return;
}
resolve(subprocess);
});
});
}
subprocess.unref();
return subprocess;
};
const open = (target, options = {}) => {
if (typeof target !== "string") {
throw new TypeError("Expected a `target`");
}
return baseOpen({
...options,
target
});
};
const openApp = (name, options) => {
if (typeof name !== "string") {
throw new TypeError("Expected a `name`");
}
const { arguments: appArguments = [] } = options || {};
if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) {
throw new TypeError("Expected `appArguments` as Array type");
}
return baseOpen({
...options,
app: {
name,
arguments: appArguments
}
});
};
function detectArchBinary(binary) {
if (typeof binary === "string" || Array.isArray(binary)) {
return binary;
}
const { [arch]: archBinary } = binary;
if (!archBinary) {
throw new Error(`${arch} is not supported`);
}
return archBinary;
}
function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
if (wsl && isWsl()) {
return detectArchBinary(wsl);
}
if (!platformBinary) {
throw new Error(`${platform} is not supported`);
}
return detectArchBinary(platformBinary);
}
const apps = {};
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
darwin: "google chrome",
win32: "chrome",
linux: ["google-chrome", "google-chrome-stable", "chromium"]
}, {
wsl: {
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
}
}));
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
darwin: "firefox",
win32: "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
linux: "firefox"
}, {
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
}));
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
darwin: "microsoft edge",
win32: "msedge",
linux: ["microsoft-edge", "microsoft-edge-dev"]
}, {
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
}));
open.apps = apps;
open.openApp = openApp;
function defineLazyProperty(object, propertyName, valueGetter) {
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
Object.defineProperty(object, propertyName, {
configurable: true,
enumerable: true,
get() {
const result = valueGetter();
define(result);
return result;
},
set(value) {
define(value);
}
});
return object;
}
function _isWsl() {
if (process.platform !== "linux") {
return false;
}
if (os.release().toLowerCase().includes("microsoft")) {
if (isDocker()) {
return false;
}
return true;
}
try {
return node_fs.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
} catch {
return false;
}
}
let isWSLCached;
function isWsl() {
if (isWSLCached === void 0) {
isWSLCached = _isWsl();
}
return isWSLCached;
}
function hasDockerEnvironment() {
try {
node_fs.statSync("/.dockerenv");
return true;
} catch {
return false;
}
}
function hasDockerCGroup() {
try {
return node_fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
} catch {
return false;
}
}
let isDockerCached;
function isDocker() {
if (isDockerCached === void 0) {
isDockerCached = hasDockerEnvironment() || hasDockerCGroup();
}
return isDockerCached;
}
async function listen(handle, options_ = {}) {
options_ = defu.defu(options_, {
port: process.env.PORT || 3e3,
hostname: process.env.HOST || "",
showURL: true,
baseURL: "/",
open: false,
clipboard: false,
isTest: process.env.NODE_ENV === "test",
isProd: process.env.NODE_ENV === "production",
autoClose: true
});
if (options_.isTest) {
options_.showURL = false;
}
if (options_.isProd || options_.isTest) {
options_.open = false;
options_.clipboard = false;
}
const port = await getPortPlease.getPort({
port: Number(options_.port),
verbose: !options_.isTest,
host: options_.hostname,
...typeof options_.port === "object" && options_.port
});
let server;
let addr;
const getURL = (host, baseURL) => {
const anyV4 = addr?.addr === "0.0.0.0";
const anyV6 = addr?.addr === "[::]";
return `${addr.proto}://${host || options_.hostname || (anyV4 || anyV6 ? "localhost" : addr.addr)}:${addr.port}${baseURL || options_.baseURL}`;
};
let https = false;
if (options_.https) {
const { key, cert } = await resolveCert({ ...options_.https }, options_.hostname);
https = { key, cert };
server = node_https.createServer({ key, cert }, handle);
addShutdown(server);
await node_util.promisify(server.listen.bind(server))(port, options_.hostname);
const _addr = server.address();
addr = { proto: "https", addr: formatAddress(_addr), port: _addr.port };
} else {
server = node_http.createServer(handle);
addShutdown(server);
await node_util.promisify(server.listen.bind(server))(port, options_.hostname);
const _addr = server.address();
addr = { proto: "http", addr: formatAddress(_addr), port: _addr.port };
}
let _closed = false;
const close = () => {
if (_closed) {
return Promise.resolve();
}
_closed = true;
return node_util.promisify(server.shutdown)();
};
if (options_.clipboard) {
const clipboardy = await import('clipboardy').then((r) => r.default || r);
await clipboardy.write(getURL()).catch(() => {
options_.clipboard = false;
});
}
const showURL = (options) => {
const add = options_.clipboard ? colorette.gray("(copied to clipboard)") : "";
const lines = [];
const baseURL = options?.baseURL || options_.baseURL || "";
const name = options?.name ? ` (${options.name})` : "";
const anyV4 = addr?.addr === "0.0.0.0";
const anyV6 = addr?.addr === "[::]";
if (anyV4 || anyV6) {
lines.push(` > Local${name}: ${formatURL(getURL("localhost", baseURL))} ${add}`);
for (const addr2 of getNetworkInterfaces(anyV4)) {
lines.push(` > Network${name}: ${formatURL(getURL(addr2, baseURL))}`);
}
} else {
lines.push(` > Listening${name}: ${formatURL(getURL(void 0, baseURL))} ${add}`);
}
console.log("\n" + lines.join("\n") + "\n");
};
if (options_.showURL) {
showURL();
}
const _open = async () => {
await open(getURL()).catch(() => {
});
};
if (options_.open) {
await _open();
}
if (options_.autoClose) {
process.on("exit", () => close());
}
return {
url: getURL(),
https,
server,
open: _open,
showURL,
close
};
}
async function resolveCert(options, host) {
if (options.key && options.cert) {
const isInline = (s = "") => s.startsWith("--");
const r = (s) => isInline(s) ? s : node_fs.promises.readFile(s, "utf8");
return {
key: await r(options.key),
cert: await r(options.cert)
};
}
const { generateCA, generateSSLCert } = await import('./chunks/cert.cjs');
const ca = await generateCA();
const cert = await generateSSLCert({
caCert: ca.cert,
caKey: ca.key,
domains: options.domains || ["localhost", "127.0.0.1", "::1", host].filter(Boolean),
validityDays: options.validityDays || 1
});
return cert;
}
function getNetworkInterfaces(v4Only = true) {
const addrs = /* @__PURE__ */ new Set();
for (const details of Object.values(os.networkInterfaces())) {
if (details) {
for (const d of details) {
if (!d.internal && !(d.mac === "00:00:00:00:00:00") && !d.address.startsWith("fe80::") && !(v4Only && (d.family === "IPv6" || +d.family === 6))) {
addrs.add(formatAddress(d));
}
}
}
}
return [...addrs].sort();
}
function formatAddress(addr) {
return addr.family === "IPv6" || addr.family === 6 ? `[${addr.address}]` : addr.address;
}
function formatURL(url) {
return colorette.cyan(colorette.underline(decodeURI(url).replace(/:(\d+)\//g, `:${colorette.bold("$1")}/`)));
}
exports.listen = listen;

44
node_modules/listhen/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import { Server, RequestListener } from 'node:http';
import { Server as Server$1 } from 'node:https';
import { GetPortInput } from 'get-port-please';
interface Certificate {
key: string;
cert: string;
}
interface HTTPSOptions {
cert: string;
key: string;
domains?: string[];
validityDays?: number;
}
interface ListenOptions {
name: string;
port?: GetPortInput;
hostname: string;
showURL: boolean;
baseURL: string;
open: boolean;
https: boolean | HTTPSOptions;
clipboard: boolean;
isTest: Boolean;
isProd: Boolean;
autoClose: Boolean;
autoCloseSignals: string[];
}
interface ShowURLOptions {
baseURL: string;
name?: string;
}
interface Listener {
url: string;
address: any;
server: Server | Server$1;
https: false | Certificate;
close: () => Promise<void>;
open: () => Promise<void>;
showURL: (options?: Pick<ListenOptions, "baseURL">) => void;
}
declare function listen(handle: RequestListener, options_?: Partial<ListenOptions>): Promise<Listener>;
export { Certificate, HTTPSOptions, ListenOptions, Listener, ShowURLOptions, listen };

449
node_modules/listhen/dist/index.mjs generated vendored Normal file
View File

@@ -0,0 +1,449 @@
import { createServer as createServer$1 } from 'node:http';
import { createServer } from 'node:https';
import { promisify } from 'node:util';
import { readFileSync, existsSync, writeFileSync, chmodSync, statSync, promises, constants } from 'node:fs';
import os, { networkInterfaces } from 'node:os';
import { gray, cyan, underline, bold } from 'colorette';
import { getPort } from 'get-port-please';
import addShutdown from 'http-shutdown';
import { defu } from 'defu';
import childProcess from 'node:child_process';
import { join } from 'node:path';
const { platform, arch } = process;
const getWslDrivesMountPoint = (() => {
const defaultMountPoint = "/mnt/";
let mountPoint;
return async function() {
if (mountPoint) {
return mountPoint;
}
const configFilePath = "/etc/wsl.conf";
let isConfigFileExists = false;
try {
await promises.access(configFilePath, constants.F_OK);
isConfigFileExists = true;
} catch {
}
if (!isConfigFileExists) {
return defaultMountPoint;
}
const configContent = await promises.readFile(configFilePath, { encoding: "utf8" });
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
if (!configMountPoint) {
return defaultMountPoint;
}
mountPoint = configMountPoint.groups.mountPoint.trim();
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
return mountPoint;
};
})();
const pTryEach = async (array, mapper) => {
let latestError;
for (const item of array) {
try {
return await mapper(item);
} catch (error) {
latestError = error;
}
}
throw latestError;
};
const baseOpen = async (options) => {
options = {
wait: false,
background: false,
newInstance: false,
allowNonzeroExitCode: false,
...options
};
if (Array.isArray(options.app)) {
return pTryEach(options.app, (singleApp) => baseOpen({
...options,
app: singleApp
}));
}
let { name: app, arguments: appArguments = [] } = options.app || {};
appArguments = [...appArguments];
if (Array.isArray(app)) {
return pTryEach(app, (appName) => baseOpen({
...options,
app: {
name: appName,
arguments: appArguments
}
}));
}
let command;
const cliArguments = [];
const childProcessOptions = {};
if (platform === "darwin") {
command = "open";
if (options.wait) {
cliArguments.push("--wait-apps");
}
if (options.background) {
cliArguments.push("--background");
}
if (options.newInstance) {
cliArguments.push("--new");
}
if (app) {
cliArguments.push("-a", app);
}
} else if (platform === "win32" || isWsl() && !isDocker()) {
const mountPoint = await getWslDrivesMountPoint();
command = isWsl() ? `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe` : `${process.env.SYSTEMROOT}\\System32\\WindowsPowerShell\\v1.0\\powershell`;
cliArguments.push(
"-NoProfile",
"-NonInteractive",
"\u2013ExecutionPolicy",
"Bypass",
"-EncodedCommand"
);
if (!isWsl()) {
childProcessOptions.windowsVerbatimArguments = true;
}
const encodedArguments = ["Start"];
if (options.wait) {
encodedArguments.push("-Wait");
}
if (app) {
encodedArguments.push(`"\`"${app}\`""`, "-ArgumentList");
if (options.target) {
appArguments.unshift(options.target);
}
} else if (options.target) {
encodedArguments.push(`"${options.target}"`);
}
if (appArguments.length > 0) {
appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
encodedArguments.push(appArguments.join(","));
}
options.target = Buffer.from(encodedArguments.join(" "), "utf16le").toString("base64");
} else {
if (app) {
command = app;
} else {
command = "xdg-open";
const useSystemXdgOpen = process.versions.electron || platform === "android";
if (!useSystemXdgOpen) {
command = join(os.tmpdir(), "xdg-open");
if (!existsSync(command)) {
try {
writeFileSync(
join(os.tmpdir(), "xdg-open"),
await import('./chunks/xdg-open.mjs').then((r) => r.xdgOpenScript()),
"utf8"
);
chmodSync(command, 493);
} catch {
command = "xdg-open";
}
}
}
}
if (appArguments.length > 0) {
cliArguments.push(...appArguments);
}
if (!options.wait) {
childProcessOptions.stdio = "ignore";
childProcessOptions.detached = true;
}
}
if (options.target) {
cliArguments.push(options.target);
}
if (platform === "darwin" && appArguments.length > 0) {
cliArguments.push("--args", ...appArguments);
}
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
if (options.wait) {
return new Promise((resolve, reject) => {
subprocess.once("error", reject);
subprocess.once("close", (exitCode) => {
if (options.allowNonzeroExitCode && exitCode > 0) {
reject(new Error(`Exited with code ${exitCode}`));
return;
}
resolve(subprocess);
});
});
}
subprocess.unref();
return subprocess;
};
const open = (target, options = {}) => {
if (typeof target !== "string") {
throw new TypeError("Expected a `target`");
}
return baseOpen({
...options,
target
});
};
const openApp = (name, options) => {
if (typeof name !== "string") {
throw new TypeError("Expected a `name`");
}
const { arguments: appArguments = [] } = options || {};
if (appArguments !== void 0 && appArguments !== null && !Array.isArray(appArguments)) {
throw new TypeError("Expected `appArguments` as Array type");
}
return baseOpen({
...options,
app: {
name,
arguments: appArguments
}
});
};
function detectArchBinary(binary) {
if (typeof binary === "string" || Array.isArray(binary)) {
return binary;
}
const { [arch]: archBinary } = binary;
if (!archBinary) {
throw new Error(`${arch} is not supported`);
}
return archBinary;
}
function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
if (wsl && isWsl()) {
return detectArchBinary(wsl);
}
if (!platformBinary) {
throw new Error(`${platform} is not supported`);
}
return detectArchBinary(platformBinary);
}
const apps = {};
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
darwin: "google chrome",
win32: "chrome",
linux: ["google-chrome", "google-chrome-stable", "chromium"]
}, {
wsl: {
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
}
}));
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
darwin: "firefox",
win32: "C:\\Program Files\\Mozilla Firefox\\firefox.exe",
linux: "firefox"
}, {
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
}));
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
darwin: "microsoft edge",
win32: "msedge",
linux: ["microsoft-edge", "microsoft-edge-dev"]
}, {
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
}));
open.apps = apps;
open.openApp = openApp;
function defineLazyProperty(object, propertyName, valueGetter) {
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
Object.defineProperty(object, propertyName, {
configurable: true,
enumerable: true,
get() {
const result = valueGetter();
define(result);
return result;
},
set(value) {
define(value);
}
});
return object;
}
function _isWsl() {
if (process.platform !== "linux") {
return false;
}
if (os.release().toLowerCase().includes("microsoft")) {
if (isDocker()) {
return false;
}
return true;
}
try {
return readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isDocker() : false;
} catch {
return false;
}
}
let isWSLCached;
function isWsl() {
if (isWSLCached === void 0) {
isWSLCached = _isWsl();
}
return isWSLCached;
}
function hasDockerEnvironment() {
try {
statSync("/.dockerenv");
return true;
} catch {
return false;
}
}
function hasDockerCGroup() {
try {
return readFileSync("/proc/self/cgroup", "utf8").includes("docker");
} catch {
return false;
}
}
let isDockerCached;
function isDocker() {
if (isDockerCached === void 0) {
isDockerCached = hasDockerEnvironment() || hasDockerCGroup();
}
return isDockerCached;
}
async function listen(handle, options_ = {}) {
options_ = defu(options_, {
port: process.env.PORT || 3e3,
hostname: process.env.HOST || "",
showURL: true,
baseURL: "/",
open: false,
clipboard: false,
isTest: process.env.NODE_ENV === "test",
isProd: process.env.NODE_ENV === "production",
autoClose: true
});
if (options_.isTest) {
options_.showURL = false;
}
if (options_.isProd || options_.isTest) {
options_.open = false;
options_.clipboard = false;
}
const port = await getPort({
port: Number(options_.port),
verbose: !options_.isTest,
host: options_.hostname,
...typeof options_.port === "object" && options_.port
});
let server;
let addr;
const getURL = (host, baseURL) => {
const anyV4 = addr?.addr === "0.0.0.0";
const anyV6 = addr?.addr === "[::]";
return `${addr.proto}://${host || options_.hostname || (anyV4 || anyV6 ? "localhost" : addr.addr)}:${addr.port}${baseURL || options_.baseURL}`;
};
let https = false;
if (options_.https) {
const { key, cert } = await resolveCert({ ...options_.https }, options_.hostname);
https = { key, cert };
server = createServer({ key, cert }, handle);
addShutdown(server);
await promisify(server.listen.bind(server))(port, options_.hostname);
const _addr = server.address();
addr = { proto: "https", addr: formatAddress(_addr), port: _addr.port };
} else {
server = createServer$1(handle);
addShutdown(server);
await promisify(server.listen.bind(server))(port, options_.hostname);
const _addr = server.address();
addr = { proto: "http", addr: formatAddress(_addr), port: _addr.port };
}
let _closed = false;
const close = () => {
if (_closed) {
return Promise.resolve();
}
_closed = true;
return promisify(server.shutdown)();
};
if (options_.clipboard) {
const clipboardy = await import('clipboardy').then((r) => r.default || r);
await clipboardy.write(getURL()).catch(() => {
options_.clipboard = false;
});
}
const showURL = (options) => {
const add = options_.clipboard ? gray("(copied to clipboard)") : "";
const lines = [];
const baseURL = options?.baseURL || options_.baseURL || "";
const name = options?.name ? ` (${options.name})` : "";
const anyV4 = addr?.addr === "0.0.0.0";
const anyV6 = addr?.addr === "[::]";
if (anyV4 || anyV6) {
lines.push(` > Local${name}: ${formatURL(getURL("localhost", baseURL))} ${add}`);
for (const addr2 of getNetworkInterfaces(anyV4)) {
lines.push(` > Network${name}: ${formatURL(getURL(addr2, baseURL))}`);
}
} else {
lines.push(` > Listening${name}: ${formatURL(getURL(void 0, baseURL))} ${add}`);
}
console.log("\n" + lines.join("\n") + "\n");
};
if (options_.showURL) {
showURL();
}
const _open = async () => {
await open(getURL()).catch(() => {
});
};
if (options_.open) {
await _open();
}
if (options_.autoClose) {
process.on("exit", () => close());
}
return {
url: getURL(),
https,
server,
open: _open,
showURL,
close
};
}
async function resolveCert(options, host) {
if (options.key && options.cert) {
const isInline = (s = "") => s.startsWith("--");
const r = (s) => isInline(s) ? s : promises.readFile(s, "utf8");
return {
key: await r(options.key),
cert: await r(options.cert)
};
}
const { generateCA, generateSSLCert } = await import('./chunks/cert.mjs');
const ca = await generateCA();
const cert = await generateSSLCert({
caCert: ca.cert,
caKey: ca.key,
domains: options.domains || ["localhost", "127.0.0.1", "::1", host].filter(Boolean),
validityDays: options.validityDays || 1
});
return cert;
}
function getNetworkInterfaces(v4Only = true) {
const addrs = /* @__PURE__ */ new Set();
for (const details of Object.values(networkInterfaces())) {
if (details) {
for (const d of details) {
if (!d.internal && !(d.mac === "00:00:00:00:00:00") && !d.address.startsWith("fe80::") && !(v4Only && (d.family === "IPv6" || +d.family === 6))) {
addrs.add(formatAddress(d));
}
}
}
}
return [...addrs].sort();
}
function formatAddress(addr) {
return addr.family === "IPv6" || addr.family === 6 ? `[${addr.address}]` : addr.address;
}
function formatURL(url) {
return cyan(underline(decodeURI(url).replace(/:(\d+)\//g, `:${bold("$1")}/`)));
}
export { listen };

51
node_modules/listhen/package.json generated vendored Normal file
View File

@@ -0,0 +1,51 @@
{
"name": "listhen",
"version": "1.0.1",
"description": "",
"repository": "unjs/listhen",
"license": "MIT",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
}
},
"main": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist",
"lib"
],
"dependencies": {
"clipboardy": "^3.0.0",
"colorette": "^2.0.19",
"defu": "^6.1.1",
"get-port-please": "^2.6.1",
"http-shutdown": "^1.2.2",
"ip-regex": "^5.0.0",
"node-forge": "^1.3.1",
"ufo": "^1.0.0"
},
"devDependencies": {
"@types/node": "^18.11.9",
"@types/node-forge": "^1.3.1",
"@vitest/coverage-c8": "^0.25.3",
"eslint": "^8.28.0",
"eslint-config-unjs": "^0.0.2",
"jiti": "^1.16.0",
"standard-version": "^9.5.0",
"typescript": "^4.9.3",
"unbuild": "^1.0.1",
"vitest": "^0.25.3"
},
"packageManager": "pnpm@7.17.1",
"scripts": {
"build": "unbuild",
"dev": "vitest",
"lint": "eslint --ext .ts .",
"play": "jiti test/fixture/app",
"release": "pnpm test && pnpm build && standard-version && git push --follow-tags && pnpm publish",
"test": "pnpm lint && vitest run --coverage"
}
}