node-fetch
node-fetch copied to clipboard
TypeScript RequestInit interface missing 'duplex'
In WHATWG RequestInit has RequestDuplex duplex property but it's missing in node-fetch typescript API
https://github.com/node-fetch/node-fetch/blob/8b3320d2a7c07bce4afc6b2bf6c3bbddda85b01f/%40types/index.d.ts#L71-L112
Based on this https://fetch.spec.whatwg.org/#enumdef-requestduplex if fetch body is ReadableStream it requires the options duplex, want to check if duplex will be added to the RequestInit type in the new the near future, if not what is the process to contribute to adding a new type.
Screenshots
https://fetch.spec.whatwg.org/#request-class
node-fetch do kind of already support streams before duplex became spec'ed
i'm guessing duplex is more complicated that just simply adding a property to RequestInit
"half" is the only valid value and it is for initiating a half-duplex fetch (i.e., the user agent sends the entire request before processing the response). "full" is reserved for future use, for initiating a full-duplex fetch (i.e., the user agent can process the response before sending the entire request). This member needs to be set when body is a ReadableStream object. See issue #1254 for defining "full".
I'm not sure it's worth the time and effort into trying to add it to node-fetch when undici / NodeJS already supports the duplex option.
Thanks for the quick response. When specifying the body as Blob.stream() to get the ReadableStream, I'm getting this error:
Uncaught (in promise) RestError: Error sending request: Failed to execute 'fetch' on 'Window': The `duplex` member must be specified for a request with a streaming body
Not sure if I'm doing something wrong, but when adding the duplex: 'half' option in RequestInit (with // @ts-ignore to ignore linter), it will work fine.
Since we are using typescript, we would like to have the duplex property being part of the type, what would be the process for me to contribute to add this RequestDuplex to RequestInit?
"half" is the only valid value and it is for initiating a half-duplex fetch (i.e., the user agent sends the entire request before processing the response). "full" is reserved for future use, for initiating a full-duplex fetch (i.e., the user agent can process the response before sending the entire request). This member needs to be set when body is a ReadableStream object. See issue #1254 for defining "full".
Technically "half" functions as "full" right now in Node.js and Deno's implementation of fetch(). We can create a TransformStream, upload the readable side, write to the writable side and read the response in parallel.
No browser implements full-duplex using fetch() over the network at large directly.
However, on Chromium-based browsers we can full-duplex stream between a ServiceWorker and a WindowClient or Client, e.g., type some lower case letters in the input field here https://plnkr.co/edit/2PQK21kZTZvZ2oVi?preview.
We can use a browser extension to use Deno or Node.js implementation, for the capability to full-duplex stream to and from the server fom arbitrary Web pages, see https://github.com/guest271314/native-messaging-deno/tree/fetch-duplex, and https://github.com/guest271314/native-messaging-nodejs/tree/full-duplex.
Hello, I encountered the same issue. What would be the workaround if you guys don't want to implement this type ?
Seems like an issue... node fetch RequestInit has a property duplex but Typescript doesn't recognize it, missing from the types?
TypeScript requires me to add the missing duplex property when using fetch and PUT, but after added, it pops up, notifying me that duplex does not exist on RequestInit...
no duplex throws error on the fly:
TypeError: RequestInit: duplex option is required when sending a body.
at new Request (node:internal/deps/undici/undici:5499:19)
at R (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/next-server/app-page.runtime.dev.js:35:340580)
at D (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:60308)
at /Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:62407
at /Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/server/lib/trace/tracer.js:131:36
at NoopContextManager.with (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:7062)
at ContextAPI.with (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:518)
at NoopTracer.startActiveSpan (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:18093)
at ProxyTracer.startActiveSpan (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:18854)
at /Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/server/lib/trace/tracer.js:120:103
at NoopContextManager.with (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:7062)
at ContextAPI.with (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/@opentelemetry/api/index.js:1:518)
at NextTracerImpl.trace (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/server/lib/trace/tracer.js:120:28)
at globalThis.fetch (/Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:56863)
at MSGraphDriveProvider.uploadDriveItem (webpack-internal:///(rsc)/./src/lib/ms-graph/drive.ts:55:22)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async PUT (webpack-internal:///(rsc)/./src/app/api/graph/upload/route.tsx:30:22)
at async /Users/hoarfroster/Desktop/hfrecipe/node_modules/next/dist/compiled/next-server/app-route.runtime.dev.js:6:62609
having duplex throws error on npm run build, but works directly on npm run dev
Type error: No overload matches this call.
Overload 1 of 2, '(input: string | URL | Request, init?: RequestInit): Promise<Response>', gave the following error.
Object literal may only specify known properties, and 'duplex' does not exist in type 'RequestInit'.
Overload 2 of 2, '(input: URL | RequestInfo, init?: RequestInit): Promise<Response>', gave the following error.
Object literal may only specify known properties, and 'duplex' does not exist in type 'RequestInit'.
89 | },
90 | body: content,
> 91 | duplex: 'half'
| ^
92 | }
93 | ).then(async (res) => {
94 | return (await res.json()) as MSGraphDriveItem | MSGraphError;
Also getting this error. Does anyone have a resolution?
same issue, any update?
Posting the fix for my use case ... which was an API proxy using NextJS (but it may help others into looking into what they're sending in the body of the fetch call).
The body in this case was a ReabableStream, to avoid the error or the above TypeScript issue we were able to resolve the stream with:
const body = await request.json();
then pass this as the body in the fetch call
@agillespie-sp That's not streaming. We should be able to upload a ReadableStream as body using Request() and fetch().
passing the stream works, but only if you add duplex: "half" to the RequestInit object. Then you get into of the issue of duplex not being on the interface and potential build issues
Is there any way to solve this instead of using // @ts-expect-error for TypeScript?