Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
4,800 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Release | ||
"on": | ||
push: | ||
branches: | ||
- "*.x" | ||
- main | ||
- next | ||
- beta | ||
jobs: | ||
release: | ||
name: release | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-node@v2 | ||
with: | ||
node-version: 16 | ||
cache: npm | ||
- run: npm ci | ||
- run: npx semantic-release | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
name: Test | ||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
types: [opened, synchronize] | ||
|
||
jobs: | ||
test_matrix: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
node_version: ["14", "16", "17"] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Use Node.js ${{ matrix.node_version }} | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: ${{ matrix.node_version }} | ||
cache: npm | ||
- run: npm ci | ||
- run: npm run test:code | ||
|
||
test: | ||
runs-on: ubuntu-latest | ||
needs: test_matrix | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- uses: actions/setup-node@v2 | ||
with: | ||
node-version: ${{ matrix.node_version }} | ||
cache: npm | ||
- run: npm ci | ||
- run: npm run test:tsc | ||
- run: npm run test:tsd | ||
- run: npm run lint |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
coverage | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import http from "http"; | ||
|
||
declare const HttpRecorder: { | ||
enable: () => typeof HttpRecorder; | ||
disable: () => typeof HttpRecorder; | ||
on: (event: "record", listener: RecordHandler) => typeof HttpRecorder; | ||
off: (event: "record", listener: RecordHandler) => typeof HttpRecorder; | ||
removeAllListeners: () => typeof HttpRecorder; | ||
}; | ||
|
||
export default HttpRecorder; | ||
|
||
export interface RecordHandler { | ||
(options: RecordHandlerOptions): void | Promise<void>; | ||
} | ||
|
||
export type RecordHandlerOptions = { | ||
request: http.ClientRequest; | ||
response: http.IncomingMessage; | ||
requestBody: Buffer[]; | ||
responseBody: Buffer[]; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// @ts-check | ||
|
||
import { EventEmitter } from "node:events"; | ||
import http from "node:http"; | ||
|
||
const emitter = new EventEmitter(); | ||
let origOnSocket; | ||
|
||
export default { | ||
enable() { | ||
if (origOnSocket) { | ||
// already enabled | ||
return; | ||
} | ||
|
||
origOnSocket = http.ClientRequest.prototype.onSocket; | ||
http.ClientRequest.prototype.onSocket = function (socket) { | ||
const interceptedRequest = this; | ||
|
||
const requestBodyChunks = []; | ||
const originalRequestWrite = interceptedRequest.write; | ||
interceptedRequest.write = function (chunk) { | ||
requestBodyChunks.push(Buffer.from(chunk)); | ||
return originalRequestWrite.call(this, chunk); | ||
}; | ||
|
||
interceptedRequest.on("response", async (response) => { | ||
const responseBodyChunks = []; | ||
for await (const chunk of response) { | ||
responseBodyChunks.push(Buffer.from(chunk)); | ||
} | ||
|
||
emitter.emit("record", { | ||
request: interceptedRequest, | ||
requestBody: requestBodyChunks, | ||
response, | ||
responseBody: responseBodyChunks, | ||
}); | ||
}); | ||
|
||
return origOnSocket.call(this, socket); | ||
}; | ||
|
||
return this; | ||
}, | ||
disable() { | ||
if (origOnSocket) { | ||
http.ClientRequest.prototype.onSocket = origOnSocket; | ||
origOnSocket = undefined; | ||
} | ||
return this; | ||
}, | ||
on(eventName, callback) { | ||
if (eventName !== "record") { | ||
throw new Error("Only 'record' events are supported"); | ||
} | ||
|
||
emitter.on("record", callback); | ||
return this; | ||
}, | ||
off(eventName, callback) { | ||
if (eventName !== "record") { | ||
throw new Error("Only 'record' events are supported"); | ||
} | ||
|
||
emitter.off("record", callback); | ||
return this; | ||
}, | ||
removeAllListeners() { | ||
emitter.removeAllListeners(); | ||
return this; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import http from "node:http"; | ||
|
||
import { expectType } from "tsd"; | ||
import HttpRecorder from "./index.js"; | ||
|
||
export function smokeTest() { | ||
expectType<typeof HttpRecorder>(HttpRecorder); | ||
} | ||
|
||
export function API() { | ||
expectType<typeof HttpRecorder>(HttpRecorder.enable()); | ||
expectType<typeof HttpRecorder>(HttpRecorder.disable()); | ||
expectType<typeof HttpRecorder>(HttpRecorder.on("record", () => {})); | ||
expectType<typeof HttpRecorder>(HttpRecorder.off("record", () => {})); | ||
expectType<typeof HttpRecorder>(HttpRecorder.removeAllListeners()); | ||
|
||
// @ts-expect-error - only "record" is supported | ||
HttpRecorder.on("not-record", () => {}); | ||
} | ||
|
||
export function recordHandler() { | ||
HttpRecorder.on("record", (options) => { | ||
expectType<http.ClientRequest>(options.request); | ||
expectType<http.IncomingMessage>(options.response); | ||
expectType<Buffer[]>(options.requestBody); | ||
expectType<Buffer[]>(options.responseBody); | ||
}); | ||
} |
Oops, something went wrong.