ipfs-utils
Advanced tools
Comparing version 5.0.1 to 6.0.0
@@ -0,1 +1,16 @@ | ||
# [6.0.0](https://github.com/ipfs/js-ipfs-utils/compare/v5.0.1...v6.0.0) (2021-01-15) | ||
### Features | ||
* add types, gh actions and remove unused methods ([#89](https://github.com/ipfs/js-ipfs-utils/issues/89)) ([707174c](https://github.com/ipfs/js-ipfs-utils/commit/707174c131a0651677200329583bf7dca652504a)) | ||
* make urlSource compatible with new ipfs.add ([#53](https://github.com/ipfs/js-ipfs-utils/issues/53)) ([2b3ebbe](https://github.com/ipfs/js-ipfs-utils/commit/2b3ebbe86df409c1bc89d7855bf427446748b073)), closes [ipfs/js-ipfs#3195](https://github.com/ipfs/js-ipfs/issues/3195) | ||
### BREAKING CHANGES | ||
* removed globalThis and normalise-input, format-mode and format-mtime | ||
## [5.0.1](https://github.com/ipfs/js-ipfs-utils/compare/v5.0.0...v5.0.1) (2020-11-25) | ||
@@ -2,0 +17,0 @@ |
{ | ||
"name": "ipfs-utils", | ||
"version": "5.0.1", | ||
"version": "6.0.0", | ||
"description": "Package to aggregate shared logic and dependencies for the IPFS ecosystem", | ||
@@ -16,4 +16,2 @@ "main": "src/index.js", | ||
"./src/http/fetch.js": "./src/http/fetch.browser.js", | ||
"./src/text-encoder.js": "./src/text-encoder.browser.js", | ||
"./src/text-decoder.js": "./src/text-decoder.browser.js", | ||
"./src/temp-dir.js": "./src/temp-dir.browser.js", | ||
@@ -24,4 +22,13 @@ "./src/path-join.js": "./src/path-join.browser.js", | ||
}, | ||
"types": "dist/src/index.d.ts", | ||
"typesVersions": { | ||
"*": { | ||
"src/*": [ | ||
"dist/src/*" | ||
] | ||
} | ||
}, | ||
"repository": "github:ipfs/js-ipfs-utils", | ||
"scripts": { | ||
"prepare": "aegir build --no-bundle", | ||
"test": "aegir test", | ||
@@ -40,7 +47,7 @@ "test:browser": "aegir test -t browser", | ||
"dependencies": { | ||
"electron-fetch": "^1.7.2", | ||
"abort-controller": "^3.0.0", | ||
"any-signal": "^2.1.0", | ||
"buffer": "^6.0.1", | ||
"err-code": "^2.0.0", | ||
"electron-fetch": "^1.7.2", | ||
"err-code": "^2.0.3", | ||
"fs-extra": "^9.0.1", | ||
@@ -50,18 +57,27 @@ "is-electron": "^2.2.0", | ||
"it-glob": "0.0.10", | ||
"merge-options": "^2.0.0", | ||
"nanoid": "^3.1.3", | ||
"it-to-stream": "^0.1.2", | ||
"merge-options": "^3.0.4", | ||
"nanoid": "^3.1.20", | ||
"native-abort-controller": "0.0.3", | ||
"native-fetch": "^2.0.0", | ||
"node-fetch": "^2.6.0", | ||
"stream-to-it": "^0.2.0", | ||
"it-to-stream": "^0.1.2" | ||
"native-fetch": "2.0.1", | ||
"node-fetch": "^2.6.1", | ||
"stream-to-it": "^0.2.2", | ||
"web-encoding": "^1.0.6" | ||
}, | ||
"devDependencies": { | ||
"aegir": "^28.1.0", | ||
"delay": "^4.3.0", | ||
"it-all": "^1.0.2", | ||
"it-drain": "^1.0.1", | ||
"it-last": "^1.0.2", | ||
"uint8arrays": "^1.1.0" | ||
"@types/err-code": "^2.0.0", | ||
"@types/fs-extra": "^9.0.5", | ||
"aegir": "^30.3.0", | ||
"delay": "^4.4.0", | ||
"it-all": "^1.0.4", | ||
"it-drain": "^1.0.3", | ||
"it-last": "^1.0.4", | ||
"uint8arrays": "^2.0.5" | ||
}, | ||
"eslintConfig": { | ||
"extends": "ipfs", | ||
"env": { | ||
"worker": true | ||
} | ||
}, | ||
"contributors": [ | ||
@@ -71,4 +87,4 @@ "Hugo Dias <hugomrdias@gmail.com>", | ||
"Alan Shaw <alan.shaw@protocol.ai>", | ||
"Irakli Gozalishvili <contact@gozala.io>", | ||
"Hector Sanjuan <code@hector.link>", | ||
"Irakli Gozalishvili <contact@gozala.io>", | ||
"bluelovers <codelovers@users.sourceforge.net>", | ||
@@ -75,0 +91,0 @@ "Marcin Rataj <lidel@lidel.org>", |
@@ -10,3 +10,3 @@ 'use strict' | ||
const IS_NODE = typeof require === 'function' && typeof process !== 'undefined' && typeof process.release !== 'undefined' && process.release.name === 'node' && !IS_ELECTRON | ||
// eslint-disable-next-line no-undef | ||
// @ts-ignore - we either ignore worker scope or dom scope | ||
const IS_WEBWORKER = typeof importScripts === 'function' && typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope | ||
@@ -13,0 +13,0 @@ const IS_TEST = typeof process !== 'undefined' && typeof process.env !== 'undefined' && process.env.NODE_ENV === 'test' |
@@ -8,4 +8,4 @@ 'use strict' | ||
} else { | ||
// use window.fetch if it is available, fall back to node-fetch if not | ||
// use window.fetch if it is available, fall back to node-fetch if not | ||
module.exports = require('native-fetch') | ||
} |
@@ -11,3 +11,3 @@ 'use strict' | ||
* | ||
* @param {Iterable | AsyncIterable | string} paths - File system path(s) to glob from | ||
* @param {Iterable<string> | AsyncIterable<string> | string} paths - File system path(s) to glob from | ||
* @param {Object} [options] - Optional options | ||
@@ -20,4 +20,4 @@ * @param {boolean} [options.recursive] - Recursively glob all paths in directories | ||
* @param {boolean} [options.preserveMtime] - preserve mtime | ||
* @param {boolean} [options.mode] - mode to use - if preserveMode is true this will be ignored | ||
* @param {boolean} [options.mtime] - mtime to use - if preserveMtime is true this will be ignored | ||
* @param {number} [options.mode] - mode to use - if preserveMode is true this will be ignored | ||
* @param {Date} [options.mtime] - mtime to use - if preserveMtime is true this will be ignored | ||
* @yields {Object} File objects in the form `{ path: String, content: AsyncIterator<Buffer> }` | ||
@@ -58,2 +58,3 @@ */ | ||
if (options.preserveMode) { | ||
// @ts-ignore | ||
mode = stat.mode | ||
@@ -65,2 +66,3 @@ } | ||
if (options.preserveMtime) { | ||
// @ts-ignore | ||
mtime = stat.mtime | ||
@@ -89,2 +91,3 @@ } | ||
// @ts-ignore | ||
async function * toGlobSource ({ path, type, prefix, mode, mtime, preserveMode, preserveMtime }, options) { | ||
@@ -143,2 +146,5 @@ options = options || {} | ||
/** | ||
* @param {string} path | ||
*/ | ||
const toPosix = path => path.replace(/\\/g, '/') |
'use strict' | ||
const Http = require('../http') | ||
const HTTP = require('../http') | ||
module.exports = async function * urlSource (url, options) { | ||
const http = new Http() | ||
const response = await http.get(url, options) | ||
yield { | ||
/** | ||
* | ||
* @param {string} url | ||
* @param {import("../types").HTTPOptions} [options] | ||
* @returns {{ path: string; content?: AsyncIterable<Uint8Array> }} | ||
*/ | ||
const urlSource = (url, options) => { | ||
return { | ||
path: decodeURIComponent(new URL(url).pathname.split('/').pop() || ''), | ||
content: response.iterator() | ||
content: readURLContent(url, options) | ||
} | ||
} | ||
/** | ||
* | ||
* @param {string} url | ||
* @param {import("../types").HTTPOptions} [options] | ||
* @returns {AsyncIterable<Uint8Array>} | ||
*/ | ||
async function * readURLContent (url, options) { | ||
const http = new HTTP() | ||
const response = await http.get(url, options) | ||
yield * response.iterator() | ||
} | ||
module.exports = urlSource |
301
src/http.js
@@ -12,2 +12,16 @@ /* eslint-disable no-undef */ | ||
/** | ||
* @typedef {import('electron-fetch').Response} Response | ||
* @typedef {import('stream').Readable} NodeReadableStream | ||
* @typedef {import('stream').Duplex} NodeDuplexStream | ||
* @typedef {import('./types').HTTPOptions} HTTPOptions | ||
*/ | ||
/** | ||
* @template TResponse | ||
* @param {Promise<TResponse>} promise | ||
* @param {number | undefined} ms | ||
* @param {AbortController} abortController | ||
* @returns {Promise<TResponse>} | ||
*/ | ||
const timeout = (promise, ms, abortController) => { | ||
@@ -34,4 +48,10 @@ if (ms === undefined) { | ||
/** | ||
* @param {(value: any) => void } next | ||
*/ | ||
const after = (next) => { | ||
return (res) => { | ||
/** | ||
* @param {any} res | ||
*/ | ||
const fn = (res) => { | ||
clearTimeout(timeoutID) | ||
@@ -46,2 +66,3 @@ | ||
} | ||
return fn | ||
} | ||
@@ -55,34 +76,13 @@ | ||
const defaults = { | ||
headers: {}, | ||
throwHttpErrors: true, | ||
credentials: 'same-origin', | ||
transformSearchParams: p => p | ||
credentials: 'same-origin' | ||
} | ||
/** | ||
* @typedef {Object} APIOptions - creates a new type named 'SpecialType' | ||
* @property {any} [body] - Request body | ||
* @property {Object} [json] - JSON shortcut | ||
* @property {string} [method] - GET, POST, PUT, DELETE, etc. | ||
* @property {string} [base] - The base URL to use in case url is a relative URL | ||
* @property {Headers|Record<string, string>} [headers] - Request header. | ||
* @property {number} [timeout] - Amount of time until request should timeout in ms. | ||
* @property {AbortSignal} [signal] - Signal to abort the request. | ||
* @property {URLSearchParams|Object} [searchParams] - URL search param. | ||
* @property {string} [credentials] | ||
* @property {boolean} [throwHttpErrors] | ||
* @property {function(URLSearchParams): URLSearchParams } [transformSearchParams] | ||
* @property {function(any): any} [transform] - When iterating the response body, transform each chunk with this function. | ||
* @property {function(Response): Promise<void>} [handleError] - Handle errors | ||
* @property {function({total:number, loaded:number, lengthComputable:boolean}):void} [onUploadProgress] - Can be passed to track upload progress. | ||
* Note that if this option in passed underlying request will be performed using `XMLHttpRequest` and response will not be streamed. | ||
*/ | ||
class HTTP { | ||
/** | ||
* | ||
* @param {APIOptions} options | ||
* @param {HTTPOptions} options | ||
*/ | ||
constructor (options = {}) { | ||
/** @type {APIOptions} */ | ||
/** @type {HTTPOptions} */ | ||
this.opts = merge(defaults, options) | ||
@@ -94,10 +94,10 @@ } | ||
* | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} options | ||
* @returns {Promise<Response>} | ||
*/ | ||
async fetch (resource, options = {}) { | ||
/** @type {APIOptions} */ | ||
/** @type {HTTPOptions} */ | ||
const opts = merge(this.opts, options) | ||
opts.headers = new Headers(opts.headers) | ||
const headers = new Headers(opts.headers) | ||
@@ -109,35 +109,42 @@ // validate resource type | ||
// validate resource format and normalize with prefixUrl | ||
if (opts.base && typeof opts.base === 'string' && typeof resource === 'string') { | ||
if (resource.startsWith('/')) { | ||
throw new Error('`resource` must not begin with a slash when using `base`') | ||
} | ||
const url = new URL(resource.toString(), opts.base) | ||
if (!opts.base.endsWith('/')) { | ||
opts.base += '/' | ||
const { | ||
searchParams, | ||
transformSearchParams, | ||
json | ||
} = opts | ||
if (searchParams) { | ||
if (typeof transformSearchParams === 'function') { | ||
// @ts-ignore | ||
url.search = transformSearchParams(new URLSearchParams(opts.searchParams)) | ||
} else { | ||
// @ts-ignore | ||
url.search = new URLSearchParams(opts.searchParams) | ||
} | ||
resource = opts.base + resource | ||
} | ||
// TODO: try to remove the logic above or fix URL instance input without trailing '/' | ||
const url = new URL(resource, opts.base) | ||
if (opts.searchParams) { | ||
url.search = opts.transformSearchParams(new URLSearchParams(opts.searchParams)) | ||
} | ||
if (opts.json !== undefined) { | ||
if (json) { | ||
opts.body = JSON.stringify(opts.json) | ||
opts.headers.set('content-type', 'application/json') | ||
headers.set('content-type', 'application/json') | ||
} | ||
const abortController = new AbortController() | ||
// @ts-ignore | ||
const signal = anySignal([abortController.signal, opts.signal]) | ||
const response = await timeout(fetch(url.toString(), { | ||
...opts, | ||
signal, | ||
timeout: undefined | ||
}), opts.timeout, abortController) | ||
const response = await timeout( | ||
fetch( | ||
url.toString(), | ||
{ | ||
...opts, | ||
signal, | ||
timeout: undefined, | ||
headers | ||
} | ||
), | ||
opts.timeout, | ||
abortController | ||
) | ||
@@ -152,9 +159,3 @@ if (!response.ok && opts.throwHttpErrors) { | ||
response.iterator = function () { | ||
const it = streamToAsyncIterator(response.body) | ||
if (!isAsyncIterator(it)) { | ||
throw new Error('Can\'t convert fetch body into a Async Iterator:') | ||
} | ||
return it | ||
return fromStream(response.body) | ||
} | ||
@@ -176,59 +177,44 @@ | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} options | ||
* @returns {Promise<Response>} | ||
*/ | ||
post (resource, options = {}) { | ||
return this.fetch(resource, { | ||
...options, | ||
method: 'POST' | ||
}) | ||
return this.fetch(resource, { ...options, method: 'POST' }) | ||
} | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} options | ||
* @returns {Promise<Response>} | ||
*/ | ||
get (resource, options = {}) { | ||
return this.fetch(resource, { | ||
...options, | ||
method: 'GET' | ||
}) | ||
return this.fetch(resource, { ...options, method: 'GET' }) | ||
} | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} options | ||
* @returns {Promise<Response>} | ||
*/ | ||
put (resource, options = {}) { | ||
return this.fetch(resource, { | ||
...options, | ||
method: 'PUT' | ||
}) | ||
return this.fetch(resource, { ...options, method: 'PUT' }) | ||
} | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} options | ||
* @returns {Promise<Response>} | ||
*/ | ||
delete (resource, options = {}) { | ||
return this.fetch(resource, { | ||
...options, | ||
method: 'DELETE' | ||
}) | ||
return this.fetch(resource, { ...options, method: 'DELETE' }) | ||
} | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} options | ||
* @returns {Promise<Response>} | ||
*/ | ||
options (resource, options = {}) { | ||
return this.fetch(resource, { | ||
...options, | ||
method: 'OPTIONS' | ||
}) | ||
return this.fetch(resource, { ...options, method: 'OPTIONS' }) | ||
} | ||
@@ -240,4 +226,4 @@ } | ||
* | ||
* @param {AsyncGenerator<Uint8Array, void, any>} source | ||
* @returns {AsyncGenerator<Object, void, any>} | ||
* @param {AsyncIterable<Uint8Array>} source | ||
* @returns {AsyncIterable<any>} | ||
*/ | ||
@@ -267,56 +253,97 @@ const ndjson = async function * (source) { | ||
const streamToAsyncIterator = function (source) { | ||
if (isAsyncIterator(source)) { | ||
// Workaround for https://github.com/node-fetch/node-fetch/issues/766 | ||
if (Object.prototype.hasOwnProperty.call(source, 'readable') && Object.prototype.hasOwnProperty.call(source, 'writable')) { | ||
const iter = source[Symbol.asyncIterator]() | ||
/** | ||
* Stream to AsyncIterable | ||
* | ||
* @template TChunk | ||
* @param {ReadableStream<TChunk> | NodeReadableStream | null} source | ||
* @returns {AsyncIterable<TChunk>} | ||
*/ | ||
const fromStream = (source) => { | ||
// Workaround for https://github.com/node-fetch/node-fetch/issues/766 | ||
if (isNodeReadableStream(source)) { | ||
const iter = source[Symbol.asyncIterator]() | ||
return { | ||
[Symbol.asyncIterator] () { | ||
return { | ||
next: iter.next.bind(iter), | ||
return (value) { | ||
source.destroy() | ||
if (typeof iter.return === 'function') { | ||
return iter.return() | ||
} | ||
return Promise.resolve({ done: true, value }) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
const wrapper = { | ||
next: iter.next.bind(iter), | ||
return: () => { | ||
source.destroy() | ||
return iter.return() | ||
}, | ||
[Symbol.asyncIterator]: () => { | ||
return wrapper | ||
if (isWebReadableStream(source)) { | ||
const reader = source.getReader() | ||
return (async function * () { | ||
try { | ||
while (true) { | ||
// Read from the stream | ||
const { done, value } = await reader.read() | ||
// Exit if we're done | ||
if (done) return | ||
// Else yield the chunk | ||
if (value) { | ||
yield value | ||
} | ||
} | ||
} finally { | ||
reader.releaseLock() | ||
} | ||
})() | ||
} | ||
return wrapper | ||
} | ||
if (isAsyncIterable(source)) { | ||
return source | ||
} | ||
const reader = source.getReader() | ||
throw new TypeError('Body can\'t be converted to AsyncIterable') | ||
} | ||
return { | ||
next () { | ||
return reader.read() | ||
}, | ||
return () { | ||
reader.releaseLock() | ||
return {} | ||
}, | ||
[Symbol.asyncIterator] () { | ||
return this | ||
} | ||
} | ||
/** | ||
* Check if it's an AsyncIterable | ||
* | ||
* @template {unknown} TChunk | ||
* @template {any} Other | ||
* @param {Other|AsyncIterable<TChunk>} value | ||
* @returns {value is AsyncIterable<TChunk>} | ||
*/ | ||
const isAsyncIterable = (value) => { | ||
return typeof value === 'object' && | ||
value !== null && | ||
typeof /** @type {any} */(value)[Symbol.asyncIterator] === 'function' | ||
} | ||
const isAsyncIterator = (obj) => { | ||
return typeof obj === 'object' && | ||
obj !== null && | ||
// typeof obj.next === 'function' && | ||
typeof obj[Symbol.asyncIterator] === 'function' | ||
/** | ||
* Check for web readable stream | ||
* | ||
* @template {unknown} TChunk | ||
* @template {any} Other | ||
* @param {Other|ReadableStream<TChunk>} value | ||
* @returns {value is ReadableStream<TChunk>} | ||
*/ | ||
const isWebReadableStream = (value) => { | ||
return value && typeof /** @type {any} */(value).getReader === 'function' | ||
} | ||
/** | ||
* @param {any} value | ||
* @returns {value is NodeReadableStream} | ||
*/ | ||
const isNodeReadableStream = (value) => | ||
Object.prototype.hasOwnProperty.call(value, 'readable') && | ||
Object.prototype.hasOwnProperty.call(value, 'writable') | ||
HTTP.HTTPError = HTTPError | ||
HTTP.TimeoutError = TimeoutError | ||
HTTP.streamToAsyncIterator = streamToAsyncIterator | ||
HTTP.streamToAsyncIterator = fromStream | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} [options] | ||
* @returns {Promise<Response>} | ||
@@ -327,4 +354,4 @@ */ | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} [options] | ||
* @returns {Promise<Response>} | ||
@@ -335,4 +362,4 @@ */ | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} [options] | ||
* @returns {Promise<Response>} | ||
@@ -343,4 +370,4 @@ */ | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} [options] | ||
* @returns {Promise<Response>} | ||
@@ -351,4 +378,4 @@ */ | ||
/** | ||
* @param {string | URL | Request} resource | ||
* @param {APIOptions} options | ||
* @param {string | Request} resource | ||
* @param {HTTPOptions} [options] | ||
* @returns {Promise<Response>} | ||
@@ -355,0 +382,0 @@ */ |
@@ -20,2 +20,5 @@ 'use strict' | ||
class HTTPError extends Error { | ||
/** | ||
* @param {import('electron-fetch').Response} response | ||
*/ | ||
constructor (response) { | ||
@@ -22,0 +25,0 @@ super(response.statusText) |
'use strict' | ||
/* eslint-env browser */ | ||
const { TimeoutError, AbortError } = require('./error') | ||
const { Request, Response, Headers } = require('../fetch') | ||
const { Response, Request, Headers, default: fetch } = require('../fetch') | ||
/** | ||
* @typedef {RequestInit & ExtraFetchOptions} FetchOptions | ||
* @typedef {Object} ExtraFetchOptions | ||
* @property {number} [timeout] | ||
* @property {URLSearchParams} [searchParams] | ||
* @property {function({total:number, loaded:number, lengthComputable:boolean}):void} [onUploadProgress] | ||
* @property {string} [overrideMimeType] | ||
* @returns {Promise<Response>} | ||
* @typedef {import('../types').FetchOptions} FetchOptions | ||
* @typedef {import('../types').ProgressFn} ProgressFn | ||
*/ | ||
/** | ||
* @param {string|URL} url | ||
* Fetch with progress | ||
* | ||
* @param {string | Request} url | ||
* @param {FetchOptions} [options] | ||
* @returns {Promise<Response>} | ||
* @returns {Promise<ResponseWithURL>} | ||
*/ | ||
@@ -26,5 +22,6 @@ const fetchWithProgress = (url, options = {}) => { | ||
const { timeout } = options | ||
if (timeout > 0 && timeout < Infinity) { | ||
request.timeout = options.timeout | ||
const { timeout, headers } = options | ||
if (timeout && timeout > 0 && timeout < Infinity) { | ||
request.timeout = timeout | ||
} | ||
@@ -36,4 +33,4 @@ | ||
if (options.headers) { | ||
for (const [name, value] of options.headers.entries()) { | ||
if (headers) { | ||
for (const [name, value] of new Headers(headers)) { | ||
request.setRequestHeader(name, value) | ||
@@ -96,3 +93,3 @@ } | ||
request.send(options.body) | ||
request.send(/** @type {BodyInit} */(options.body)) | ||
}) | ||
@@ -103,2 +100,6 @@ } | ||
/** | ||
* @param {string | Request} url | ||
* @param {FetchOptions} options | ||
*/ | ||
const fetchWith = (url, options = {}) => | ||
@@ -109,7 +110,5 @@ (options.onUploadProgress != null) | ||
exports.fetch = fetchWith | ||
exports.Request = Request | ||
exports.Headers = Headers | ||
/** | ||
* Parse Headers from a XMLHttpRequest | ||
* | ||
* @param {string} input | ||
@@ -133,3 +132,3 @@ * @returns {Headers} | ||
* @param {string} url | ||
* @param {string|Blob|ArrayBufferView|ArrayBuffer|FormData|ReadableStream<Uint8Array>} body | ||
* @param {BodyInit} body | ||
* @param {ResponseInit} options | ||
@@ -142,1 +141,8 @@ */ | ||
} | ||
module.exports = { | ||
fetch: fetchWith, | ||
Request, | ||
Headers, | ||
ResponseWithURL | ||
} |
@@ -1,27 +0,17 @@ | ||
// @ts-check | ||
'use strict' | ||
const { Request, Response, Headers, default: nodeFetch } = require('../fetch') | ||
const { Request, Response, Headers, default: nativeFetch } = require('../fetch') | ||
// @ts-ignore | ||
const toStream = require('it-to-stream') | ||
const { Buffer } = require('buffer') | ||
/** | ||
* @typedef {RequestInit & ExtraFetchOptions} FetchOptions | ||
* @typedef {import('electron-fetch').BodyInit} BodyInit | ||
* @typedef {import('stream').Readable} NodeReadableStream | ||
* | ||
* @typedef {import('stream').Readable} Readable | ||
* @typedef {Object} LoadProgress | ||
* @property {number} total | ||
* @property {number} loaded | ||
* @property {boolean} lengthComputable | ||
* @typedef {Object} ExtraFetchOptions | ||
* @property {number} [timeout] | ||
* @property {URLSearchParams} [searchParams] | ||
* @property {function(LoadProgress):void} [onUploadProgress] | ||
* @property {function(LoadProgress):void} [onDownloadProgress] | ||
* @property {string} [overrideMimeType] | ||
* @returns {Promise<Response>} | ||
* @typedef {import('../types').FetchOptions} FetchOptions | ||
* @typedef {import('../types').ProgressFn} ProgressFn | ||
*/ | ||
/** | ||
* @param {string|URL} url | ||
* @param {string|Request} url | ||
* @param {FetchOptions} [options] | ||
@@ -32,8 +22,4 @@ * @returns {Promise<Response>} | ||
// @ts-ignore | ||
nodeFetch(url, withUploadProgress(options)) | ||
nativeFetch(url, withUploadProgress(options)) | ||
exports.fetch = fetch | ||
exports.Request = Request | ||
exports.Headers = Headers | ||
/** | ||
@@ -47,8 +33,13 @@ * Takes fetch options and wraps request body to track upload progress if | ||
const withUploadProgress = (options) => { | ||
const { onUploadProgress } = options | ||
if (onUploadProgress) { | ||
const { onUploadProgress, body } = options | ||
if (onUploadProgress && body) { | ||
// This works around the fact that electron-fetch serializes `Uint8Array`s | ||
// and `ArrayBuffer`s to strings. | ||
const content = normalizeBody(body) | ||
const rsp = new Response(content) | ||
const source = iterateBodyWithProgress(/** @type {NodeReadableStream} */(rsp.body), onUploadProgress) | ||
return { | ||
...options, | ||
// @ts-ignore | ||
body: bodyWithUploadProgress(options, onUploadProgress) | ||
body: toStream.readable(source) | ||
} | ||
@@ -61,27 +52,6 @@ } else { | ||
/** | ||
* Takes request `body` and `onUploadProgress` handler and returns wrapped body | ||
* that as consumed will report progress to supplied `onUploadProgress` handler. | ||
* | ||
* @param {FetchOptions} init | ||
* @param {function(LoadProgress):void} onUploadProgress | ||
* @returns {Readable} | ||
* @param {BodyInit} input | ||
* @returns {Blob | FormData | URLSearchParams | ReadableStream<Uint8Array> | string | NodeReadableStream | Buffer} | ||
*/ | ||
const bodyWithUploadProgress = (init, onUploadProgress) => { | ||
// This works around the fact that electron-fetch serializes `Uint8Array`s | ||
// and `ArrayBuffer`s to strings. | ||
const content = normalizeBody(init.body) | ||
// @ts-ignore - Response does not accept node `Readable` streams. | ||
const { body } = new Response(content, init) | ||
// @ts-ignore - Unlike standard Response, node-fetch `body` has a differnt | ||
// type see: see https://github.com/node-fetch/node-fetch/blob/master/src/body.js | ||
const source = iterateBodyWithProgress(body, onUploadProgress) | ||
return toStream.readable(source) | ||
} | ||
/** | ||
* @param {BodyInit} [input] | ||
* @returns {Buffer|Readable|Blob|null} | ||
*/ | ||
const normalizeBody = (input = null) => { | ||
const normalizeBody = (input) => { | ||
if (input instanceof ArrayBuffer) { | ||
@@ -93,8 +63,4 @@ return Buffer.from(input) | ||
return Buffer.from(input) | ||
} else { | ||
// @ts-ignore - Could be FormData|URLSearchParams|ReadableStream<Uint8Array> | ||
// however electron-fetch does not support either of those types and | ||
// node-fetch normalizes those to node streams. | ||
return input | ||
} | ||
return input | ||
} | ||
@@ -107,8 +73,7 @@ | ||
* | ||
* @param {Buffer|null|Readable} body | ||
* @param {function(LoadProgress):void} onUploadProgress | ||
* @param {NodeReadableStream | null} body | ||
* @param {ProgressFn} onUploadProgress | ||
* @returns {AsyncIterable<Buffer>} | ||
*/ | ||
const iterateBodyWithProgress = async function * (body, onUploadProgress) { | ||
/** @type {Buffer|null|Readable} */ | ||
if (body == null) { | ||
@@ -132,1 +97,7 @@ onUploadProgress({ total: 0, loaded: 0, lengthComputable: true }) | ||
} | ||
module.exports = { | ||
fetch, | ||
Request, | ||
Headers | ||
} |
'use strict' | ||
/** | ||
* @param {string[]} args | ||
*/ | ||
function join (...args) { | ||
@@ -4,0 +7,0 @@ if (args.length === 0) { |
'use strict' | ||
module.exports = require('path').join | ||
const { join } = require('path') | ||
module.exports = join |
'use strict' | ||
const globalThis = require('./globalthis') | ||
module.exports = { | ||
@@ -6,0 +4,0 @@ supportsFileReader: typeof self !== 'undefined' && 'FileReader' in self, |
@@ -8,3 +8,3 @@ 'use strict' | ||
* | ||
* @param {function(string): string} transform - Transform function to add prefixes or sufixes to the unique id | ||
* @param {(uuid: string) => string} transform - Transform function to add prefixes or sufixes to the unique id | ||
* @returns {string} - Full real path to a temporary folder | ||
@@ -11,0 +11,0 @@ */ |
@@ -11,3 +11,3 @@ 'use strict' | ||
* | ||
* @param {function(string): string} transform - Transform function to add prefixes or sufixes to the unique id | ||
* @param {(uuid: string) => string} [transform=(p) => p] - Transform function to add prefixes or sufixes to the unique id | ||
* @returns {string} - Full real path to a temporary folder | ||
@@ -14,0 +14,0 @@ */ |
'use strict' | ||
module.exports = require('util').TextDecoder | ||
module.exports = require('web-encoding').TextDecoder |
'use strict' | ||
module.exports = require('util').TextEncoder | ||
const { TextEncoder } = require('web-encoding') | ||
module.exports = TextEncoder |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72045
64
1334
17
8
4
+ Addedweb-encoding@^1.0.6
+ Added@zxing/text-encoding@0.9.0(transitive)
+ Addedavailable-typed-arrays@1.0.7(transitive)
+ Addedcall-bind@1.0.7(transitive)
+ Addedfor-each@0.3.3(transitive)
+ Addedhas-tostringtag@1.0.2(transitive)
+ Addedis-arguments@1.1.1(transitive)
+ Addedis-callable@1.2.7(transitive)
+ Addedis-generator-function@1.0.10(transitive)
+ Addedis-typed-array@1.1.13(transitive)
+ Addedmerge-options@3.0.4(transitive)
+ Addedpossible-typed-array-names@1.0.0(transitive)
+ Addedset-function-length@1.2.2(transitive)
+ Addedutil@0.12.5(transitive)
+ Addedweb-encoding@1.1.5(transitive)
+ Addedwhich-typed-array@1.1.15(transitive)
- Removedmerge-options@2.0.0(transitive)
Updatederr-code@^2.0.3
Updatedmerge-options@^3.0.4
Updatednanoid@^3.1.20
Updatednative-fetch@2.0.1
Updatednode-fetch@^2.6.1
Updatedstream-to-it@^0.2.2