Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ohmyfetch

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ohmyfetch - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

8

CHANGELOG.md

@@ -5,2 +5,10 @@ # Changelog

### [0.0.3](https://github.com/nuxt-contrib/ohmyfetch/compare/v0.0.2...v0.0.3) (2020-12-12)
### Features
* bundle ufo and destr for easier bundler integration ([8f5ba88](https://github.com/nuxt-contrib/ohmyfetch/commit/8f5ba88f1ac0aa40ff2c99316da98a71d6dcc7e8))
* support `$fetch.raw` and improve docs ([f9f70a5](https://github.com/nuxt-contrib/ohmyfetch/commit/f9f70a59222bc0d0166cbe9a03eebf2a73682398))
### [0.0.2](https://github.com/nuxt-contrib/ohmyfetch/compare/v0.0.1...v0.0.2) (2020-12-09)

@@ -7,0 +15,0 @@

24

dist/index.d.ts

@@ -9,16 +9,26 @@ declare type Fetch = typeof globalThis.fetch;

}
declare type $FetchInput = RequestInfo;
interface $FetchOptions extends RequestInit {
declare type FetchRequest = RequestInfo;
interface FetchOptions extends RequestInit {
baseURL?: string;
response?: boolean;
}
declare type $Fetch<T = any> = (input: $FetchInput, opts?: $FetchOptions) => Promise<T>;
interface FetchResponse<T> extends Response {
data?: T;
}
interface $Fetch {
<T = any>(request: FetchRequest, opts?: FetchOptions): Promise<T>;
raw<T = any>(request: FetchRequest, opts?: FetchOptions): Promise<FetchResponse<T>>;
}
declare function createFetch({ fetch }: CreateFetchOptions): $Fetch;
declare class FetchError extends Error {
declare class FetchError<T = any> extends Error {
name: 'FetchError';
request?: FetchRequest;
response?: FetchResponse<T>;
data?: T;
}
declare function createFetchError<T = any>(response: Response, input: RequestInfo, data: T): FetchError;
declare function createFetchError<T = any>(request: FetchRequest, response: FetchResponse<T>): FetchError<T>;
declare const $fetch: $Fetch<any>;
declare const $fetch: $Fetch;
export { $Fetch, $FetchInput, $FetchOptions, $fetch, CreateFetchOptions, Fetch, FetchError, RequestInfo, RequestInit, Response, createFetch, createFetchError };
export { $Fetch, $fetch, CreateFetchOptions, FetchError, FetchOptions, FetchRequest, FetchResponse, createFetch, createFetchError };

@@ -5,9 +5,99 @@ 'use strict';

const destr2 = require('destr');
const ufo = require('@nuxt/ufo');
// https://github.com/fastify/secure-json-parse
// https://github.com/hapijs/bourne
var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
var JsonSigRx = /^["{[]|^-?[0-9][0-9.]{0,14}$/;
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function jsonParseTransform(key, value) {
if (key === '__proto__' || key === 'constructor') {
return;
}
const destr2__default = /*#__PURE__*/_interopDefaultLegacy(destr2);
return value;
}
function destr(val) {
if (typeof val !== 'string') {
return val;
}
var _lval = val.toLowerCase();
if (_lval === 'true') {
return true;
}
if (_lval === 'false') {
return false;
}
if (_lval === 'null') {
return null;
}
if (_lval === 'nan') {
return NaN;
}
if (_lval === 'infinity') {
return Infinity;
}
if (_lval === 'undefined') {
return undefined;
}
if (!JsonSigRx.test(val)) {
return val;
}
try {
if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {
return JSON.parse(val, jsonParseTransform);
}
return JSON.parse(val);
} catch (_e) {
return val;
}
}
var dist = destr;
function withoutTrailingSlash(input = "/") {
return input.endsWith("/") ? input.slice(0, -1) : input;
}
function hasProtocol(inputStr) {
return /^\w+:\//.test(inputStr);
}
function parseURL(input = "/") {
if (typeof input !== "string") {
if (!input || !input.url) {
throw new Error(`Invalid url: ${JSON.stringify(input)}`);
}
return input;
}
const _hasProtocol = hasProtocol(input);
const url = new URL(input, _hasProtocol ? void 0 : "default:/");
return {url, hasProtocol: _hasProtocol};
}
function joinPath(...path) {
const last = path.pop();
if (!last) {
return "/";
}
return path.map(withoutTrailingSlash).join("") + last;
}
function normalizeURL(input, stripBase) {
const {url, hasProtocol: hasProtocol2} = parseURL(input);
return !stripBase && hasProtocol2 ? url.href : url.pathname + url.search + url.hash;
}
function joinURL(input0, ...input) {
const path = input.map(parseURL);
const baseURL = parseURL(input0);
baseURL.url.pathname = joinPath(baseURL.url.pathname, ...path.map((p) => p.url.pathname));
return normalizeURL(baseURL);
}
class FetchError extends Error {

@@ -19,7 +109,13 @@ constructor() {

}
function createFetchError(response, input, data) {
const message = `${response.status} ${response.statusText} (${input.toString()})`;
function createFetchError(request, response) {
const message = `${response.status} ${response.statusText} (${request.toString()})`;
const error = new FetchError(message);
Object.defineProperty(error, "request", {get() {
return request;
}});
Object.defineProperty(error, "response", {get() {
return response;
}});
Object.defineProperty(error, "data", {get() {
return data;
return response.data;
}});

@@ -37,14 +133,19 @@ const stack = error.stack;

function createFetch({fetch}) {
return async function $fetch(input, opts) {
if (opts && opts.baseURL && typeof input === "string") {
input = ufo.joinURL(opts.baseURL, input);
const raw = async function(request, opts) {
if (opts && opts.baseURL && typeof request === "string") {
request = joinURL(opts.baseURL, request);
}
const response = await fetch(input, opts);
const response = await fetch(request, opts);
const text = await response.text();
const data = destr2__default['default'](text);
response.data = dist(text);
if (!response.ok) {
throw createFetchError(response, input, data);
throw createFetchError(request, response);
}
return data;
return response;
};
const $fetch = function(request, opts) {
return raw(request, opts).then((r) => r.data);
};
$fetch.raw = raw;
return $fetch;
}

@@ -51,0 +152,0 @@

@@ -6,4 +6,2 @@ 'use strict';

const nodeFetch = require('node-fetch');
const destr2 = require('destr');
const ufo = require('@nuxt/ufo');

@@ -13,4 +11,100 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

const nodeFetch__default = /*#__PURE__*/_interopDefaultLegacy(nodeFetch);
const destr2__default = /*#__PURE__*/_interopDefaultLegacy(destr2);
// https://github.com/fastify/secure-json-parse
// https://github.com/hapijs/bourne
var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
var JsonSigRx = /^["{[]|^-?[0-9][0-9.]{0,14}$/;
function jsonParseTransform(key, value) {
if (key === '__proto__' || key === 'constructor') {
return;
}
return value;
}
function destr(val) {
if (typeof val !== 'string') {
return val;
}
var _lval = val.toLowerCase();
if (_lval === 'true') {
return true;
}
if (_lval === 'false') {
return false;
}
if (_lval === 'null') {
return null;
}
if (_lval === 'nan') {
return NaN;
}
if (_lval === 'infinity') {
return Infinity;
}
if (_lval === 'undefined') {
return undefined;
}
if (!JsonSigRx.test(val)) {
return val;
}
try {
if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {
return JSON.parse(val, jsonParseTransform);
}
return JSON.parse(val);
} catch (_e) {
return val;
}
}
var dist = destr;
function withoutTrailingSlash(input = "/") {
return input.endsWith("/") ? input.slice(0, -1) : input;
}
function hasProtocol(inputStr) {
return /^\w+:\//.test(inputStr);
}
function parseURL(input = "/") {
if (typeof input !== "string") {
if (!input || !input.url) {
throw new Error(`Invalid url: ${JSON.stringify(input)}`);
}
return input;
}
const _hasProtocol = hasProtocol(input);
const url = new URL(input, _hasProtocol ? void 0 : "default:/");
return {url, hasProtocol: _hasProtocol};
}
function joinPath(...path) {
const last = path.pop();
if (!last) {
return "/";
}
return path.map(withoutTrailingSlash).join("") + last;
}
function normalizeURL(input, stripBase) {
const {url, hasProtocol: hasProtocol2} = parseURL(input);
return !stripBase && hasProtocol2 ? url.href : url.pathname + url.search + url.hash;
}
function joinURL(input0, ...input) {
const path = input.map(parseURL);
const baseURL = parseURL(input0);
baseURL.url.pathname = joinPath(baseURL.url.pathname, ...path.map((p) => p.url.pathname));
return normalizeURL(baseURL);
}
class FetchError extends Error {

@@ -22,7 +116,13 @@ constructor() {

}
function createFetchError(response, input, data) {
const message = `${response.status} ${response.statusText} (${input.toString()})`;
function createFetchError(request, response) {
const message = `${response.status} ${response.statusText} (${request.toString()})`;
const error = new FetchError(message);
Object.defineProperty(error, "request", {get() {
return request;
}});
Object.defineProperty(error, "response", {get() {
return response;
}});
Object.defineProperty(error, "data", {get() {
return data;
return response.data;
}});

@@ -40,14 +140,19 @@ const stack = error.stack;

function createFetch({fetch}) {
return async function $fetch(input, opts) {
if (opts && opts.baseURL && typeof input === "string") {
input = ufo.joinURL(opts.baseURL, input);
const raw = async function(request, opts) {
if (opts && opts.baseURL && typeof request === "string") {
request = joinURL(opts.baseURL, request);
}
const response = await fetch(input, opts);
const response = await fetch(request, opts);
const text = await response.text();
const data = destr2__default['default'](text);
response.data = dist(text);
if (!response.ok) {
throw createFetchError(response, input, data);
throw createFetchError(request, response);
}
return data;
return response;
};
const $fetch = function(request, opts) {
return raw(request, opts).then((r) => r.data);
};
$fetch.raw = raw;
return $fetch;
}

@@ -54,0 +159,0 @@

{
"name": "ohmyfetch",
"version": "0.0.2",
"version": "0.0.3",
"description": "oh-my-fetch",

@@ -32,4 +32,2 @@ "repository": "nuxt-contrib/ohmyfetch",

"dependencies": {
"@nuxt/ufo": "^0.0.4",
"destr": "^1.0.1",
"node-fetch": "^2.6.1"

@@ -39,2 +37,3 @@ },

"@nuxt/h2": "^0.0.14",
"@nuxt/ufo": "^0.0.4",
"@nuxtjs/eslint-config-typescript": "latest",

@@ -45,2 +44,3 @@ "@types/flat": "latest",

"@types/node-fetch": "^2.5.7",
"destr": "^1.0.1",
"eslint": "latest",

@@ -47,0 +47,0 @@ "jest": "latest",

@@ -1,8 +0,14 @@

<!-- [![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![npm version][npm-version-src]][npm-version-href]
[![Github Actions][github-actions-src]][github-actions-href]
[![Codecov][codecov-src]][codecov-href] -->
[![Codecov][codecov-src]][codecov-href]
[![bundle][bundle-src]][bundle-href]
# 😱 ohmyfetch
![ohmyfetch](https://user-images.githubusercontent.com/904724/101663230-bb578c80-3a4a-11eb-89eb-14cd3e08dd8c.png)
<!-- # 😱 ohmyfetch -->
<!-- [![npm downloads][npm-downloads-src]][npm-downloads-href] -->
## 🚀 Quick Start

@@ -33,10 +39,12 @@

![oh-my-fetch](https://media.giphy.com/media/Dn1QRA9hqMcoMz9zVZ/giphy.gif)
<details>
<summary>Spoiler</summary>
<img src="https://media.giphy.com/media/Dn1QRA9hqMcoMz9zVZ/giphy.gif">
</details>
## 🤔 Why?
### ✔️ Parse Response
## ✔️ Parsing Response
**`$fetch`:**
`$fetch` Smartly parses JSON and native valuesusing [destr](https://github.com/nuxt-contrib/destr) and fallback to text if cannot parse

@@ -47,17 +55,8 @@ ```js

- Using [destr](https://github.com/nuxt-contrib/destr)
- Smartly parse JSON and native values like `true`
- Fallback to text if cannot parse
- Secure against prototype pollution
## ✔️ Handling Errors
**`fetch`:**
`$fetch` Automatically throw errors when `response.ok` is `false` with a friendly error message and compact stack (hiding internals).
```js
const { users } = await fetch('/api/users').then(r => r.json())
```
Parsed error body is available with `error.data`. You may also use `FetchError` type.
### ✔️ Handle Errors
**`$fetch`:**
```ts

@@ -69,35 +68,22 @@ await $fetch('http://google.com/404')

- Automatically throw errors when `response.ok` is `false`
- Friendly error message with compact stack (hiding internals)
- Parsed error body is available with `error.data`
In order to bypass errors as reponse you can use `error.data`:
**`fetch`:**
```js
const resonse = await fetch('http://google.com/404')
// You need to manually check response.ok and throw an error
```ts
await $fetch(...).catch((error) => error.data)
```
### ✔️ Type Friendly
## ✔️ Type Friendly
**`$fetch`:**
Response can be type assisted:
```ts
const { article } = await $fetch<Article>(`/api/article/${id}`)
// article object is type assisted
// Auto complete working with article.id
```
- Expected response type can be specified
**`fetch`:**
## ✔️ Support baseURL
```js
const { article } = await fetch(`/api/article/${id}`).then(r => r.json())
// article type is any
```
By setting `baseURL` option `$fetch` prepends it with respecting to trailing/leading slashes and query params for baseURL using [ufo](https://github.com/nuxt-contrib/ufo):
### ✔️ Support baseURL
**`$fetch`:**
```js

@@ -107,15 +93,15 @@ await $fetch('/config', { baseURL })

- Allow making factory functions to add baseURL
- Prepend baseURL with respecting trailing/leading slashes and query params for baseURL (using [ufo](https://github.com/nuxt-contrib/ufo))
## 🍣 Access to Raw Response
**`fetch`:**
If you need to access raw response (for headers, etc), can use `$fetch.raw`:
```js
await $fetch(baseURL + '/config')
const response = await $fetch.raw('/sushi')
// response.data
// response.headers
// ...
```
### ✔️ Univeral
Supporting browsers, workers and NodeJS
## 📦 Bundler Notes

@@ -132,5 +118,5 @@

Using same name of `fetch` can be confusing since API is different but still it is a fetch so using closesest possible alternative.
Using the same name of `fetch` can be confusing since API is different but still it is a fetch so using closest possible alternative.
**Why note having default export?**
**Why not having default export?**

@@ -145,3 +131,3 @@ Default exports are always risky to be mixed with CommonJS exports.

If you need to support legacy users, can optionally transpile the library to build pipelines.
If you need to support legacy users, can optionally transpile the library in build pipeline.

@@ -164,1 +150,5 @@ ## License

[codecov-href]: https://codecov.io/gh/nuxt-contrib/ohmyfetch
[bundle-src]: https://img.shields.io/bundlephobia/minzip/ohmyfetch?style=flat-square
[bundle-href]: https://bundlephobia.com/result?p=ohmyfetch

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc