sindresorhus / ky-universal Goto Github PK
View Code? Open in Web Editor NEWUse Ky in both Node.js and browsers
Home Page: https://github.com/sindresorhus/ky
License: MIT License
Use Ky in both Node.js and browsers
Home Page: https://github.com/sindresorhus/ky
License: MIT License
I am writing an app for web and electron using Quasar. I wanted to move from axios to Ky but as soon as I replace it Vuex store refuses to accept changes to it's state. store.commit works and I am able to log payload data and current store values but no mutations are accepted by store without any errors or warnings. This is very interesting and I can't pin where it fails. Any help would be appreciated.
I recently encounter a very strange situation. My ky.get().json()
hangs without any response.
The project sends API query to Contentful and gets response. I tried multiple times and finally figure out that, there seems to be limit of the response size/length?
In Postman, I can see that my limit is around 3.3 KB. Any of you encounter similar situation?
Hi there,
Running a simple test fails saying that Buffer is not defined. I tried npm i buffer --save
but that didn't work.
Here's the test:
describe("App", () => {
it("render", () => {
render(App);
});
});
And here's the log:
β Test suite failed to run
/Users/danielbakas/Documents/Profesional/Semantyk/Projects/Semantyk/client/node_modules/ky-universal/node_modules/node-fetch/src/utils/form-data.js:1
ReferenceError: Buffer is not defined
at Object.<anonymous> (node_modules/ky-universal/node_modules/node-fetch/src/utils/form-data.js:7:24)
Any idea on how to fix this?
Thanks π
Would it make sense to polyfill readable stream in the node stream library or https://www.npmjs.com/package/web-streams-polyfill? Otherwise the onDownloadProgress option isn't usable for non-browsers
In Node.js v14, I got this error.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/salty/Documents/src/youtu-bu/node_modules/ky-universal/index.js
require() of ES modules is not supported.
require() of /Users/salty/Documents/src/youtu-bu/node_modules/ky-universal/index.js from /Users/salty/Documents/src/youtu-bu/packages/youtu-bu-sakagura/.next/server/pages/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename /Users/salty/Documents/src/youtu-bu/node_modules/ky-universal/index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/salty/Documents/src/youtu-bu/node_modules/ky-universal/package.json.
Could you tell me why do you use "type": "module"
in package.json?
This was happening via nuxt/http which uses ky and a copied implementation of ky-universal.
I figured this should also be fixed here too.
The error classes HTTPError
and TimeoutError
seem to be inaccessible through ky-universal
. It only re-exports the default export of ky/umd
, not these classes. Following workaround can only be found by inspecting the source code:
const { HTTPError, TimeoutError } = require('ky/umd')
I think it is reasonable to expect following to work:
const { HTTPError, TimeoutError } = require('ky-universal')
Would you accept a PR implementing this?
I have the following use case:
Is this setup possible? If not, what would be an alternative?
We are working on a KY / Fetch-based universal HTTP layer for Nuxt. The problem is that Nuxt already polyfills global.fetch
, this is breaking ky-universal
as if (!global.fetch)
prevents filling other globals that ky
internally depends on them.
Update: Issue still exists by removing if condition. Maybe a jest / webpack global issue. Closing issue for now.
I've had a somewhat frustrating start to ky, not sure what I'm doing wrong
(node:29176) UnhandledPromiseRejectionWarning: TypeError: Headers is not a constructor
at new Ky (/Volumes/Repositories/Private/apitests/testProj1/node_modules/ky/umd.js:211:20)
at Function.ky.(anonymous function) [as get] (/Volumes/Repositories/Private/apitests/testProj1/node_modules/ky/umd.js:389:37)
at getParentChildEndpoint (/Volumes/Repositories/Private/apitests/testProj1/src/api/util/getParentChildEndpoint.js:14:16)
at Object.getStatus (/Volumes/Repositories/Private/apitests/testProj1/src/api/instanceApi.js:49:22)
Rerproduced like this:
const ky = require('ky-universal').default;
const prefix = 'http://aa9da6ff.ngrok.io/api/instances/gub6r';
const instanceApi = ky.create({ prefixUrl: prefix, throwHttpErrors: false });
const result = await instanceApi.get('status').json();
This seems to be line 211 in umd.js:
I have both KY and Ky-universal installed. What am I doing wrong or missing?
If I try to catch this, the error is the same as that shown in the stack trace. I'd expect a HTTP error (like 404), not a stack trace like this. Thanks!
Hi, I'm using ky-universal in a nuxtjs project and at the build there is an error:
Module not found: Error: Can't resolve 'web-streams-polyfill/ponyfill/es2018'```
What can I do to solve this Issue?
Thanks
When trying to use ky/ky-universal with the newly created Next.js app receive such error:
Error: Must use import to load ES Module: /Users/---/node_modules/ky-universal/index.js
require() of ES modules is not supported.
require() of /---/node_modules/ky-universal/index.js from /---/.next/server/pages/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename /---/node_modules/ky-universal/index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /---/node_modules/ky-universal/package.json.
Packages version:
Node 14.15.4,
"dependencies": {
"ky": "^0.26.0",
"ky-universal": "^0.9.1",
"next": "10.0.5",
"react": "17.0.1",
"react-dom": "17.0.1"
}
Code extract
import ky from "ky-universal";
export default function Home() {
const fetchData = async () => {
const res = await ky
.get("https://jsonplaceholder.typicode.com/todos/1")
.json();
setData(res);
console.log(res);
};
It's not stable enough now, but it is likely to become better than node-fetch
.
Hello, I am using a package which uses ky-universal as a dependency.
I am getting an error while executing on the ky-universal package that
/home/kush/Code/solid-stream-aggregator/node_modules/ky-universal/node_modules/node-fetch/src/utils/form-data.js:1
ReferenceError: Buffer is not defined
at Object.<anonymous> (node_modules/ky-universal/node_modules/node-fetch/src/utils/form-data.js:7:24)
Hi all,
Don't working default import in ts, like import ky from 'ky-universal'
is undefiend
but:
const ky = require('ky-universal')
is working
Broken:
import ky from "ky-universal";
const result = await ky
.post(process.env.BE_ENDPOINT!, {
json: jsonBody,
})
.json();
// we never reach here, await never resolves
Works:
import ky from "ky-universal";
const response = await ky
.post(process.env.BE_ENDPOINT!, {
json: jsonBody,
});
const result = await response.json(); // result is here, yay
deps:
"node": "16.17.1"
"ky": "0.33.2",
"ky-universal": "0.11.0",
"web-streams-polyfill": "3.2.1"
ky-universal#[email protected]
NOTE - Seems to depend on the response body somehow (size?), as it doesn't happen for all requests, but it is consistent within the context of a single request (ie. a broken request/response pair stays broken, a valid request/response pair works).
We are definitely sending a non 2xx response to the ky.post (using ky-universal), and no error is thrown. We assumed that both ky and ky-universal have the same methods, but upon reading the read.me for ky-universal it is not explicitly stated that it does (or doesn't for that matter).
Would you mind updating the read.me to be more explicit regarding how ky-universal can be used?
Many thanks!
Hi hopefully this is an easy / quick answer
In the FAQ here: https://github.com/sindresorhus/ky-universal#clone-hangs-with-a-large-response-in-node---what-should-i-do
It's stated that Ky is used under the hood and has a default highWatermark of 10mb.
However when using ky-universal I run into issues with cloning at 20kb and looking through https://github.com/sindresorhus/ky I (perhaps naively) don't think a highWatermark default is being set.
Perhaps I'm just missing it, but would be great to get clarification on this.
Thanks in advance.
The way web-streams-polyfill
is called makes it a non optional dependancy as it is declared in package.json
if (!global.ReadableStream) {
try {
global.ReadableStream = require('web-streams-polyfill/ponyfill/es2018');
} catch (_) {}
}
Therefore if the environment simply does not have ReadableStream
s the dependancy is called. If a developer is not using readable streams they still have to install it. Thus the dependancy is not optional.
In a electron renderer thread if you don't bundle (nodeIntegration===true) you get whatever main prop a package points to, in this case we get the node version of ky.
But if we look at these lines https://github.com/sindresorhus/ky-universal/blob/master/index.js#L14-L16 we will get into troubles because the if clause tests if global.fetch
exists and in electron renderer that will be true because native web fetch is available.
So instead of using node-fetch we use native fetch, but when another package using ky
uses https://github.com/form-data/form-data with fetch it fails because form-data
only works with node-fetch.
To fix this either we detect the environment for this specific case and workaround it or we remove the if clauses since ky
already allows for lazy resolution of globals.
I'm happy to PR a fix, but would like some feedback on this first.
In node v16.16.0 with
"ky": "^0.31.3",
"ky-universal": "^0.10.1"
my script throws
node_modules/ky/distribution/core/constants.js:6
hasContentType = new globalThis.Request('https://a.com', {
^
TypeError: globalThis.Request is not a constructor
This appears to have been introduced at ky 0.31.2
Hello, ive tried to migrate from axios (using nuxt), and start using '@nuxt/http' but when i was tryed to get header from the post response
import http from 'ky-universal'
const actions = {
// Get Token
async login(context, payload) {
let data = null
try {
data = await http.post(
process.env.apiUrl + '/api/content/create?type=User',
{
body: payload
}
)
} catch (err) {}
console.log(data.headers.get('Authorization'))
},
}
console.log(data.headers.get('Authorization')) shows null, there is anyway to make it work?
in firefox network tab response header looks like:
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Accept, Authorization, Content-Type
Access-Control-Allow-Origin: *
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhY2Nlc3MiOiJjb2xkQGNvbGQuY29sZCIsImF1ZCI6bnVsbCwiZXhwIjoxNTg0NTQyMzMwLCJpYXQiOm51bGwsImlzcyI6bnVsbCwianRpIjpudWxsLCJuYmYiOm51bGwsInN1YiI6bnVsbH0.SYAwu0h5xA6xNQQGqja9uItHq0Wbq-52I4CrT78N7U0
Cache-Control: max-age=2592000, public
Etag: MTU4MzkzNjUzMw==
Date: Wed, 11 Mar 2020 14:38:50 GMT
Content-Length: 0
Hi,
When using ky-universal
with Typescript it requires DOM types ("lib": ["dom"]
) to be included in tsconfig
, because of it's dependency on ky
. i. e. without it the build fails with:
node_modules/ky/index.d.ts:426:11 - error TS2304: Cannot find name 'Request'.
This is a bit inconvenient when using ky-universal
in a node.js service since it doesn't make sense to add DOM types to a backend project.
Are there any workarounds for this that you are aware of?
Thanks!
Since Node.js doesn't support top-level await, this code throws when imported:
Line 29 in ca24367
There seems to be a problem using web-streams-polyfill
on nodejs 14.x
I ran into the issue where, given some code like described in the documentation:
const ky = require('ky-universal');
(async () => {
const {body} = await ky('https://httpbin.org/bytes/16');
const {value} = await body.getReader().read();
const result = new TextDecoder('utf-8').decode(value);
// β¦
})();
I would get a runtime error:
TypeError: _a.getReader is not a function
at the 'body.getReader()
call.
I read the docs to install web-streams-polyfill
which I did (3.0.0) but still get the error.
I took stepped through the ky-universal
code and see
//index.js
if (!global.ReadableStream) {
try {
global.ReadableStream = require('web-streams-polyfill/ponyfill/es2018');
} catch (_) {}
}
This seems to be a problem because the require('web-streams-polyfill/ponyfill/es2018') returns an object, so the following fails:
//ky/umd.js
const supportsStreams = typeof globals.ReadableStream === 'function';
so.... clever me, I thought I would pre-shim the globals.ReadableStream
to hot-patch the problem by adding this to my app code:
if ( !global.ReadableStream ) {
global.ReadableStream = require( 'web-streams-polyfill/ponyfill/es2018' ).ReadableStream
}
but still, the body.getReader()
function doesn't exist. Unfortunately the ky
code is too fancy for me to follow, so here I am, filing this issue!
fyi, I also tried [email protected]
but same error.
I use ky in a React app.
For tests (jest on node) I inject ky-universal instead.
(with beforeRequest
hook set to return canned responses - also useful for mocks during developments! π)
Recently upgraded from 0.9.1 to 0.10.x and all tests relying on ky failed.
Since the diff is mostly a node-fetch minor bump and everything else being equal, obviously it's NOT an issue with ky-universal, but with a dependency.
Took me a while, but I was able to find the underlying error: ReferenceError: TextDecoder is not defined
(thrown by this line: https://github.com/node-fetch/node-fetch/blob/main/src/body.js#L159)
From there, the way to a workaround was shorter. In my setupTests
file, I just added:
import {TextDecoder} from 'util'
global.TextDecoder = TextDecoder
(I you use TS, you can easily appease its complaint with: global.TextDecoder = TextDecoder as typeof global.TextDecoder
)
And although I still don't understand how such a built-in api became undefined, at least I was back to green β
I know ky-universal is not as popular as ky, but if a search engine brings even a single soul to this text and they find it helpful, I'll be happy.
LLAP! π
I hit this bug today, it was caused by node-fetch/node-fetch#386
The bug makes ky-universal
not useable at all in node. (You don't know when the code will hang as you don't know the response size ahead of time)
Is there a way to remove clone()
from the source code?
Node 14
[email protected]
[email protected]
This is a sample project demonstrating the problem. Inside the package.json file we specify that the .js
files are treated as esm modules.
However running the simple test.js
sample:
import ky from 'ky-universal'
const parsed = await ky('https://httpbin.org/json').json()
console.log(parsed)
Fails i.e:
The issue seems that it seems to be loading the browser.js
variant instead of the index.js
which polyfills for the node environment.
E.g. if we explictely import the index.js
variant that does the polyfill'ing it works as intended:
import ky from './node_modules/ky-universal/index.js'
const parsed = await ky('https://httpbin.org/json').json()
console.log(parsed)
The problem seem to be related to the changes done in the latest version.
Since the test samples will work perfectly fine with the previous versions of ky and ky-universal.
Checking out the branch previous-versions
that use [email protected]
and [email protected]
I just reported an issue on the Next.js issue tracker that concerns ky-universal
β vercel/next.js#13549
tl;dr
The body timeout issue on parsing large JSON responses still happens with v0.7.0
when using Next.js.
A contributor pointed out (see vercel/next.js#13549 (comment)) that this is happening because ky-universal
is preferring global fetch
over the latest beta version (own dependency). How do you propose we solve this?
One option I can think of is letting users inject their version of node-fetch
. Another way to solve this would be expose a flag to force-use the bundled version of node-fetch
.
Are there better solutions?
After updating to 0.9.1 I'm getting:
\node_modules\ky-universal\index.js:58
globalThis.ReadableStream = await Promise.resolve().then(function () {
^^^^^
SyntaxError: await is only valid in async functions and the top level bodies of modules
> 1 | import ky from 'ky-universal';
| ^
I'm using node v15.6.0.
I'm not quite sure how I'm supposed to fix this. Any help would be greatly appreciated.
How can I use Ky for react SSR?
Line 65 in ca24367
Version 3.1.1
should not have it.
I currently need to use KY on a machine with high confidentiality. This machine only has an intranet. I checked many online tutorials, but I didn't find the way to add an agent. Can you give me an example?
Repro β https://github.com/paambaati/ky-body-timeout-repro
I use ky
and ky-universal
in a Next.js app and I noticed responses failing with a body-timeout
error on the Node.js side only for responses above roughly 50KB in size. I've tried tweaking the highWatermark
and size
options, but it doesn't seem to have an effect.
I have an afterResponse
hook that does some additional stuff like logging the responses, redirecting to my login page if the response is a 401
, etc.
If I remove the hook, it works. This is illustrated in my repro where I've added a hook with just one console.log
statement, and you can see the issue occurring. Returning the res
has no effect. If the hook is completely removed on the repro, it works.
This is not a bug report or an issue with ky-universal.
I'm sharing a solution to a problem I had, hoping it would be visible to people having the same problem if I put it here.
I'd be glad to move it to somewhere else if this is not the best place to share this.
I wasn't able to import ky-universal
in a Jest test file.
I worked around this by creating the following file:
jest.setup.js
:
const fetch = require('node-fetch');
globalThis.fetch = fetch;
globalThis.Request = fetch.Request;
globalThis.Headers = fetch.Headers;
And adding this to jest.config.js
:
module.exports = {
...
setupFiles: ["./jest.setup.js"],
...
}
ky-universal
is an ES6 module.
No matter how hard I tried, I was not able to make Jest load an ES6 module.
It got transformed to something like this, probably by Babel:
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import ky from "ky";
And imports can't be anywhere except at the top level in ES6 Modules.
With ky
, I was able to get it transformed to cjs
by installing esbuild
:
yarn add -D esbuild esbuild-jest
and adding this in my jest.config.js
:
module.exports = {
...
transform: {
"^.+\\.(t|j)sx?$": [
"esbuild-jest",
{}
],
},
transformIgnorePatterns: [
'/node_modules/(?!ky)'
]
...
}
But ky-universal
is doing top-level await inside it, and neither esbuild-jest
nor ts-jest
was able to process top level await.
I tried so hard to make this work with just ES6 support and not using a bundler like esbuild. But I had to conclude this is pretty much impossible after two days of digging.
So I tried to start with just ky
, which works fine when converted into cjs
by esbuild
, and started putting stuff into globalThis
, one by one, by looking at the errors that came up.
For my code, errors stopped appearing after I assigned the above three things, but there could be more.
If it happens just check the error to see what's missing and add it to globalThis
.
Hi,
For some reason, I can't access HTTPError
from this package. Import from ky
package works just fine.
import { HTTPError } from "ky-universal";
import { HTTPError as HTTPErrorFromKy } from "ky";
/**
* prints {HTTPError: undefined, HTTPErrorFromKy: Ζ HTTPError()}
*/
console.log({ HTTPError, HTTPErrorFromKy });
https://codesandbox.io/s/red-field-qdh1d7?file=/src/index.js
Thank you,
RafaΕ
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.