Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions e2e/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,24 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ProductOrder'
/media-types/octet-stream:
post:
tags:
- media types
requestBody:
content:
application/octet-stream:
schema:
type: string
format: binary
responses:
200:
description: ok
content:
application/octet-stream:
schema:
type: string
format: binary

/escape-hatches/plain-text:
get:
Expand Down
27 changes: 27 additions & 0 deletions e2e/src/generated/client/axios/client.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions e2e/src/generated/client/fetch/client.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions e2e/src/generated/server/express/routes/media-types.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions e2e/src/generated/server/koa/routes/media-types.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions e2e/src/index.axios.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,20 @@ describe.each(
})
})

describe("POST /media-types/octet-stream", () => {
it("can send and parse application/octet-stream request bodies", async () => {
const blob = new Blob([new Uint8Array([0xde, 0xad, 0xbe, 0xef])], {
type: "application/octet-stream",
})
const res = await client.postMediaTypesOctetStream({
requestBody: blob,
})
expect(res.status).toBe(200)

await expect(res.data).toEqualBlob(blob)
})
})

describe("query parameters", () => {
it("GET /params/simple-query", async () => {
const {status, data} = await client.getParamsSimpleQuery({
Expand Down
14 changes: 14 additions & 0 deletions e2e/src/index.fetch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,20 @@ describe.each(
})
})

describe("POST /media-types/octet-stream", () => {
it("can send and parse application/octet-stream request bodies", async () => {
const blob = new Blob([new Uint8Array([0xde, 0xad, 0xbe, 0xef])], {
type: "application/octet-stream",
})
const res = await client.postMediaTypesOctetStream({
requestBody: blob,
})
expect(res.status).toBe(200)

await expect(await res.blob()).toEqualBlob(blob)
})
})

describe("query parameters", () => {
it("GET /params/simple-query", async () => {
const res = await client.getParamsSimpleQuery({
Expand Down
10 changes: 10 additions & 0 deletions e2e/src/jest.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type {CustomMatcherResult} from "expect"

declare module "expect" {
interface AsymmetricMatchers {
toEqualBlob(this: R, expected: Blob): Promise<CustomMatcherResult>
}
interface Matchers<R> {
toEqualBlob(this: R, expected: Blob): Promise<CustomMatcherResult>
}
}
12 changes: 12 additions & 0 deletions e2e/src/routes/express/media-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {SkipResponse} from "@nahkies/typescript-express-runtime/server"
import {
createRouter,
type PostMediaTypesOctetStream,
type PostMediaTypesText,
type PostMediaTypesXWwwFormUrlencoded,
} from "../../generated/server/express/routes/media-types.ts"
Expand All @@ -23,9 +24,20 @@ const postMediaTypesXWwwFormUrlencoded: PostMediaTypesXWwwFormUrlencoded =
return respond.with200().body(body)
}

const postMediaTypesOctetStream: PostMediaTypesOctetStream = async (
{body},
respond,
) => {
const arrayBuffer = await body.arrayBuffer()
const hex = Buffer.from(arrayBuffer).toString("hex")
console.log(hex)
return respond.with200().body(body)
}

export function createMediaTypesRouter() {
return createRouter({
postMediaTypesText,
postMediaTypesXWwwFormUrlencoded,
postMediaTypesOctetStream,
})
}
9 changes: 9 additions & 0 deletions e2e/src/routes/koa/media-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {SkipResponse} from "@nahkies/typescript-koa-runtime/server"
import {
createRouter,
type PostMediaTypesOctetStream,
type PostMediaTypesText,
type PostMediaTypesXWwwFormUrlencoded,
} from "../../generated/server/koa/routes/media-types.ts"
Expand All @@ -24,9 +25,17 @@ const postMediaTypesXWwwFormUrlencoded: PostMediaTypesXWwwFormUrlencoded =
return respond.with200().body(body)
}

const postMediaTypesOctetStream: PostMediaTypesOctetStream = async (
{body},
respond,
) => {
return respond.with200().body(body)
}

export function createMediaTypesRouter() {
return createRouter({
postMediaTypesText,
postMediaTypesXWwwFormUrlencoded,
postMediaTypesOctetStream,
})
}
41 changes: 41 additions & 0 deletions e2e/src/test-utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {Blob} from "node:buffer"
import {expect} from "@jest/globals"
import {AsymmetricMatcher} from "expect"

class NumberInRange extends AsymmetricMatcher<number> {
Expand All @@ -23,3 +25,42 @@ class NumberInRange extends AsymmetricMatcher<number> {

export const numberBetween = (min: number, max: number) =>
new NumberInRange(min, max)

expect.extend({
async toEqualBlob(received: Blob, expected: Blob) {
if (!(received instanceof Blob)) {
return {
pass: false,
message: () =>
"received is not a blob:\n" +
`received: '${this.utils.printReceived(received)}'` +
`expected: '${this.utils.printExpected(expected)}'`,
}
}

const [bufA, bufB] = await Promise.all([
received.arrayBuffer(),
expected.arrayBuffer(),
])

const a = new Uint8Array(bufA)
const b = new Uint8Array(bufB)

const pass = a.length === b.length && a.every((v, i) => v === b[i])

if (pass) {
return {
pass: true,
message: () => "expected blobs not to be equal",
}
} else {
return {
pass: false,
message: () =>
`expected blobs to be equal, but got:\n` +
`received: ${[...a].map((x) => x.toString(16).padStart(2, "0")).join(" ")}\n` +
`expected: ${[...b].map((x) => x.toString(16).padStart(2, "0")).join(" ")}`,
}
}
},
})
Loading