Skip to content

Commit

Permalink
perf: remove compatible API
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan committed Aug 21, 2024
1 parent 66ed5de commit c54663d
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 263 deletions.
52 changes: 39 additions & 13 deletions src/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ const mrmime = require("mrmime");
const onFinishedStream = require("on-finished");

const getFilenameFromUrl = require("./utils/getFilenameFromUrl");
const {
setStatusCode,
send,
pipe,
createReadStreamOrReadFileSync,
} = require("./utils/compatibleAPI");
const ready = require("./utils/ready");
const parseTokenList = require("./utils/parseTokenList");
const memorize = require("./utils/memorize");
Expand All @@ -28,6 +22,38 @@ async function getEtag(stat) {
return `W/"${size}-${mtime}"`;
}

/**
* @typedef {Object} ExpectedResponse
* @property {(status: number) => void} [status]
* @property {(data: any) => void} [send]
* @property {(data: any) => void} [pipeInto]
*/

/**
* @param {string} filename
* @param {import("./index").OutputFileSystem} outputFileSystem
* @param {number} start
* @param {number} end
* @returns {{ bufferOrStream: (Buffer | import("fs").ReadStream), byteLength: number }}
*/
function createReadStreamOrReadFileSync(
filename,
outputFileSystem,
start,
end,
) {
const bufferOrStream =
/** @type {import("fs").createReadStream} */
(outputFileSystem.createReadStream)(filename, {
start,
end,
});
// Handle files with zero bytes
const byteLength = end === 0 ? 0 : end - start + 1;

return { bufferOrStream, byteLength };
}

/**
* Create a full Content-Type header given a MIME type or extension.
*
Expand Down Expand Up @@ -226,7 +252,7 @@ function wrapper(context) {
}

// Send basic response
setStatusCode(res, status);
res.statusCode = 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");
Expand Down Expand Up @@ -520,7 +546,7 @@ function wrapper(context) {

// For Koa
if (res.statusCode === 404) {
setStatusCode(res, 200);
res.statusCode = 200;
}

if (
Expand All @@ -532,7 +558,7 @@ function wrapper(context) {
(res.getHeader("Last-Modified")),
})
) {
setStatusCode(res, 304);
res.statusCode = 304;

// Remove content header fields
res.removeHeader("Content-Encoding");
Expand Down Expand Up @@ -583,7 +609,7 @@ function wrapper(context) {

if (parsedRanges !== -2 && parsedRanges.length === 1) {
// Content-Range
setStatusCode(res, 206);
res.statusCode = 206;
res.setHeader(
"Content-Range",
getValueContentRangeHeader(
Expand Down Expand Up @@ -622,7 +648,7 @@ function wrapper(context) {
if (req.method === "HEAD") {
// For Koa
if (res.statusCode === 404) {
setStatusCode(res, 200);
res.statusCode = 200;
}

res.end();
Expand All @@ -635,7 +661,7 @@ function wrapper(context) {
) === "function";

if (!isPipeSupports) {
send(res, /** @type {Buffer} */ (bufferOrStream));
res.end(/** @type {Buffer} */ (bufferOrStream));
return;
}

Expand Down Expand Up @@ -666,7 +692,7 @@ function wrapper(context) {
}
});

pipe(res, /** @type {ReadStream} */ (bufferOrStream));
/** @type {ReadStream} */ (bufferOrStream).pipe(res);

// Response finished, cleanup
onFinishedStream(res, cleanup);
Expand Down
107 changes: 0 additions & 107 deletions src/utils/compatibleAPI.js

This file was deleted.

85 changes: 0 additions & 85 deletions test/middleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2736,91 +2736,6 @@ describe.each([
);
});
});

describe("should work without `fs.createReadStream`", () => {
let compiler;
let codeContent;

const outputPath = path.resolve(
__dirname,
"./outputs/basic-test-no-createReadStream",
);

beforeAll(async () => {
compiler = getCompiler({
...webpackConfig,
output: {
filename: "bundle.js",
path: outputPath,
},
});
compiler.hooks.afterCompile.tap("wdm-test", (params) => {
codeContent = params.assets["bundle.js"].source();
});

[server, req, instance] = await frameworkFactory(
name,
framework,
compiler,
);

instance.context.outputFileSystem.mkdirSync(outputPath, {
recursive: true,
});
instance.context.outputFileSystem.writeFileSync(
path.resolve(outputPath, "image.svg"),
"svg image",
);

instance.context.outputFileSystem.createReadStream = null;
});

afterAll(async () => {
await close(server, instance);
});

it('should return the "200" code for the "GET" request to the bundle file', async () => {
const response = await req.get("/bundle.js");

expect(response.statusCode).toEqual(200);
expect(response.headers["content-length"]).toEqual(
String(Buffer.byteLength(codeContent)),
);
expect(response.headers["content-type"]).toEqual(
"text/javascript; charset=utf-8",
);
expect(response.text).toEqual(codeContent);
});

it('should return the "200" code for the "GET" request to the "image.svg" file', async () => {
const fileData = instance.context.outputFileSystem.readFileSync(
path.resolve(outputPath, "image.svg"),
);

const response = await req.get("/image.svg");

expect(response.statusCode).toEqual(200);
expect(response.headers["content-length"]).toEqual(
fileData.byteLength.toString(),
);
expect(response.headers["content-type"]).toEqual("image/svg+xml");
});

it('should return the "200" code for the "HEAD" request to the "image.svg" file', async () => {
const fileData = instance.context.outputFileSystem.readFileSync(
path.resolve(outputPath, "image.svg"),
);

const response = await req.head("/image.svg");

expect(response.statusCode).toEqual(200);
expect(response.headers["content-length"]).toEqual(
fileData.byteLength.toString(),
);
expect(response.headers["content-type"]).toEqual("image/svg+xml");
expect(response.body).toEqual({});
});
});
});

describe("watchOptions option", () => {
Expand Down
6 changes: 6 additions & 0 deletions types/middleware.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ declare function wrapper<
declare namespace wrapper {
export {
Stats,
ExpectedResponse,
SendErrorOptions,
NextFunction,
IncomingMessage,
Expand All @@ -29,6 +30,11 @@ declare namespace wrapper {
};
}
type Stats = import("fs").Stats;
type ExpectedResponse = {
status?: ((status: number) => void) | undefined;
send?: ((data: any) => void) | undefined;
pipeInto?: ((data: any) => void) | undefined;
};
/**
* send error options
*/
Expand Down
58 changes: 0 additions & 58 deletions types/utils/compatibleAPI.d.ts

This file was deleted.

0 comments on commit c54663d

Please sign in to comment.