Giter VIP home page Giter VIP logo

ky's Issues

TypeError relative URL after upgrading to 0.5.0

I've got this code:

  fetchHomeCards = async () => {
    this.setState({ loading: true });
    const response = await ky("/api/cards/");
    if (response.ok) {
...

it used to work just fine in 0.4.1, but busted now.

In Firefox I get TypeError: /api/cards/ is not a valid URL. on this line:

var url = new _globalThis.URL(this._options.prefixUrl + this._input);

In Chrome I get a lot more helpful error:

index.js:181 Uncaught (in promise) TypeError: Failed to construct 'URL': Invalid URL
    at new Ky (index.js:181)
    at ky (index.js:518)
    at CardsContainer._callee$ (State.js:15)
    at tryCatch (runtime.js:62)
    at Generator.invoke [as _invoke] (runtime.js:288)
    at Generator.prototype.(:3000/anonymous function) [as next] (http://localhost:3000/static/js/1.chunk.js:941:21)
    at asyncGeneratorStep (asyncToGenerator.js:3)
    at _next (asyncToGenerator.js:25)
    at asyncToGenerator.js:32
    at new Promise (<anonymous>)
    at CardsContainer.fetchHomeCards (asyncToGenerator.js:21)
    at Home._callee$ (Home.js:9)
    at tryCatch (runtime.js:62)
    at Generator.invoke [as _invoke] (runtime.js:288)
    at Generator.prototype.(:3000/anonymous function) [as next] (http://localhost:3000/static/js/1.chunk.js:941:21)
    at asyncGeneratorStep (asyncToGenerator.js:3)
    at _next (asyncToGenerator.js:25)
    at asyncToGenerator.js:32
    at new Promise (<anonymous>)
    at Home.<anonymous> (asyncToGenerator.js:21)
    at Home.componentDidMount (Home.js:12)
    at commitLifeCycles (react-dom.development.js:15986)
    at commitAllLifeCycles (react-dom.development.js:17388)
    at HTMLUnknownElement.callCallback (react-dom.development.js:147)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
    at invokeGuardedCallback (react-dom.development.js:250)
    at commitRoot (react-dom.development.js:17549)
    at completeRoot (react-dom.development.js:19002)
    at performWorkOnRoot (react-dom.development.js:18924)
    at performWork (react-dom.development.js:18826)
    at performSyncWork (react-dom.development.js:18799)
    at requestWork (react-dom.development.js:18676)
    at scheduleWork (react-dom.development.js:18480)
    at scheduleRootUpdate (react-dom.development.js:19186)
    at updateContainerAtExpirationTime (react-dom.development.js:19212)
    at updateContainer (react-dom.development.js:19280)
    at ReactRoot.push../node_modules/react-dom/cjs/react-dom.development.js.ReactRoot.render (react-dom.development.js:19559)
    at react-dom.development.js:19713
    at unbatchedUpdates (react-dom.development.js:19064)
    at legacyRenderSubtreeIntoContainer (react-dom.development.js:19709)
    at Object.render (react-dom.development.js:19776)
    at Module../src/index.js (index.js:8)
    at __webpack_require__ (bootstrap:782)
    at fn (bootstrap:150)
    at Object.0 (serviceWorker.js:131)
    at __webpack_require__ (bootstrap:782)
    at checkDeferredModules (bootstrap:45)
    at Array.webpackJsonpCallback [as push] (bootstrap:32)
    at main.chunk.js:1

Add simple query/search parameters option?

I've added a very simple wrapper around fetch myself and added the ability to passing in a qs object, which adds some parameters to the url:

const uri = new URL(url)
if (qs) {
	Object.keys(qs).forEach((key) => uri.searchParams.append(key, qs[key]))
}

it's a nicer api then just adding these to the url by hand.
I could make a PR if interested.

React native reference error in 0.5.1

I have been using this library on version 0.4.1 for some time and that works in react-native when running on the simulator with a debugger attached. Running on device results in Reference Error: self is not defined. This should be fixed in issue #53 (With commit f107e7b) which is available from version 0.5.0. After upgrading ky to 0.5.0 or 0.5.1 Running on a simulator with a debugger attached or a device results in Reference Error: document is not defined.

I import ky and export an instance as follows:

import ky from "ky";
export const api = ky.extend({prefixUrl: BASE_URL});

The error shown in the console is as follows:

Possible Unhandled Promise Rejection (id: 0):
ReferenceError: document is not defined
ReferenceError: document is not defined
    at new Ky (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:111478:76)
    at Function.ky.(anonymous function) [as post] (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:111772:16)
    at _callee3$ (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:115504:24)
    at tryCatch (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:2081:19)
    at Generator.invoke [as _invoke] (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:2256:24)
    at Generator.prototype.(anonymous function) [as next] (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:2124:23)
    at tryCatch (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:2081:19)
    at invoke (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:2157:22)
    at blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:2167:15
    at tryCallOne (blob:file:///58581b4b-dc99-4126-b9a9-cb3f918e33f0:6115:14)

alternative syntax

Hi, could you have a look at this alternative syntax for the constructor ? It gets rid of delete this._options.timeout; and delete this._options.json; . Does it look cleaner for you ?

constructor(input, {timeout = 10000, json, ...otherOptions}) {
		this._input = input;
		this._retryCount = 0;

		this._options = {
			method: 'get',
			credentials: 'same-origin', // TODO: This can be removed when the spec change is implemented in all browsers. Context: https://www.chromestatus.com/feature/4539473312350208
			retry: 3,
			...otherOptions
		};

		this._timeout = timeout;

		const headers = new window.Headers(this._options.headers || {});

		if (json) {
			headers.set('content-type', 'application/json');
			this._options.body = JSON.stringify(json);
		}

Maybe some assertions for `defaults` type in `extend`?

The defaults param will be used to deepMerge with other options and the deepMerge method will flat items for array argument.
Everything goes on normal and users may not know what happen if they pass in an array until they look into code. But there is something changed for options for Ky constructor actually.
Maybe there could be some assertions for the defaults param type as it should be an object? :)

Adding an delete alias for better named imports

I ran into this problem when using rollup specifically, but the issue occurs anytime someone attempts to perform a named import. ie.

import { post, get, delete } from 'ky'

The problem here is that delete is a restricted keyword and causes issues when imported and called. One suggestion is to rename it during the import like:

import { post, get, delete as del } from 'ky'

But this doesnt really solve the problem that the export is still confusing.

As a suggestion, i think adding 'del', which would just be an alias for delete would remove this problem:

import { del } from 'ky'

Adding a prettier config

Hello,

What's your opinion on having a prettier config? It'd much easier for contributors to write according to your style.

Question: Is XHR Supported

From looking at the tags in the package.json file, I noticed it says XHR, but when looking at the actual repository's docs, it uses the browser fetch API. Does this mean this library does not support XHR?

No ES5 package

This library doesn't work with popular tools like create-react-app or next.js. The reason is that it has no precompiled ES5 bundles. This is considered a bad practice as when someone is using it he has to compile it to ES5 himself to support older browsers. Also, ky won't work on older browsers when just put into the page as a script.

I don't think it's a good idea to force users to compile every dependency to make sure it's ES5-ready. It would massively affect build times.

Both hooks.afterResponse and beforeRequest could be defined optional

Hooks implementation is really a superb and extremly powerfull solution, but I would suggest some small changes to the typescript definition:

  1. Both hooks.afterResponse and beforeRequest could be optional
  2. BeforeRequestHook sould be BeforeRequestHook = (options: Options) => void;

Ability to provide custom fetch

I am loving the simplicity of this module. What I also love is Next.js. However, those two unfortunately doesn't play well with each other.

Trying to call ky inside Next's getInitialProps throws that self is not defined, because during first request Next.js calls getInitialProps on the server.

One possible solution would be to accept a user's fetch (e.g. https://www.npmjs.com/package/isomorphic-unfetch).

I understand that this adds a complexity, but if you are willing to accept it, I can send a PR.

`Promise.race()` breaks debugging

I generally develop frontend having "Pause on exceptions" functionality of chrome dev tools enabled. Here Ky doesn't work so good and forced me to disable that feature.
What happens is that determining if the fetch request goes well or it goes in timeout, Ky puts the actual request in race against a promise that on timeout (delay) throws an error. It's a nice looking piece of code and works fine, but when the fetch resolves correctly (in time) the other promise continues on its way and launches an uncontrolled exception that is caught by "Pause on exceptions".

A solution can be removing the throw statement form the timeout promise and chaining the result of the promises race with another function that checks which promise won (fetch or timeout), if the latter then throw the error.

Searching for ky

I have just spent 15 minutes, because I forgot ky name. Using keywords like fetch, library, tiny etc. I failed to find this library in google, npm and github. In the end I kept scrolling in my liked tweets until I found it.

Hooks

Something like:

ky(input, {..., hooks: {
	beforeRequest: [
		...
	]
}})

afterResponse hooks not fired if await ky directly

As discussed in Pr #93:
afterResponse hooks are not executed for the following code:

const response = await ky.get('https://example.com', {
    hooks: {
        afterResponse: [
             response => {
                 // This won't get called
             }
         ]
     }
});

const data = await response.json();

I know this is not how ky is supposed to be used, but it's easy to fall into this and see that everything is working, except the hooks.

Maybe some dist resources?

For some out of the box reasons for this lib. Maybe there could be some dist resources like iife, umd or whatever? Since the target env is browser and the native esm support for browser is not that popular. :)

TypeScript typings

Sindre, what's your current position on bundling Typescript typings to the repository? Somewhere I got the impression that you like Typescript and find typings useful. Do you intend to add them yourself? Will you allow someone to help with them? (but what about maintenance if you will change the API?)

Will you accept PR with initial typings?

Universal app

I know we should use Got for node js, but I'm building an universal app that will be rendered on both server/client side, so how should we handle that ?

Include a UMD build

I'm having to transpile the module before usage and I'm not sure if that's intentional.

This is the line which caused me pain.

ky/index.js

Line 192 in eb4b341

export default createInstance();

Feel free to close this is if the use of export is intentional, I couldn't really tell from the docs.

Use es6 modules

Is it possible to leverage the es6 module export syntax instead of the current commonjs style?

Since this is a client side adaptation of fetch, one pro would be possible use of the file without a node bundler, and allow direct inclusion via `<script type="module">"

Example:

<script type="module">
        import ky, { extend, HTTPError, TimeoutError } from './index.js';

        document.addEventListener('DOMContentLoaded', () => {
            console.log({ ky });
            console.log({ extend });
            console.log({ HTTPError });
            console.log({ TimeoutError });
            alert('hi');
        });

    </script>

My current implementation needs some help to get working:

export default createInstance();
export let extend = defaults => createInstance(defaults);
export { HTTPError, TimeoutError };

That above fails a few tests. Example: k.extend is not defined anymore. We can instead directly add extend as a method.

TypeScript - Don't allow `body` option for GET and HEAD requests

Would be nice to not allow the body option when using ky.get() and ky.head().

We could use a custom Omit type for this:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

Would also be nice to handle ky(โ€ฆ, {method: 'get', body: โ€ฆ}), but not sure whether that is possible?

It would also be nice to disallow the body option when the json option is used.

More info: http://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/

Object spread operator is breaking in local dev

โ” Issue

Ky is breaking due to the use of Object Spread Operator.

๐Ÿ”ฆ Context

I've tested it with Create-React-App. CRA supports the Object Spread Operator, however if it's used within a module, Babel does not transpile it. Interestingly enough, Ky works fine when I add into a box at Codesandbox.io.

๐Ÿ’ป Error Sample

./node_modules/ky/index.js
Module parse failed: Unexpected token (21:19)
You may need an appropriate loader to handle this file type.
| 				}
| 
| 				returnValue = {...returnValue, [key]: value};
| 			}
| 		}

๐ŸŒ Your Environment

Create react app @ latest
Node @ v10.6.0

Trouble with Cypress

Env

"ky": "^0.5.1",
"cypress": "^3.1.2",

Problem

Cypress doesn't support fetch api call.

Chromium give following error:

GET https://raw.githubusercontent.com/parlr/lsf-data/master/ net::ERR_ABORTED 400 (Bad Request)

After trying to force fetch polyfill by adding below code in support/index.js

Cypress.on('window:before:load', win => {
  win.fetch = null;
});

I got this error:

Uncaught (in promise) ReferenceError: err is not defined
    at _callee$ (actions.js:36)
    at tryCatch (runtime.js:62)
    at Generator.invoke [as _invoke] (runtime.js:296)
    at Generator.prototype.(:8080/__/anonymous function) [as throw] (webpack:///./node_modules/regenerator-runtime/runtime.js?:114:21)
    at asyncGeneratorStep (actions.js:5)
    at _throw (actions.js:7)

Error not thrown without the json method

Hi,

I was just trying to catch errors in the front-end of my react/redux app when I spotted a really odd behavior.

  • When doing a DELETE request on my API without ".json()" appended to my response, http errors are not thrown, even with throwHttpErrors forced true in the options.
try {
    await api.delete(`roles/${id}`);
    dispatch(actions.deleteRole(id));
  } catch (error) {
    dispatch({
      type: types.DELETE_ROLE_ERROR,
      payload: {
        error,
      },
    });
  }
  • When doing the same DELETE request with ".json()" appended to the response, errors are thrown but the request is fired twice so the second one always returns a 404.
try {
    await api.delete(`roles/${id}`).json();
    dispatch(actions.deleteRole(id));
  } catch (error) {
    dispatch({
      type: types.DELETE_ROLE_ERROR,
      payload: {
        error,
      },
    });
  }

Any idea why this would happen?

Why Ky?

Why yet another library? Why not contribute to existing ones instead of splitting the ecosystem, making it harder for beginners to choose one lib?

Here is a very similar yet much older lib you could have contributed too https://github.com/elbywan/wretch

Add JSON convenience methods

To simplify json calls, which is probably the major use-case of this library it might be nice to provide some wrapper methods which simplify the api calls even further for the common get, put, patch, delete http verbs.

Eg.

const json = await ky.getJson('https://some-api.com');
const json = await ky.postJson('https://some-api.com', {foo: true});

These would obviously just be some syntatic sugar around the existing json examples, but imo it would make the api even nicer to use.

Unhandled Rejection (Error): `input` must not begin with a slash when using `prefixUrl`

Hi,

I receive this exception when trying to call an API resource at https://example.com/foo/id

My ky instance is created as follow:

import ky from 'ky';

const config = {
    prefixUrl: process.env.API_ENTRYPOINT,
    headers: {
        'accept': 'application/ld+json'
    }
};

export default ky.extend(config);

I read the discussion related to the #11 and especially the one you wrote #11 (comment)

Sorry to be rude, but I disagree with the choice you made.
From my point of view, the only acceptable format should be await ky('/unicorn', {prefixUrl: 'https://cats.com'});.

It is not a matter of taste, just a choice guided by the RFC3986:
As per the section 3.3:

If a URI contains an authority component, then the path component
must either be empty or begin with a slash ("/") character.

For the url https://cats.com/unicorn we have the following parts:

  • The scheme: https
  • The : separator
  • The authority //cats.com (no userinfo, no port and host=cats.com)
  • The path to the resource: /unicorn

Except if the path is empty, a path must start with a slash.

Can you please reconsider the choice you made in #11 and modify this library according to that RFC?

Set the `accept` header when shortcut methods are called

Issuehunt badges

Mentioned it in sindresorhus/got#695 (comment)

One thing that got does, which I think it awesome, and which we don't have in ky, is setting the accept header when .json() is called.

@sholladay What's the benefit of sending this header? It works already without.

selrond earned $20.00 by resolving this issue!

naming

I know this was probably on purpose, or at least less important than the reasons pointed on the readme. however I have a really hard time dissociating this from the homonymous product ๐Ÿค”.

of course this could be a plus on describing the lib โ€” like "less friction on your client HTTP requests" โ€” and it's always nice to have a short npm name.

on future releases we may mirror it to another name if it's commonly agreed between maintainers here.. (hey, bhr for browser http request is still available ๐Ÿ˜…)

Default retry is different to readme

Hello,

Just a simple typo in the readme most likely, I would submit a PR but I'm not sure which is actually the most correct behaviour, a default retry of 2 like in the readme or 3 like the actual default.

Cheers

More comprehensive `retry` option

Issuehunt badges

In addition to accepting a number, it should accept an object with the ability to specify which methods and status codes to retry on. Same as Got: https://github.com/sindresorhus/got#retry


IssueHunt Summary

whitecrownclown whitecrownclown has been rewarded.

Backers (Total: $60.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Request continues after timeout

Something like:

const timeout = (promise, ms) => Promise.race([
	promise,
	(async () => {
		await delay(ms);
+       promise.abort();
		throw new TimeoutError();
	})()
]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.