webpack-dev-middleware
Advanced tools
Comparing version 7.2.1 to 7.3.0
@@ -50,5 +50,4 @@ "use strict"; | ||
// TODO fix me after the next webpack release | ||
/** | ||
* @typedef {Object & { createReadStream?: import("fs").createReadStream, statSync?: import("fs").statSync, lstat?: import("fs").lstat, readFileSync?: import("fs").readFileSync }} OutputFileSystem | ||
* @typedef {import("webpack").OutputFileSystem & { createReadStream?: import("fs").createReadStream, statSync: import("fs").statSync, readFileSync: import("fs").readFileSync }} OutputFileSystem | ||
*/ | ||
@@ -254,8 +253,8 @@ | ||
if (Array.isArray( /** @type {MultiCompiler} */context.compiler.compilers)) { | ||
const compiler = /** @type {MultiCompiler} */context.compiler; | ||
const watchOptions = compiler.compilers.map(childCompiler => childCompiler.options.watchOptions || {}); | ||
const c = /** @type {MultiCompiler} */context.compiler; | ||
const watchOptions = c.compilers.map(childCompiler => childCompiler.options.watchOptions || {}); | ||
context.watching = compiler.watch(watchOptions, errorHandler); | ||
} else { | ||
const compiler = /** @type {Compiler} */context.compiler; | ||
const watchOptions = compiler.options.watchOptions || {}; | ||
const c = /** @type {Compiler} */context.compiler; | ||
const watchOptions = c.options.watchOptions || {}; | ||
context.watching = compiler.watch(watchOptions, errorHandler); | ||
@@ -326,2 +325,21 @@ } | ||
server.ext("onRequest", (request, h) => new Promise((resolve, reject) => { | ||
let isFinished = false; | ||
/** | ||
* @param {string | Buffer} [data] | ||
*/ | ||
// eslint-disable-next-line no-param-reassign | ||
request.raw.res.send = data => { | ||
isFinished = true; | ||
request.raw.res.end(data); | ||
}; | ||
/** | ||
* @param {string | Buffer} [data] | ||
*/ | ||
// eslint-disable-next-line no-param-reassign | ||
request.raw.res.finish = data => { | ||
isFinished = true; | ||
request.raw.res.end(data); | ||
}; | ||
devMiddleware(request.raw.req, request.raw.res, error => { | ||
@@ -332,3 +350,5 @@ if (error) { | ||
} | ||
resolve(request); | ||
if (!isFinished) { | ||
resolve(request); | ||
} | ||
}); | ||
@@ -354,53 +374,221 @@ }).then(() => h.continue).catch(error => { | ||
/** | ||
* @param {{ req: RequestInternal, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedResponse, status: number, body: Buffer | import("fs").ReadStream | { message: string }, state: Object }} ctx | ||
* @param {{ req: RequestInternal, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse, status: number, body: string | Buffer | import("fs").ReadStream | { message: string }, state: Object }} ctx | ||
* @param {Function} next | ||
* @returns {Promise<void>} | ||
*/ | ||
const wrapper = async function webpackDevMiddleware(ctx, next) { | ||
return new Promise((resolve, reject) => { | ||
const { | ||
req | ||
} = ctx; | ||
const { | ||
res | ||
} = ctx; | ||
res.locals = ctx.state; | ||
const { | ||
req, | ||
res | ||
} = ctx; | ||
res.locals = ctx.state; | ||
let { | ||
status | ||
} = ctx; | ||
/** | ||
* @returns {number} code | ||
*/ | ||
res.getStatusCode = () => status; | ||
/** | ||
* @param {number} statusCode status code | ||
*/ | ||
res.setStatusCode = statusCode => { | ||
status = statusCode; | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.status = statusCode; | ||
}; | ||
res.getReadyReadableStreamState = () => "open"; | ||
try { | ||
await new Promise( | ||
/** | ||
* @param {number} status status code | ||
* @param {(value: void) => void} resolve | ||
* @param {(reason?: any) => void} reject | ||
*/ | ||
res.status = status => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.status = status; | ||
(resolve, reject) => { | ||
/** | ||
* @param {import("fs").ReadStream} stream readable stream | ||
*/ | ||
res.stream = stream => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.body = stream; | ||
}; | ||
/** | ||
* @param {string | Buffer} data data | ||
*/ | ||
res.send = data => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.body = data; | ||
}; | ||
/** | ||
* @param {string | Buffer} [data] data | ||
*/ | ||
res.finish = data => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.status = status; | ||
res.end(data); | ||
}; | ||
devMiddleware(req, res, err => { | ||
if (err) { | ||
reject(err); | ||
return; | ||
} | ||
resolve(); | ||
}); | ||
}); | ||
} catch (err) { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.status = /** @type {Error & { statusCode: number }} */err.statusCode || /** @type {Error & { status: number }} */err.status || 500; | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.body = { | ||
message: /** @type {Error} */err.message | ||
}; | ||
} | ||
await next(); | ||
}; | ||
wrapper.devMiddleware = devMiddleware; | ||
return wrapper; | ||
} | ||
wdm.koaWrapper = koaWrapper; | ||
/** | ||
* @template {IncomingMessage} [RequestInternal=IncomingMessage] | ||
* @template {ServerResponse} [ResponseInternal=ServerResponse] | ||
* @param {Compiler | MultiCompiler} compiler | ||
* @param {Options<RequestInternal, ResponseInternal>} [options] | ||
* @returns {(ctx: any, next: Function) => Promise<void> | void} | ||
*/ | ||
function honoWrapper(compiler, options) { | ||
const devMiddleware = wdm(compiler, options); | ||
/** | ||
* @param {{ env: any, body: any, json: any, status: any, set:any, req: RequestInternal & import("./utils/compatibleAPI").ExpectedIncomingMessage & { header: (name: string) => string }, res: ResponseInternal & import("./utils/compatibleAPI").ExpectedServerResponse & { headers: any, status: any } }} c | ||
* @param {Function} next | ||
* @returns {Promise<void>} | ||
*/ | ||
// eslint-disable-next-line consistent-return | ||
const wrapper = async function webpackDevMiddleware(c, next) { | ||
const { | ||
req, | ||
res | ||
} = c; | ||
c.set("webpack", { | ||
devMiddleware: devMiddleware.context | ||
}); | ||
/** | ||
* @returns {string | undefined} | ||
*/ | ||
req.getMethod = () => c.req.method; | ||
/** | ||
* @param {string} name | ||
* @returns {string | string[] | undefined} | ||
*/ | ||
req.getHeader = name => c.req.header(name); | ||
/** | ||
* @returns {string | undefined} | ||
*/ | ||
req.getURL = () => c.req.url; | ||
let { | ||
status | ||
} = c.res; | ||
/** | ||
* @returns {number} code | ||
*/ | ||
res.getStatusCode = () => status; | ||
/** | ||
* @param {number} code | ||
*/ | ||
res.setStatusCode = code => { | ||
status = code; | ||
}; | ||
/** | ||
* @param {string} name header name | ||
*/ | ||
res.getHeader = name => c.res.headers.get(name); | ||
/** | ||
* @param {string} name | ||
* @param {string | number | Readonly<string[]>} value | ||
*/ | ||
res.setHeader = (name, value) => { | ||
c.res.headers.append(name, value); | ||
return c.res; | ||
}; | ||
/** | ||
* @param {string} name | ||
*/ | ||
res.removeHeader = name => { | ||
c.res.headers.delete(name); | ||
}; | ||
/** | ||
* @returns {string[]} | ||
*/ | ||
res.getResponseHeaders = () => Array.from(c.res.headers.keys()); | ||
/** | ||
* @returns {ServerResponse} | ||
*/ | ||
res.getOutgoing = () => c.env.outgoing; | ||
res.setState = () => { | ||
// Do nothing, because we set it before | ||
}; | ||
res.getReadyReadableStreamState = () => "readable"; | ||
let body; | ||
try { | ||
await new Promise( | ||
/** | ||
* @param {import("fs").ReadStream} stream readable stream | ||
* @param {(value: void) => void} resolve | ||
* @param {(reason?: any) => void} reject | ||
*/ | ||
res.pipeInto = stream => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.body = stream; | ||
resolve(); | ||
}; | ||
/** | ||
* @param {Buffer} content content | ||
*/ | ||
res.send = content => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.body = content; | ||
resolve(); | ||
}; | ||
devMiddleware(req, res, err => { | ||
if (err) { | ||
reject(err); | ||
return; | ||
} | ||
resolve(next()); | ||
}).catch(err => { | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.status = err.statusCode || err.status || 500; | ||
// eslint-disable-next-line no-param-reassign | ||
ctx.body = { | ||
message: err.message | ||
(resolve, reject) => { | ||
/** | ||
* @param {import("fs").ReadStream} stream readable stream | ||
*/ | ||
res.stream = stream => { | ||
body = stream; | ||
// responseHandler(stream); | ||
}; | ||
/** | ||
* @param {string | Buffer} data data | ||
*/ | ||
res.send = data => { | ||
body = data; | ||
}; | ||
/** | ||
* @param {string | Buffer} [data] data | ||
*/ | ||
res.finish = data => { | ||
body = typeof data !== "undefined" ? data : null; | ||
}; | ||
devMiddleware(req, res, err => { | ||
if (err) { | ||
reject(err); | ||
return; | ||
} | ||
resolve(); | ||
}); | ||
}); | ||
}); | ||
} catch (err) { | ||
c.status(500); | ||
return c.json({ | ||
message: /** @type {Error} */err.message | ||
}); | ||
} | ||
if (typeof body !== "undefined") { | ||
return c.body(body, status); | ||
} | ||
await next(); | ||
}; | ||
@@ -410,3 +598,3 @@ wrapper.devMiddleware = devMiddleware; | ||
} | ||
wdm.koaWrapper = koaWrapper; | ||
wdm.honoWrapper = honoWrapper; | ||
module.exports = wdm; |
@@ -9,5 +9,18 @@ "use strict"; | ||
setStatusCode, | ||
getStatusCode, | ||
getRequestHeader, | ||
getRequestMethod, | ||
getRequestURL, | ||
getResponseHeader, | ||
setResponseHeader, | ||
removeResponseHeader, | ||
getResponseHeaders, | ||
send, | ||
finish, | ||
pipe, | ||
createReadStreamOrReadFileSync | ||
createReadStreamOrReadFileSync, | ||
getOutgoing, | ||
initState, | ||
setState, | ||
getReadyReadableStreamState | ||
} = require("./utils/compatibleAPI"); | ||
@@ -118,6 +131,3 @@ const ready = require("./utils/ready"); | ||
const acceptedMethods = context.options.methods || ["GET", "HEAD"]; | ||
// fixes #282. credit @cexoso. in certain edge situations res.locals is undefined. | ||
// eslint-disable-next-line no-param-reassign | ||
res.locals = res.locals || {}; | ||
initState(res); | ||
async function goNext() { | ||
@@ -129,7 +139,5 @@ if (!context.options.serverSideRender) { | ||
ready(context, () => { | ||
/** @type {any} */ | ||
// eslint-disable-next-line no-param-reassign | ||
res.locals.webpack = { | ||
setState(res, "webpack", { | ||
devMiddleware: context | ||
}; | ||
}); | ||
resolve(next()); | ||
@@ -139,3 +147,4 @@ }, req); | ||
} | ||
if (req.method && !acceptedMethods.includes(req.method)) { | ||
const method = getRequestMethod(req); | ||
if (method && !acceptedMethods.includes(method)) { | ||
await goNext(); | ||
@@ -166,5 +175,5 @@ return; | ||
// Clear existing headers | ||
const headers = res.getHeaderNames(); | ||
const headers = getResponseHeaders(res); | ||
for (let i = 0; i < headers.length; i++) { | ||
res.removeHeader(headers[i]); | ||
removeResponseHeader(res, headers[i]); | ||
} | ||
@@ -177,3 +186,3 @@ if (options && options.headers) { | ||
if (typeof value !== "undefined") { | ||
res.setHeader(key, value); | ||
setResponseHeader(res, key, value); | ||
} | ||
@@ -185,5 +194,5 @@ } | ||
setStatusCode(res, status); | ||
res.setHeader("Content-Type", "text/html; charset=utf-8"); | ||
res.setHeader("Content-Security-Policy", "default-src 'none'"); | ||
res.setHeader("X-Content-Type-Options", "nosniff"); | ||
setResponseHeader(res, "Content-Type", "text/html; charset=utf-8"); | ||
setResponseHeader(res, "Content-Security-Policy", "default-src 'none'"); | ||
setResponseHeader(res, "X-Content-Type-Options", "nosniff"); | ||
let byteLength = Buffer.byteLength(document); | ||
@@ -197,11 +206,31 @@ if (options && options.modifyResponseData) { | ||
} | ||
res.setHeader("Content-Length", byteLength); | ||
res.end(document); | ||
setResponseHeader(res, "Content-Length", byteLength); | ||
finish(res, document); | ||
} | ||
/** | ||
* @param {NodeJS.ErrnoException} error | ||
*/ | ||
function errorHandler(error) { | ||
switch (error.code) { | ||
case "ENAMETOOLONG": | ||
case "ENOENT": | ||
case "ENOTDIR": | ||
sendError(404, { | ||
modifyResponseData: context.options.modifyResponseData | ||
}); | ||
break; | ||
default: | ||
sendError(500, { | ||
modifyResponseData: context.options.modifyResponseData | ||
}); | ||
break; | ||
} | ||
} | ||
function isConditionalGET() { | ||
return req.headers["if-match"] || req.headers["if-unmodified-since"] || req.headers["if-none-match"] || req.headers["if-modified-since"]; | ||
return getRequestHeader(req, "if-match") || getRequestHeader(req, "if-unmodified-since") || getRequestHeader(req, "if-none-match") || getRequestHeader(req, "if-modified-since"); | ||
} | ||
function isPreconditionFailure() { | ||
// if-match | ||
const ifMatch = req.headers["if-match"]; | ||
const ifMatch = /** @type {string} */getRequestHeader(req, "if-match"); | ||
@@ -214,3 +243,3 @@ // A recipient MUST ignore If-Unmodified-Since if the request contains | ||
if (ifMatch) { | ||
const etag = res.getHeader("ETag"); | ||
const etag = getResponseHeader(res, "ETag"); | ||
return !etag || ifMatch !== "*" && parseTokenList(ifMatch).every(match => match !== etag && match !== `W/${etag}` && `W/${match}` !== etag); | ||
@@ -220,3 +249,4 @@ } | ||
// if-unmodified-since | ||
const ifUnmodifiedSince = req.headers["if-unmodified-since"]; | ||
const ifUnmodifiedSince = /** @type {string} */ | ||
getRequestHeader(req, "if-unmodified-since"); | ||
if (ifUnmodifiedSince) { | ||
@@ -228,3 +258,3 @@ const unmodifiedSince = parseHttpDate(ifUnmodifiedSince); | ||
if (!isNaN(unmodifiedSince)) { | ||
const lastModified = parseHttpDate( /** @type {string} */res.getHeader("Last-Modified")); | ||
const lastModified = parseHttpDate( /** @type {string} */getResponseHeader(res, "Last-Modified")); | ||
return isNaN(lastModified) || lastModified > unmodifiedSince; | ||
@@ -240,3 +270,6 @@ } | ||
function isCachable() { | ||
return res.statusCode >= 200 && res.statusCode < 300 || res.statusCode === 304; | ||
const statusCode = getStatusCode(res); | ||
return statusCode >= 200 && statusCode < 300 || statusCode === 304 || | ||
// For Koa and Hono, because by default status code is 404, but we already found a file | ||
statusCode === 404; | ||
} | ||
@@ -251,3 +284,4 @@ | ||
// https://tools.ietf.org/html/rfc2616#section-14.9.4 | ||
const cacheControl = req.headers["cache-control"]; | ||
const cacheControl = /** @type {string} */ | ||
getRequestHeader(req, "cache-control"); | ||
if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) { | ||
@@ -258,4 +292,6 @@ return false; | ||
// fields | ||
const noneMatch = req.headers["if-none-match"]; | ||
const modifiedSince = req.headers["if-modified-since"]; | ||
const noneMatch = /** @type {string} */ | ||
getRequestHeader(req, "if-none-match"); | ||
const modifiedSince = /** @type {string} */ | ||
getRequestHeader(req, "if-modified-since"); | ||
@@ -309,3 +345,3 @@ // unconditional request | ||
const ifRange = /** @type {string | undefined} */ | ||
req.headers["if-range"]; | ||
getRequestHeader(req, "if-range"); | ||
if (!ifRange) { | ||
@@ -317,3 +353,4 @@ return true; | ||
if (ifRange.indexOf('"') !== -1) { | ||
const etag = /** @type {string | undefined} */res.getHeader("ETag"); | ||
const etag = /** @type {string | undefined} */ | ||
getResponseHeader(res, "ETag"); | ||
if (!etag) { | ||
@@ -327,3 +364,3 @@ return true; | ||
const lastModified = /** @type {string | undefined} */ | ||
res.getHeader("Last-Modified"); | ||
getResponseHeader(res, "Last-Modified"); | ||
if (!lastModified) { | ||
@@ -339,5 +376,5 @@ return true; | ||
function getRangeHeader() { | ||
const rage = req.headers.range; | ||
if (rage && BYTES_RANGE_REGEXP.test(rage)) { | ||
return rage; | ||
const range = /** @type {string} */getRequestHeader(req, "range"); | ||
if (range && BYTES_RANGE_REGEXP.test(range)) { | ||
return range; | ||
} | ||
@@ -373,3 +410,3 @@ | ||
const extra = {}; | ||
const filename = getFilenameFromUrl(context, /** @type {string} */req.url, extra); | ||
const filename = getFilenameFromUrl(context, /** @type {string} */getRequestURL(req), extra); | ||
if (extra.errorCode) { | ||
@@ -382,2 +419,3 @@ if (extra.errorCode === 403) { | ||
}); | ||
await goNext(); | ||
return; | ||
@@ -419,6 +457,7 @@ } | ||
headers.forEach(header => { | ||
res.setHeader(header.key, header.value); | ||
setResponseHeader(res, header.key, header.value); | ||
}); | ||
} | ||
if (!res.getHeader("Content-Type")) { | ||
if (!getResponseHeader(res, "Content-Type") || getStatusCode(res) === 404) { | ||
removeResponseHeader(res, "Content-Type"); | ||
// content-type name(like application/javascript; charset=utf-8) or false | ||
@@ -430,14 +469,14 @@ const contentType = mime.contentType(path.extname(filename)); | ||
if (contentType) { | ||
res.setHeader("Content-Type", contentType); | ||
setResponseHeader(res, "Content-Type", contentType); | ||
} else if (context.options.mimeTypeDefault) { | ||
res.setHeader("Content-Type", context.options.mimeTypeDefault); | ||
setResponseHeader(res, "Content-Type", context.options.mimeTypeDefault); | ||
} | ||
} | ||
if (!res.getHeader("Accept-Ranges")) { | ||
res.setHeader("Accept-Ranges", "bytes"); | ||
if (!getResponseHeader(res, "Accept-Ranges")) { | ||
setResponseHeader(res, "Accept-Ranges", "bytes"); | ||
} | ||
if (context.options.lastModified && !res.getHeader("Last-Modified")) { | ||
if (context.options.lastModified && !getResponseHeader(res, "Last-Modified")) { | ||
const modified = /** @type {import("fs").Stats} */ | ||
extra.stats.mtime.toUTCString(); | ||
res.setHeader("Last-Modified", modified); | ||
setResponseHeader(res, "Last-Modified", modified); | ||
} | ||
@@ -455,3 +494,3 @@ | ||
const rangeHeader = getRangeHeader(); | ||
if (context.options.etag && !res.getHeader("ETag")) { | ||
if (context.options.etag && !getResponseHeader(res, "ETag")) { | ||
/** @type {import("fs").Stats | Buffer | ReadStream | undefined} */ | ||
@@ -479,4 +518,6 @@ let value; | ||
} = result); | ||
} catch (_err) { | ||
// Ignore here | ||
} catch (error) { | ||
errorHandler( /** @type {NodeJS.ErrnoException} */error); | ||
await goNext(); | ||
return; | ||
} | ||
@@ -492,3 +533,3 @@ } | ||
} | ||
res.setHeader("ETag", result.hash); | ||
setResponseHeader(res, "ETag", result.hash); | ||
} | ||
@@ -503,13 +544,10 @@ } | ||
}); | ||
await goNext(); | ||
return; | ||
} | ||
// For Koa | ||
if (res.statusCode === 404) { | ||
setStatusCode(res, 200); | ||
} | ||
if (isCachable() && isFresh({ | ||
etag: ( /** @type {string | undefined} */res.getHeader("ETag")), | ||
etag: ( /** @type {string | undefined} */ | ||
getResponseHeader(res, "ETag")), | ||
"last-modified": ( /** @type {string | undefined} */ | ||
res.getHeader("Last-Modified")) | ||
getResponseHeader(res, "Last-Modified")) | ||
})) { | ||
@@ -519,11 +557,13 @@ setStatusCode(res, 304); | ||
// Remove content header fields | ||
res.removeHeader("Content-Encoding"); | ||
res.removeHeader("Content-Language"); | ||
res.removeHeader("Content-Length"); | ||
res.removeHeader("Content-Range"); | ||
res.removeHeader("Content-Type"); | ||
res.end(); | ||
removeResponseHeader(res, "Content-Encoding"); | ||
removeResponseHeader(res, "Content-Language"); | ||
removeResponseHeader(res, "Content-Length"); | ||
removeResponseHeader(res, "Content-Range"); | ||
removeResponseHeader(res, "Content-Type"); | ||
finish(res); | ||
await goNext(); | ||
return; | ||
} | ||
} | ||
let isPartialContent = false; | ||
if (rangeHeader) { | ||
@@ -539,9 +579,10 @@ let parsedRanges = /** @type {import("range-parser").Ranges | import("range-parser").Result | []} */ | ||
context.logger.error("Unsatisfiable range for 'Range' header."); | ||
res.setHeader("Content-Range", getValueContentRangeHeader("bytes", size)); | ||
setResponseHeader(res, "Content-Range", getValueContentRangeHeader("bytes", size)); | ||
sendError(416, { | ||
headers: { | ||
"Content-Range": res.getHeader("Content-Range") | ||
"Content-Range": getResponseHeader(res, "Content-Range") | ||
}, | ||
modifyResponseData: context.options.modifyResponseData | ||
}); | ||
await goNext(); | ||
return; | ||
@@ -556,3 +597,4 @@ } else if (parsedRanges === -2) { | ||
setStatusCode(res, 206); | ||
res.setHeader("Content-Range", getValueContentRangeHeader("bytes", size, /** @type {import("range-parser").Ranges} */parsedRanges[0])); | ||
setResponseHeader(res, "Content-Range", getValueContentRangeHeader("bytes", size, /** @type {import("range-parser").Ranges} */parsedRanges[0])); | ||
isPartialContent = true; | ||
[offset, len] = getOffsetAndLenFromRange(parsedRanges[0]); | ||
@@ -570,3 +612,4 @@ } | ||
} = createReadStreamOrReadFileSync(filename, context.outputFileSystem, start, end)); | ||
} catch (_ignoreError) { | ||
} catch (error) { | ||
errorHandler( /** @type {NodeJS.ErrnoException} */error); | ||
await goNext(); | ||
@@ -586,14 +629,18 @@ return; | ||
// @ts-ignore | ||
res.setHeader("Content-Length", byteLength); | ||
if (req.method === "HEAD") { | ||
// For Koa | ||
if (res.statusCode === 404) { | ||
setResponseHeader(res, "Content-Length", byteLength); | ||
if (method === "HEAD") { | ||
if (!isPartialContent) { | ||
setStatusCode(res, 200); | ||
} | ||
res.end(); | ||
finish(res); | ||
await goNext(); | ||
return; | ||
} | ||
if (!isPartialContent) { | ||
setStatusCode(res, 200); | ||
} | ||
const isPipeSupports = typeof ( /** @type {import("fs").ReadStream} */bufferOrStream.pipe) === "function"; | ||
if (!isPipeSupports) { | ||
send(res, /** @type {Buffer} */bufferOrStream); | ||
await goNext(); | ||
return; | ||
@@ -612,23 +659,13 @@ } | ||
cleanup(); | ||
// Handle Error | ||
switch ( /** @type {NodeJS.ErrnoException} */error.code) { | ||
case "ENAMETOOLONG": | ||
case "ENOENT": | ||
case "ENOTDIR": | ||
sendError(404, { | ||
modifyResponseData: context.options.modifyResponseData | ||
}); | ||
break; | ||
default: | ||
sendError(500, { | ||
modifyResponseData: context.options.modifyResponseData | ||
}); | ||
break; | ||
} | ||
errorHandler(error); | ||
goNext(); | ||
}).on(getReadyReadableStreamState(res), () => { | ||
goNext(); | ||
}); | ||
pipe(res, /** @type {ReadStream} */bufferOrStream); | ||
// Response finished, cleanup | ||
onFinishedStream(res, cleanup); | ||
const outgoing = getOutgoing(res); | ||
if (outgoing) { | ||
// Response finished, cleanup | ||
onFinishedStream(outgoing, cleanup); | ||
} | ||
} | ||
@@ -635,0 +672,0 @@ ready(context, processRequest, req); |
@@ -5,12 +5,69 @@ "use strict"; | ||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */ | ||
/** @typedef {import("../index").OutputFileSystem} OutputFileSystem */ | ||
/** | ||
* @typedef {Object} ExpectedResponse | ||
* @property {(status: number) => void} [status] | ||
* @property {(data: any) => void} [send] | ||
* @property {(data: any) => void} [pipeInto] | ||
* @typedef {Object} ExpectedIncomingMessage | ||
* @property {(name: string) => string | string[] | undefined} [getHeader] | ||
* @property {() => string | undefined} [getMethod] | ||
* @property {() => string | undefined} [getURL] | ||
*/ | ||
/** | ||
* @template {ServerResponse & ExpectedResponse} Response | ||
* @typedef {Object} ExpectedServerResponse | ||
* @property {(status: number) => void} [setStatusCode] | ||
* @property {() => number} [getStatusCode] | ||
* @property {(name: string) => string | string[] | undefined | number} [getHeader] | ||
* @property {(name: string, value: number | string | Readonly<string[]>) => ExpectedServerResponse} [setHeader] | ||
* @property {(name: string) => void} [removeHeader] | ||
* @property {(data: string | Buffer) => void} [send] | ||
* @property {(data?: string | Buffer) => void} [finish] | ||
* @property {() => string[]} [getResponseHeaders] | ||
* @property {(data: any) => void} [stream] | ||
* @property {() => any} [getOutgoing] | ||
* @property {(name: string, value: any) => void} [setState] | ||
* @property {() => "ready" | "open" | "readable"} [getReadyReadableStreamState] | ||
*/ | ||
/** | ||
* @template {IncomingMessage & ExpectedIncomingMessage} Request | ||
* @param {Request} req | ||
* @param {string} name | ||
* @returns {string | string[] | undefined} | ||
*/ | ||
function getRequestHeader(req, name) { | ||
// Pseudo API | ||
if (typeof req.getHeader === "function") { | ||
return req.getHeader(name); | ||
} | ||
return req.headers[name]; | ||
} | ||
/** | ||
* @template {IncomingMessage & ExpectedIncomingMessage} Request | ||
* @param {Request} req | ||
* @returns {string | undefined} | ||
*/ | ||
function getRequestMethod(req) { | ||
// Pseudo API | ||
if (typeof req.getMethod === "function") { | ||
return req.getMethod(); | ||
} | ||
return req.method; | ||
} | ||
/** | ||
* @template {IncomingMessage & ExpectedIncomingMessage} Request | ||
* @param {Request} req | ||
* @returns {string | undefined} | ||
*/ | ||
function getRequestURL(req) { | ||
// Pseudo API | ||
if (typeof req.getURL === "function") { | ||
return req.getURL(); | ||
} | ||
return req.url; | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
@@ -21,4 +78,4 @@ * @param {number} code | ||
// Pseudo API | ||
if (typeof res.status === "function") { | ||
res.status(code); | ||
if (typeof res.setStatusCode === "function") { | ||
res.setStatusCode(code); | ||
return; | ||
@@ -33,4 +90,63 @@ } | ||
/** | ||
* @template {ServerResponse} Response | ||
* @param {Response & ExpectedResponse} res | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {number} | ||
*/ | ||
function getStatusCode(res) { | ||
// Pseudo API | ||
if (typeof res.getStatusCode === "function") { | ||
return res.getStatusCode(); | ||
} | ||
return res.statusCode; | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
* @returns {string | string[] | undefined | number} | ||
*/ | ||
function getResponseHeader(res, name) { | ||
// Real and Pseudo API | ||
return res.getHeader(name); | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
* @param {number | string | Readonly<string[]>} value | ||
* @returns {Response} | ||
*/ | ||
function setResponseHeader(res, name, value) { | ||
// Real and Pseudo API | ||
return res.setHeader(name, value); | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
*/ | ||
function removeResponseHeader(res, name) { | ||
// Real and Pseudo API | ||
res.removeHeader(name); | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {string[]} | ||
*/ | ||
function getResponseHeaders(res) { | ||
// Pseudo API | ||
if (typeof res.getResponseHeaders === "function") { | ||
return res.getResponseHeaders(); | ||
} | ||
return res.getHeaderNames(); | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {import("fs").ReadStream} bufferOrStream | ||
@@ -40,5 +156,5 @@ */ | ||
// Pseudo API and Koa API | ||
if (typeof ( /** @type {Response & ExpectedResponse} */res.pipeInto) === "function") { | ||
if (typeof res.stream === "function") { | ||
// Writable stream into Readable stream | ||
res.pipeInto(bufferOrStream); | ||
res.stream(bufferOrStream); | ||
return; | ||
@@ -52,19 +168,34 @@ } | ||
/** | ||
* @template {IncomingMessage} Request | ||
* @template {ServerResponse} Response | ||
* @param {Response & ExpectedResponse} res | ||
* @param {string | Buffer} bufferOrStream | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string | Buffer} bufferOrString | ||
*/ | ||
function send(res, bufferOrStream) { | ||
function send(res, bufferOrString) { | ||
// Pseudo API and Express API and Koa API | ||
if (typeof res.send === "function") { | ||
res.send(bufferOrStream); | ||
res.send(bufferOrString); | ||
return; | ||
} | ||
res.end(bufferOrStream); | ||
res.end(bufferOrString); | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string | Buffer} [data] | ||
*/ | ||
function finish(res, data) { | ||
// Pseudo API and Express API and Koa API | ||
if (typeof res.finish === "function") { | ||
res.finish(data); | ||
return; | ||
} | ||
// Pseudo API and Express API and Koa API | ||
res.end(data); | ||
} | ||
/** | ||
* @param {string} filename | ||
* @param {import("../index").OutputFileSystem} outputFileSystem | ||
* @param {OutputFileSystem} outputFileSystem | ||
* @param {number} start | ||
@@ -92,4 +223,3 @@ * @param {number} end | ||
} else { | ||
bufferOrStream = /** @type {import("fs").readFileSync} */ | ||
outputFileSystem.readFileSync(filename); | ||
bufferOrStream = outputFileSystem.readFileSync(filename); | ||
({ | ||
@@ -104,7 +234,77 @@ byteLength | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {Response} res | ||
*/ | ||
function getOutgoing(res) { | ||
// Pseudo API and Express API and Koa API | ||
if (typeof res.getOutgoing === "function") { | ||
return res.getOutgoing(); | ||
} | ||
return res; | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
*/ | ||
function initState(res) { | ||
if (typeof res.setState === "function") { | ||
return; | ||
} | ||
// fixes #282. credit @cexoso. in certain edge situations res.locals is undefined. | ||
// eslint-disable-next-line no-param-reassign | ||
res.locals = res.locals || {}; | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
* @param {any} value | ||
*/ | ||
function setState(res, name, value) { | ||
if (typeof res.setState === "function") { | ||
res.setState(name, value); | ||
return; | ||
} | ||
/** @type {any} */ | ||
// eslint-disable-next-line no-param-reassign | ||
res.locals[name] = value; | ||
} | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {"ready" | "open" | "readable"} | ||
*/ | ||
function getReadyReadableStreamState(res) { | ||
// Pseudo API and Express API and Koa API | ||
if (typeof res.getReadyReadableStreamState === "function") { | ||
return res.getReadyReadableStreamState(); | ||
} | ||
return "ready"; | ||
} | ||
module.exports = { | ||
setStatusCode, | ||
getStatusCode, | ||
getRequestHeader, | ||
getRequestMethod, | ||
getRequestURL, | ||
getResponseHeader, | ||
setResponseHeader, | ||
removeResponseHeader, | ||
getResponseHeaders, | ||
pipe, | ||
send, | ||
pipe, | ||
createReadStreamOrReadFileSync | ||
finish, | ||
createReadStreamOrReadFileSync, | ||
getOutgoing, | ||
initState, | ||
setState, | ||
getReadyReadableStreamState | ||
}; |
@@ -111,4 +111,3 @@ "use strict"; | ||
// eslint-disable-next-line no-param-reassign | ||
extra.stats = /** @type {import("fs").statSync} */ | ||
context.outputFileSystem.statSync(filename); | ||
extra.stats = context.outputFileSystem.statSync(filename); | ||
} catch (_ignoreError) { | ||
@@ -125,4 +124,4 @@ // eslint-disable-next-line no-continue | ||
try { | ||
extra.stats = /** @type {import("fs").statSync} */ | ||
context.outputFileSystem.statSync(filename); | ||
// eslint-disable-next-line no-param-reassign | ||
extra.stats = context.outputFileSystem.statSync(filename); | ||
} catch (__ignoreError) { | ||
@@ -129,0 +128,0 @@ // eslint-disable-next-line no-continue |
{ | ||
"name": "webpack-dev-middleware", | ||
"version": "7.2.1", | ||
"version": "7.3.0", | ||
"description": "A development middleware for webpack", | ||
@@ -71,2 +71,3 @@ "license": "MIT", | ||
"@hapi/hapi": "^21.3.7", | ||
"@hono/node-server": "^1.12.0", | ||
"@types/connect": "^3.4.35", | ||
@@ -93,2 +94,4 @@ "@types/express": "^4.17.13", | ||
"file-loader": "^6.2.0", | ||
"finalhandler": "^1.2.0", | ||
"hono": "^4.4.13", | ||
"husky": "^9.0.10", | ||
@@ -101,2 +104,3 @@ "jest": "^29.3.1", | ||
"prettier": "^3.2.4", | ||
"router": "^1.3.8", | ||
"standard-version": "^9.3.0", | ||
@@ -106,3 +110,3 @@ "strip-ansi": "^6.0.0", | ||
"typescript": "^5.3.3", | ||
"webpack": "^5.90.3" | ||
"webpack": "^5.93.0" | ||
}, | ||
@@ -109,0 +113,0 @@ "keywords": [ |
@@ -578,2 +578,27 @@ <div align="center"> | ||
### Router | ||
```js | ||
const http = require("http"); | ||
const Router = require("router"); | ||
const finalhandler = require("finalhandler"); | ||
const webpack = require("webpack"); | ||
const webpackConfig = require("./webpack.config.js"); | ||
const devMiddleware = require("webpack-dev-middleware"); | ||
const compiler = webpack(webpackConfig); | ||
const devMiddlewareOptions = { | ||
/** Your webpack-dev-middleware-options */ | ||
}; | ||
const router = Router(); | ||
router.use(devMiddleware(compiler, devMiddlewareOptions)); | ||
var server = http.createServer((req, res) => { | ||
router(req, res, finalhandler(req, res)); | ||
}); | ||
server.listen(3000); | ||
``` | ||
### Express | ||
@@ -603,4 +628,4 @@ | ||
const webpack = require("webpack"); | ||
const webpackConfig = require("./test/fixtures/webpack.simple.config"); | ||
const middleware = require("./dist"); | ||
const webpackConfig = require("./webpack.simple.config"); | ||
const middleware = require("webpack-dev-middleware"); | ||
@@ -674,2 +699,23 @@ const compiler = webpack(webpackConfig); | ||
### Hono | ||
```js | ||
import webpack from "webpack"; | ||
import { serve } from "@hono/node-server"; | ||
import { Hono } from "hono"; | ||
import devMiddleware from "webpack-dev-middleware"; | ||
import webpackConfig from "./webpack.config.js"; | ||
const compiler = webpack(webpackConfig); | ||
const devMiddlewareOptions = { | ||
/** Your webpack-dev-middleware-options */ | ||
}; | ||
const app = new Hono(); | ||
app.use(devMiddleware.honoWrapper(compiler, devMiddlewareOptions)); | ||
serve(app); | ||
``` | ||
## Contributing | ||
@@ -676,0 +722,0 @@ |
@@ -1,3 +0,1 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
export = wdm; | ||
@@ -32,3 +30,3 @@ /** @typedef {import("schema-utils/declarations/validate").Schema} Schema */ | ||
/** | ||
* @typedef {Object & { createReadStream?: import("fs").createReadStream, statSync?: import("fs").statSync, lstat?: import("fs").lstat, readFileSync?: import("fs").readFileSync }} OutputFileSystem | ||
* @typedef {import("webpack").OutputFileSystem & { createReadStream?: import("fs").createReadStream, statSync: import("fs").statSync, readFileSync: import("fs").readFileSync }} OutputFileSystem | ||
*/ | ||
@@ -158,4 +156,3 @@ /** @typedef {ReturnType<Compiler["getInfrastructureLogger"]>} Logger */ | ||
declare function wdm< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -170,2 +167,3 @@ >( | ||
koaWrapper, | ||
honoWrapper, | ||
Schema, | ||
@@ -210,10 +208,2 @@ Compiler, | ||
} | ||
type Compiler = import("webpack").Compiler; | ||
type MultiCompiler = import("webpack").MultiCompiler; | ||
type API< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
> = Middleware<RequestInternal, ResponseInternal> & | ||
AdditionalMethods<RequestInternal, ResponseInternal>; | ||
/** | ||
@@ -250,4 +240,3 @@ * @template S | ||
declare function koaWrapper< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -258,3 +247,19 @@ >( | ||
): (ctx: any, next: Function) => Promise<void> | void; | ||
/** | ||
* @template {IncomingMessage} [RequestInternal=IncomingMessage] | ||
* @template {ServerResponse} [ResponseInternal=ServerResponse] | ||
* @param {Compiler | MultiCompiler} compiler | ||
* @param {Options<RequestInternal, ResponseInternal>} [options] | ||
* @returns {(ctx: any, next: Function) => Promise<void> | void} | ||
*/ | ||
declare function honoWrapper< | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
>( | ||
compiler: Compiler | MultiCompiler, | ||
options?: Options<RequestInternal, ResponseInternal> | undefined, | ||
): (ctx: any, next: Function) => Promise<void> | void; | ||
type Schema = import("schema-utils/declarations/validate").Schema; | ||
type Compiler = import("webpack").Compiler; | ||
type MultiCompiler = import("webpack").MultiCompiler; | ||
type Configuration = import("webpack").Configuration; | ||
@@ -267,9 +272,5 @@ type Stats = import("webpack").Stats; | ||
| { | ||
webpack?: | ||
| { | ||
devMiddleware?: | ||
| Context<import("http").IncomingMessage, ServerResponse> | ||
| undefined; | ||
} | ||
| undefined; | ||
webpack?: { | ||
devMiddleware?: Context<IncomingMessage, ServerResponse>; | ||
}; | ||
} | ||
@@ -284,7 +285,6 @@ | undefined; | ||
type MultiWatching = ReturnType<MultiCompiler["watch"]>; | ||
type OutputFileSystem = Object & { | ||
type OutputFileSystem = import("webpack").OutputFileSystem & { | ||
createReadStream?: typeof import("fs").createReadStream; | ||
statSync?: import("fs").StatSyncFn; | ||
lstat?: typeof import("fs").lstat; | ||
readFileSync?: typeof import("fs").readFileSync; | ||
statSync: import("fs").StatSyncFn; | ||
readFileSync: typeof import("fs").readFileSync; | ||
}; | ||
@@ -300,4 +300,3 @@ type Logger = ReturnType<Compiler["getInfrastructureLogger"]>; | ||
type ModifyResponseData< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -311,4 +310,3 @@ > = ( | ||
type Context< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -326,4 +324,3 @@ > = { | ||
type FilledContext< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -338,4 +335,3 @@ > = WithoutUndefined<Context<RequestInternal, ResponseInternal>, "watching">; | ||
type Headers< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -351,4 +347,3 @@ > = | ||
type Options< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -377,4 +372,3 @@ > = { | ||
type Middleware< | ||
RequestInternal extends | ||
import("http").IncomingMessage = import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
@@ -395,3 +389,3 @@ > = ( | ||
type AdditionalMethods< | ||
RequestInternal extends import("http").IncomingMessage, | ||
RequestInternal extends IncomingMessage, | ||
ResponseInternal extends ServerResponse, | ||
@@ -405,2 +399,7 @@ > = { | ||
}; | ||
type API< | ||
RequestInternal extends IncomingMessage = import("http").IncomingMessage, | ||
ResponseInternal extends ServerResponse = ServerResponse, | ||
> = Middleware<RequestInternal, ResponseInternal> & | ||
AdditionalMethods<RequestInternal, ResponseInternal>; | ||
type WithOptional<T, K extends keyof T> = Omit<T, K> & Partial<T>; | ||
@@ -407,0 +406,0 @@ type WithoutUndefined<T, K extends keyof T> = T & { |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = wrapper; | ||
@@ -17,4 +16,4 @@ /** | ||
declare function wrapper< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("./index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -37,4 +36,4 @@ context: import("./index.js").FilledContext<Request, Response>, | ||
type SendErrorOptions< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("./index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
> = { | ||
@@ -41,0 +40,0 @@ /** |
@@ -1,51 +0,165 @@ | ||
/// <reference types="node" /> | ||
export type IncomingMessage = import("../index.js").IncomingMessage; | ||
export type ServerResponse = import("../index.js").ServerResponse; | ||
export type ExpectedResponse = { | ||
status?: ((status: number) => void) | undefined; | ||
send?: ((data: any) => void) | undefined; | ||
pipeInto?: ((data: any) => void) | undefined; | ||
export type OutputFileSystem = import("../index").OutputFileSystem; | ||
export type ExpectedIncomingMessage = { | ||
getHeader?: ((name: string) => string | string[] | undefined) | undefined; | ||
getMethod?: (() => string | undefined) | undefined; | ||
getURL?: (() => string | undefined) | undefined; | ||
}; | ||
export type ExpectedServerResponse = { | ||
setStatusCode?: ((status: number) => void) | undefined; | ||
getStatusCode?: (() => number) | undefined; | ||
getHeader?: | ||
| ((name: string) => string | string[] | undefined | number) | ||
| undefined; | ||
setHeader?: | ||
| (( | ||
name: string, | ||
value: number | string | Readonly<string[]>, | ||
) => ExpectedServerResponse) | ||
| undefined; | ||
removeHeader?: ((name: string) => void) | undefined; | ||
send?: ((data: string | Buffer) => void) | undefined; | ||
finish?: ((data?: string | Buffer) => void) | undefined; | ||
getResponseHeaders?: (() => string[]) | undefined; | ||
stream?: ((data: any) => void) | undefined; | ||
getOutgoing?: (() => any) | undefined; | ||
setState?: ((name: string, value: any) => void) | undefined; | ||
getReadyReadableStreamState?: | ||
| (() => "ready" | "open" | "readable") | ||
| undefined; | ||
}; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {number} code | ||
*/ | ||
export function setStatusCode< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response, code: number): void; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {number} | ||
*/ | ||
export function getStatusCode< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response): number; | ||
/** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ | ||
/** @typedef {import("../index.js").ServerResponse} ServerResponse */ | ||
/** @typedef {import("../index").OutputFileSystem} OutputFileSystem */ | ||
/** | ||
* @typedef {Object} ExpectedResponse | ||
* @property {(status: number) => void} [status] | ||
* @property {(data: any) => void} [send] | ||
* @property {(data: any) => void} [pipeInto] | ||
* @typedef {Object} ExpectedIncomingMessage | ||
* @property {(name: string) => string | string[] | undefined} [getHeader] | ||
* @property {() => string | undefined} [getMethod] | ||
* @property {() => string | undefined} [getURL] | ||
*/ | ||
/** | ||
* @template {ServerResponse & ExpectedResponse} Response | ||
* @typedef {Object} ExpectedServerResponse | ||
* @property {(status: number) => void} [setStatusCode] | ||
* @property {() => number} [getStatusCode] | ||
* @property {(name: string) => string | string[] | undefined | number} [getHeader] | ||
* @property {(name: string, value: number | string | Readonly<string[]>) => ExpectedServerResponse} [setHeader] | ||
* @property {(name: string) => void} [removeHeader] | ||
* @property {(data: string | Buffer) => void} [send] | ||
* @property {(data?: string | Buffer) => void} [finish] | ||
* @property {() => string[]} [getResponseHeaders] | ||
* @property {(data: any) => void} [stream] | ||
* @property {() => any} [getOutgoing] | ||
* @property {(name: string, value: any) => void} [setState] | ||
* @property {() => "ready" | "open" | "readable"} [getReadyReadableStreamState] | ||
*/ | ||
/** | ||
* @template {IncomingMessage & ExpectedIncomingMessage} Request | ||
* @param {Request} req | ||
* @param {string} name | ||
* @returns {string | string[] | undefined} | ||
*/ | ||
export function getRequestHeader< | ||
Request extends IncomingMessage & ExpectedIncomingMessage, | ||
>(req: Request, name: string): string | string[] | undefined; | ||
/** | ||
* @template {IncomingMessage & ExpectedIncomingMessage} Request | ||
* @param {Request} req | ||
* @returns {string | undefined} | ||
*/ | ||
export function getRequestMethod< | ||
Request extends IncomingMessage & ExpectedIncomingMessage, | ||
>(req: Request): string | undefined; | ||
/** | ||
* @template {IncomingMessage & ExpectedIncomingMessage} Request | ||
* @param {Request} req | ||
* @returns {string | undefined} | ||
*/ | ||
export function getRequestURL< | ||
Request extends IncomingMessage & ExpectedIncomingMessage, | ||
>(req: Request): string | undefined; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {number} code | ||
* @param {string} name | ||
* @returns {string | string[] | undefined | number} | ||
*/ | ||
export function setStatusCode< | ||
Response extends import("http").ServerResponse< | ||
import("http").IncomingMessage | ||
> & | ||
import("../index.js").ExtendedServerResponse & | ||
ExpectedResponse, | ||
>(res: Response, code: number): void; | ||
export function getResponseHeader< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response, name: string): string | string[] | undefined | number; | ||
/** | ||
* @template {IncomingMessage} Request | ||
* @template {ServerResponse} Response | ||
* @param {Response & ExpectedResponse} res | ||
* @param {string | Buffer} bufferOrStream | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
* @param {number | string | Readonly<string[]>} value | ||
* @returns {Response} | ||
*/ | ||
export function send< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
>(res: Response & ExpectedResponse, bufferOrStream: string | Buffer): void; | ||
export function setResponseHeader< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>( | ||
res: Response, | ||
name: string, | ||
value: number | string | Readonly<string[]>, | ||
): Response; | ||
/** | ||
* @template {ServerResponse} Response | ||
* @param {Response & ExpectedResponse} res | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
*/ | ||
export function removeResponseHeader< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response, name: string): void; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {string[]} | ||
*/ | ||
export function getResponseHeaders< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response): string[]; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {import("fs").ReadStream} bufferOrStream | ||
*/ | ||
export function pipe<Response extends import("../index.js").ServerResponse>( | ||
res: Response & ExpectedResponse, | ||
export function pipe<Response extends ServerResponse & ExpectedServerResponse>( | ||
res: Response, | ||
bufferOrStream: import("fs").ReadStream, | ||
): void; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string | Buffer} bufferOrString | ||
*/ | ||
export function send<Response extends ServerResponse & ExpectedServerResponse>( | ||
res: Response, | ||
bufferOrString: string | Buffer, | ||
): void; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string | Buffer} [data] | ||
*/ | ||
export function finish< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response, data?: string | Buffer | undefined): void; | ||
/** | ||
* @param {string} filename | ||
* @param {import("../index").OutputFileSystem} outputFileSystem | ||
* @param {OutputFileSystem} outputFileSystem | ||
* @param {number} start | ||
@@ -57,3 +171,3 @@ * @param {number} end | ||
filename: string, | ||
outputFileSystem: import("../index").OutputFileSystem, | ||
outputFileSystem: OutputFileSystem, | ||
start: number, | ||
@@ -65,1 +179,33 @@ end: number, | ||
}; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {Response} res | ||
*/ | ||
export function getOutgoing< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response): Response; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
*/ | ||
export function initState< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response): void; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @param {string} name | ||
* @param {any} value | ||
*/ | ||
export function setState< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response, name: string, value: any): void; | ||
/** | ||
* @template {ServerResponse & ExpectedServerResponse} Response | ||
* @param {Response} res | ||
* @returns {"ready" | "open" | "readable"} | ||
*/ | ||
export function getReadyReadableStreamState< | ||
Response extends ServerResponse & ExpectedServerResponse, | ||
>(res: Response): "ready" | "open" | "readable"; |
@@ -15,3 +15,3 @@ export = etag; | ||
} | ||
type Stats = import("fs").Stats; | ||
type ReadStream = import("fs").ReadStream; | ||
type Stats = import("fs").Stats; |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = getFilenameFromUrl; | ||
@@ -12,4 +11,4 @@ /** | ||
declare function getFilenameFromUrl< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -16,0 +15,0 @@ context: import("../index.js").FilledContext<Request, Response>, |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = getPaths; | ||
@@ -14,4 +13,4 @@ /** @typedef {import("webpack").Compiler} Compiler */ | ||
declare function getPaths< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -18,0 +17,0 @@ context: import("../index.js").FilledContext<Request, Response>, |
@@ -15,10 +15,8 @@ export = memorize; | ||
| { | ||
cache?: | ||
| Map< | ||
string, | ||
{ | ||
data: T; | ||
} | ||
> | ||
| undefined; | ||
cache?: Map< | ||
string, | ||
{ | ||
data: T; | ||
} | ||
>; | ||
} | ||
@@ -25,0 +23,0 @@ | undefined, |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = ready; | ||
@@ -14,4 +13,4 @@ /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */ | ||
declare function ready< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -18,0 +17,0 @@ context: import("../index.js").FilledContext<Request, Response>, |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = setupHooks; | ||
@@ -19,4 +18,4 @@ /** @typedef {import("webpack").Configuration} Configuration */ | ||
declare function setupHooks< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -23,0 +22,0 @@ context: import("../index.js").WithOptional< |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = setupOutputFileSystem; | ||
@@ -12,4 +11,4 @@ /** @typedef {import("webpack").MultiCompiler} MultiCompiler */ | ||
declare function setupOutputFileSystem< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -16,0 +15,0 @@ context: import("../index.js").WithOptional< |
@@ -1,2 +0,1 @@ | ||
/// <reference types="node" /> | ||
export = setupWriteToDisk; | ||
@@ -14,4 +13,4 @@ /** @typedef {import("webpack").Compiler} Compiler */ | ||
declare function setupWriteToDisk< | ||
Request extends import("http").IncomingMessage, | ||
Response extends import("../index.js").ServerResponse, | ||
Request extends IncomingMessage, | ||
Response extends ServerResponse, | ||
>( | ||
@@ -18,0 +17,0 @@ context: import("../index.js").WithOptional< |
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
129304
3087
746
44