@miniflare/http-server
Advanced tools
Comparing version 2.0.0-rc.3 to 2.0.0-rc.4
@@ -27,2 +27,4 @@ /// <reference types="node" /> | ||
export declare const DEFAULT_PORT = 8787; | ||
export declare function getAccessibleHosts(ipv4?: boolean): string[]; | ||
@@ -33,2 +35,3 @@ | ||
port?: number; | ||
open?: boolean | string; | ||
https?: boolean | string; | ||
@@ -54,2 +57,3 @@ httpsKey?: string; | ||
port?: number; | ||
open?: boolean | string; | ||
https?: boolean | string; | ||
@@ -56,0 +60,0 @@ httpsKey?: string; |
@@ -0,3 +1,24 @@ | ||
var __create = Object.create; | ||
var __defProp = Object.defineProperty; | ||
var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
var __getOwnPropNames = Object.getOwnPropertyNames; | ||
var __getProtoOf = Object.getPrototypeOf; | ||
var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true }); | ||
var __export = (target, all) => { | ||
__markAsModule(target); | ||
for (var name in all) | ||
__defProp(target, name, { get: all[name], enumerable: true }); | ||
}; | ||
var __reExport = (target, module2, desc) => { | ||
if (module2 && typeof module2 === "object" || typeof module2 === "function") { | ||
for (let key of __getOwnPropNames(module2)) | ||
if (!__hasOwnProp.call(target, key) && key !== "default") | ||
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable }); | ||
} | ||
return target; | ||
}; | ||
var __toModule = (module2) => { | ||
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2); | ||
}; | ||
var __decorateClass = (decorators, target, key, kind) => { | ||
@@ -14,21 +35,27 @@ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target; | ||
// packages/http-server/src/index.ts | ||
import assert from "assert"; | ||
import http from "http"; | ||
import https from "https"; | ||
import { ReadableStream } from "stream/web"; | ||
import { URL } from "url"; | ||
import zlib from "zlib"; | ||
import { | ||
Request, | ||
logResponse | ||
} from "@miniflare/core"; | ||
import { randomHex } from "@miniflare/shared"; | ||
import { coupleWebSocket } from "@miniflare/web-sockets"; | ||
import { Headers } from "undici"; | ||
__export(exports, { | ||
DEFAULT_PORT: () => DEFAULT_PORT, | ||
HTTPPlugin: () => HTTPPlugin, | ||
convertNodeRequest: () => convertNodeRequest, | ||
createRequestListener: () => createRequestListener, | ||
createServer: () => createServer, | ||
getAccessibleHosts: () => getAccessibleHosts, | ||
startServer: () => startServer | ||
}); | ||
var import_assert = __toModule(require("assert")); | ||
var import_http = __toModule(require("http")); | ||
var import_https = __toModule(require("https")); | ||
var import_web = __toModule(require("stream/web")); | ||
var import_url = __toModule(require("url")); | ||
var import_zlib = __toModule(require("zlib")); | ||
var import_core = __toModule(require("@miniflare/core")); | ||
var import_shared2 = __toModule(require("@miniflare/shared")); | ||
var import_web_sockets = __toModule(require("@miniflare/web-sockets")); | ||
var import_undici2 = __toModule(require("undici")); | ||
// packages/http-server/src/helpers.ts | ||
import { networkInterfaces } from "os"; | ||
var import_os = __toModule(require("os")); | ||
function getAccessibleHosts(ipv4 = false) { | ||
const hosts = []; | ||
Object.values(networkInterfaces()).forEach((net) => net?.forEach(({ family, address }) => { | ||
Object.values((0, import_os.networkInterfaces)()).forEach((net) => net?.forEach(({ family, address }) => { | ||
if (!ipv4 || family === "IPv4") | ||
@@ -41,17 +68,12 @@ hosts.push(address); | ||
// packages/http-server/src/plugin.ts | ||
import fs from "fs/promises"; | ||
import path from "path"; | ||
import { promisify } from "util"; | ||
import { | ||
Option, | ||
OptionType, | ||
Plugin, | ||
defaultClock | ||
} from "@miniflare/shared"; | ||
import { fetch } from "undici"; | ||
var import_promises = __toModule(require("fs/promises")); | ||
var import_path = __toModule(require("path")); | ||
var import_util = __toModule(require("util")); | ||
var import_shared = __toModule(require("@miniflare/shared")); | ||
var import_undici = __toModule(require("undici")); | ||
var DAY = 864e5; | ||
var CERT_DAYS = 30; | ||
var CF_DAYS = 30; | ||
var defaultCertRoot = path.resolve(".mf", "cert"); | ||
var defaultCfPath = path.resolve("node_modules", ".mf", "cf.json"); | ||
var defaultCertRoot = import_path.default.resolve(".mf", "cert"); | ||
var defaultCfPath = import_path.default.resolve("node_modules", ".mf", "cf.json"); | ||
var defaultCfFetch = process.env.NODE_ENV !== "test"; | ||
@@ -91,5 +113,5 @@ var defaultCfFetchEndpoint = "https://workers.cloudflare.com/cf.json"; | ||
function valueOrFile(value, filePath) { | ||
return value ?? (filePath && fs.readFile(filePath, "utf8")); | ||
return value ?? (filePath && import_promises.default.readFile(filePath, "utf8")); | ||
} | ||
var HTTPPlugin = class extends Plugin { | ||
var HTTPPlugin = class extends import_shared.Plugin { | ||
constructor(ctx, options, defaults = {}) { | ||
@@ -103,3 +125,3 @@ super(ctx); | ||
this.cfFetchEndpoint = defaults.cfFetchEndpoint ?? defaultCfFetchEndpoint; | ||
this.clock = defaults.clock ?? defaultClock; | ||
this.clock = defaults.clock ?? import_shared.defaultClock; | ||
this.httpsEnabled = !!(this.https || this.httpsKey || this.httpsKeyPath || this.httpsCert || this.httpsCertPath || this.httpsCa || this.httpsCaPath || this.httpsPfx || this.httpsPfxPath); | ||
@@ -109,2 +131,3 @@ } | ||
port; | ||
open; | ||
https; | ||
@@ -147,4 +170,4 @@ httpsKey; | ||
try { | ||
this.#cf = JSON.parse(await fs.readFile(cfPath, "utf8")); | ||
const cfStat = await fs.stat(cfPath); | ||
this.#cf = JSON.parse(await import_promises.default.readFile(cfPath, "utf8")); | ||
const cfStat = await import_promises.default.stat(cfPath); | ||
refetch = this.clock() - cfStat.mtimeMs > CF_DAYS * DAY; | ||
@@ -156,7 +179,7 @@ } catch { | ||
try { | ||
const res = await fetch(this.cfFetchEndpoint); | ||
const res = await (0, import_undici.fetch)(this.cfFetchEndpoint); | ||
const cfText = await res.text(); | ||
this.#cf = JSON.parse(cfText); | ||
await fs.mkdir(path.dirname(cfPath), { recursive: true }); | ||
await fs.writeFile(cfPath, cfText, "utf8"); | ||
await import_promises.default.mkdir(import_path.default.dirname(cfPath), { recursive: true }); | ||
await import_promises.default.writeFile(cfPath, cfText, "utf8"); | ||
this.ctx.log.info("Updated Request cf object cache!"); | ||
@@ -174,8 +197,8 @@ } catch (e) { | ||
if (typeof https2 === "string") { | ||
const keyPath = path.join(https2, "key.pem"); | ||
const certPath = path.join(https2, "cert.pem"); | ||
const keyPath = import_path.default.join(https2, "key.pem"); | ||
const certPath = import_path.default.join(https2, "cert.pem"); | ||
let regenerate = true; | ||
try { | ||
const keyStat = await fs.stat(keyPath); | ||
const certStat = await fs.stat(certPath); | ||
const keyStat = await import_promises.default.stat(keyPath); | ||
const certStat = await import_promises.default.stat(certPath); | ||
const created = Math.max(keyStat.mtimeMs, certStat.mtimeMs); | ||
@@ -187,3 +210,3 @@ regenerate = this.clock() - created > (CERT_DAYS - 2) * DAY; | ||
this.ctx.log.info("Generating new self-signed certificate..."); | ||
const selfSigned = await import("selfsigned"); | ||
const selfSigned = require("selfsigned"); | ||
const certAttrs = [ | ||
@@ -222,6 +245,6 @@ { name: "commonName", value: "localhost" } | ||
}; | ||
const cert = await promisify(selfSigned.generate)(certAttrs, certOptions); | ||
await fs.mkdir(https2, { recursive: true }); | ||
await fs.writeFile(keyPath, cert.private, "utf8"); | ||
await fs.writeFile(certPath, cert.cert, "utf8"); | ||
const cert = await (0, import_util.promisify)(selfSigned.generate)(certAttrs, certOptions); | ||
await import_promises.default.mkdir(https2, { recursive: true }); | ||
await import_promises.default.writeFile(keyPath, cert.private, "utf8"); | ||
await import_promises.default.writeFile(certPath, cert.cert, "utf8"); | ||
} | ||
@@ -246,4 +269,4 @@ this.httpsKeyPath = keyPath; | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.STRING, | ||
alias: "H", | ||
@@ -255,4 +278,4 @@ description: "Host for HTTP(S) server to listen on", | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.NUMBER, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.NUMBER, | ||
alias: "p", | ||
@@ -264,4 +287,12 @@ description: "Port for HTTP(S) server to listen on", | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.BOOLEAN_STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.BOOLEAN_STRING, | ||
alias: "O", | ||
description: "Automatically open browser to URL", | ||
fromWrangler: ({ miniflare }) => miniflare?.open | ||
}) | ||
], HTTPPlugin.prototype, "open", 2); | ||
__decorateClass([ | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.BOOLEAN_STRING, | ||
description: "Enable self-signed HTTPS (with optional cert path)", | ||
@@ -273,7 +304,7 @@ logName: "HTTPS", | ||
__decorateClass([ | ||
Option({ type: OptionType.NONE }) | ||
(0, import_shared.Option)({ type: import_shared.OptionType.NONE }) | ||
], HTTPPlugin.prototype, "httpsKey", 2); | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.STRING, | ||
name: "https-key", | ||
@@ -286,7 +317,7 @@ description: "Path to PEM SSL key", | ||
__decorateClass([ | ||
Option({ type: OptionType.NONE }) | ||
(0, import_shared.Option)({ type: import_shared.OptionType.NONE }) | ||
], HTTPPlugin.prototype, "httpsCert", 2); | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.STRING, | ||
name: "https-cert", | ||
@@ -299,7 +330,7 @@ description: "Path to PEM SSL cert chain", | ||
__decorateClass([ | ||
Option({ type: OptionType.NONE }) | ||
(0, import_shared.Option)({ type: import_shared.OptionType.NONE }) | ||
], HTTPPlugin.prototype, "httpsCa", 2); | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.STRING, | ||
name: "https-ca", | ||
@@ -312,7 +343,7 @@ description: "Path to SSL trusted CA certs", | ||
__decorateClass([ | ||
Option({ type: OptionType.NONE }) | ||
(0, import_shared.Option)({ type: import_shared.OptionType.NONE }) | ||
], HTTPPlugin.prototype, "httpsPfx", 2); | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.STRING, | ||
name: "https-pfx", | ||
@@ -325,4 +356,4 @@ description: "Path to PFX/PKCS12 SSL key/cert chain", | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.STRING, | ||
description: "Passphrase to decrypt SSL files", | ||
@@ -335,4 +366,4 @@ logName: "HTTPS Passphrase", | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.BOOLEAN_STRING, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.BOOLEAN_STRING, | ||
description: "Path for cached Request cf object from Cloudflare", | ||
@@ -343,6 +374,6 @@ negatable: true, | ||
if (value === true) | ||
return path.relative("", defaultCfPath); | ||
return import_path.default.relative("", defaultCfPath); | ||
if (value === false) | ||
return void 0; | ||
return path.relative("", value); | ||
return import_path.default.relative("", value); | ||
}, | ||
@@ -353,7 +384,7 @@ fromWrangler: ({ miniflare }) => miniflare?.cf_fetch | ||
__decorateClass([ | ||
Option({ type: OptionType.NONE }) | ||
(0, import_shared.Option)({ type: import_shared.OptionType.NONE }) | ||
], HTTPPlugin.prototype, "metaProvider", 2); | ||
__decorateClass([ | ||
Option({ | ||
type: OptionType.BOOLEAN, | ||
(0, import_shared.Option)({ | ||
type: import_shared.OptionType.BOOLEAN, | ||
description: "Reload HTML pages whenever worker is reloaded", | ||
@@ -365,2 +396,3 @@ fromWrangler: ({ miniflare }) => miniflare?.live_reload | ||
// packages/http-server/src/index.ts | ||
var DEFAULT_PORT = 8787; | ||
var liveReloadScript = `<script defer type="application/javascript"> | ||
@@ -386,7 +418,7 @@ (function () { | ||
const origin = `${protocol}://${req.headers.host ?? "localhost"}`; | ||
const url = new URL(req.url ?? "", origin); | ||
const url = new import_url.URL(req.url ?? "", origin); | ||
let body = null; | ||
if (req.method !== "GET" && req.method !== "HEAD") { | ||
let iterator; | ||
body = new ReadableStream({ | ||
body = new import_web.ReadableStream({ | ||
type: "bytes", | ||
@@ -420,6 +452,6 @@ start() { | ||
req.headers["cf-ipcountry"] ??= meta?.cf?.country ?? "US"; | ||
req.headers["cf-ray"] ??= randomHex(16); | ||
req.headers["cf-ray"] ??= (0, import_shared2.randomHex)(16); | ||
req.headers["cf-visitor"] ??= `{"scheme":"${proto}"}`; | ||
req.headers["host"] = url.host; | ||
const headers = new Headers(); | ||
const headers = new import_undici2.Headers(); | ||
for (const [name, values] of Object.entries(req.headers)) { | ||
@@ -436,3 +468,3 @@ if (name === "transfer-encoding" || name === "connection" || name === "keep-alive" || name === "expect") { | ||
} | ||
const request = new Request(url, { | ||
const request = new import_core.Request(url, { | ||
method: req.method, | ||
@@ -486,7 +518,7 @@ headers, | ||
if (/(x-)?gzip/.test(coding)) { | ||
encoders.push(zlib.createGzip()); | ||
encoders.push(import_zlib.default.createGzip()); | ||
} else if (/(x-)?deflate/.test(coding)) { | ||
encoders.push(zlib.createDeflate()); | ||
encoders.push(import_zlib.default.createDeflate()); | ||
} else if (coding === "br") { | ||
encoders.push(zlib.createBrotliCompress()); | ||
encoders.push(import_zlib.default.createBrotliCompress()); | ||
} else { | ||
@@ -529,3 +561,3 @@ mf.log.warn(`Unknown encoding "${coding}", sending plain response...`); | ||
if (accept.includes("text/html") || accept.includes("*/*") || accept.includes("text/*")) { | ||
const { default: Youch } = await import("youch"); | ||
const Youch = require("youch"); | ||
const youch = new Youch(e, req); | ||
@@ -549,13 +581,7 @@ youch.addLink(() => { | ||
} | ||
const proxiedError = new Proxy(e, { | ||
get(target, propertyKey, receiver) { | ||
const value = Reflect.get(target, propertyKey, receiver); | ||
return propertyKey === "stack" ? `${req.method} ${req.url}: ${value}` : value; | ||
} | ||
}); | ||
mf.log.error(proxiedError); | ||
mf.log.error((0, import_shared2.prefixError)(`${req.method} ${req.url}`, e)); | ||
} | ||
} | ||
assert(req.method && req.url); | ||
await logResponse(mf.log, { | ||
(0, import_assert.default)(req.method && req.url); | ||
await (0, import_core.logResponse)(mf.log, { | ||
start, | ||
@@ -576,16 +602,15 @@ method: req.method, | ||
const httpsOptions = plugins.HTTPPlugin.httpsOptions; | ||
assert(httpsOptions); | ||
server = https.createServer({ ...httpsOptions, ...options }, listener); | ||
(0, import_assert.default)(httpsOptions); | ||
server = import_https.default.createServer({ ...httpsOptions, ...options }, listener); | ||
} else { | ||
server = http.createServer(options ?? {}, listener); | ||
server = import_http.default.createServer(options ?? {}, listener); | ||
} | ||
const ws = await import("ws"); | ||
const WebSocketServer = ws.WebSocketServer ?? ws.default.WebSocketServer; | ||
const { WebSocketServer } = require("ws"); | ||
const webSocketServer = new WebSocketServer({ noServer: true }); | ||
const liveReloadServer = new WebSocketServer({ noServer: true }); | ||
server.on("upgrade", async (request, socket, head) => { | ||
const { pathname } = new URL(request.url ?? "", "http://localhost"); | ||
const { pathname } = new import_url.URL(request.url ?? "", "http://localhost"); | ||
if (pathname === "/cdn-cgi/mf/reload") { | ||
liveReloadServer.handleUpgrade(request, socket, head, (ws2) => { | ||
liveReloadServer.emit("connection", ws2, request); | ||
liveReloadServer.handleUpgrade(request, socket, head, (ws) => { | ||
liveReloadServer.emit("connection", ws, request); | ||
}); | ||
@@ -601,5 +626,5 @@ } else { | ||
} | ||
webSocketServer.handleUpgrade(request, socket, head, (ws2) => { | ||
void coupleWebSocket(ws2, webSocket); | ||
webSocketServer.emit("connection", ws2, request); | ||
webSocketServer.handleUpgrade(request, socket, head, (ws) => { | ||
void (0, import_web_sockets.coupleWebSocket)(ws, webSocket); | ||
webSocketServer.emit("connection", ws, request); | ||
}); | ||
@@ -609,7 +634,7 @@ } | ||
const reloadListener = () => { | ||
for (const ws2 of liveReloadServer.clients) { | ||
ws2.close(1012, "Service Restart"); | ||
for (const ws of liveReloadServer.clients) { | ||
ws.close(1012, "Service Restart"); | ||
} | ||
for (const ws2 of webSocketServer.clients) { | ||
ws2.close(1012, "Service Restart"); | ||
for (const ws of webSocketServer.clients) { | ||
ws.close(1012, "Service Restart"); | ||
} | ||
@@ -624,3 +649,3 @@ }; | ||
const plugins = await mf.getPlugins(); | ||
const { httpsEnabled, host, port = 8787 } = plugins.HTTPPlugin; | ||
const { httpsEnabled, host, port = DEFAULT_PORT } = plugins.HTTPPlugin; | ||
return new Promise((resolve) => { | ||
@@ -639,3 +664,5 @@ server.listen(port, host, () => { | ||
} | ||
export { | ||
// Annotate the CommonJS export names for ESM import in node: | ||
0 && (module.exports = { | ||
DEFAULT_PORT, | ||
HTTPPlugin, | ||
@@ -647,3 +674,3 @@ convertNodeRequest, | ||
startServer | ||
}; | ||
}); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@miniflare/http-server", | ||
"version": "2.0.0-rc.3", | ||
"version": "2.0.0-rc.4", | ||
"description": "HTTP server module for Miniflare: a fun, full-featured, fully-local simulator for Cloudflare Workers", | ||
@@ -14,4 +14,3 @@ "keywords": [ | ||
"license": "MIT", | ||
"type": "module", | ||
"exports": "./dist/src/index.js", | ||
"main": "./dist/src/index.js", | ||
"types": "./dist/src/index.d.ts", | ||
@@ -40,5 +39,5 @@ "files": [ | ||
"dependencies": { | ||
"@miniflare/core": "2.0.0-rc.3", | ||
"@miniflare/shared": "2.0.0-rc.3", | ||
"@miniflare/web-sockets": "2.0.0-rc.3", | ||
"@miniflare/core": "2.0.0-rc.4", | ||
"@miniflare/shared": "2.0.0-rc.4", | ||
"@miniflare/web-sockets": "2.0.0-rc.4", | ||
"kleur": "^4.1.4", | ||
@@ -51,5 +50,5 @@ "selfsigned": "^1.10.11", | ||
"devDependencies": { | ||
"@miniflare/shared-test": "2.0.0-rc.3", | ||
"@miniflare/shared-test": "2.0.0-rc.4", | ||
"@types/node-forge": "^0.10.4" | ||
} | ||
} |
@@ -5,3 +5,3 @@ # `@miniflare/http-server` | ||
fun, full-featured, fully-local simulator for Cloudflare Workers. See | ||
[🧰 Using the API](https://miniflare.dev/api.html) for more details. | ||
[🧰 Using the API](https://v2.miniflare.dev/get-started/api) for more details. | ||
@@ -8,0 +8,0 @@ ## Example |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
41703
736
2
No
+ Added@miniflare/core@2.0.0-rc.4(transitive)
+ Added@miniflare/shared@2.0.0-rc.4(transitive)
+ Added@miniflare/web-sockets@2.0.0-rc.4(transitive)
- Removed@miniflare/core@2.0.0-rc.3(transitive)
- Removed@miniflare/shared@2.0.0-rc.3(transitive)
- Removed@miniflare/web-sockets@2.0.0-rc.3(transitive)
Updated@miniflare/core@2.0.0-rc.4
Updated@miniflare/shared@2.0.0-rc.4