diff --git a/package.json b/package.json index b77179f790..f796465ce5 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,11 @@ "browser": { "./src/core/components/init-assets.js": false, "./src/core/runtime/config-nodejs.js": "./src/core/runtime/config-browser.js", + "./src/core/runtime/dns-nodejs.js": "./src/core/runtime/dns-browser.js", + "./src/core/runtime/fetch-nodejs.js": "./src/core/runtime/fetch-browser.js", "./src/core/runtime/libp2p-nodejs.js": "./src/core/runtime/libp2p-browser.js", "./src/core/runtime/preload-nodejs.js": "./src/core/runtime/preload-browser.js", "./src/core/runtime/repo-nodejs.js": "./src/core/runtime/repo-browser.js", - "./src/core/runtime/dns-nodejs.js": "./src/core/runtime/dns-browser.js", "./test/utils/create-repo-nodejs.js": "./test/utils/create-repo-browser.js", "stream": "readable-stream", "joi": "joi-browser" @@ -149,6 +150,7 @@ "multibase": "~0.6.0", "multihashes": "~0.4.14", "multihashing-async": "~0.5.1", + "node-fetch": "^2.3.0", "once": "^1.4.0", "peer-book": "~0.8.0", "peer-id": "~0.12.0", diff --git a/src/core/components/files-regular/add-from-url.js b/src/core/components/files-regular/add-from-url.js new file mode 100644 index 0000000000..1ad7e9d8dd --- /dev/null +++ b/src/core/components/files-regular/add-from-url.js @@ -0,0 +1,41 @@ +'use-strict' + +const { URL } = require('url') +const fetch = require('../../runtime/fetch-nodejs') + +module.exports = (self) => { + return async (url, options, callback) => { + if (typeof options === 'function') { + callback = options + options = {} + } + + let files + + try { + const parsedUrl = new URL(url) + const res = await fetch(url) + + if (!res.ok) { + throw new Error('unexpected status code: ' + res.status) + } + + // TODO: use res.body when supported + const content = Buffer.from(await res.arrayBuffer()) + const path = decodeURIComponent(parsedUrl.pathname.split('/').pop()) + + files = await self.add({ content, path }, options) + } catch (err) { + if (callback) { + return callback(err) + } + throw err + } + + if (callback) { + callback(null, files) + } + + return files + } +} diff --git a/src/core/components/files-regular/index.js b/src/core/components/files-regular/index.js index 8823d69995..879cd2a967 100644 --- a/src/core/components/files-regular/index.js +++ b/src/core/components/files-regular/index.js @@ -2,6 +2,7 @@ module.exports = self => ({ add: require('./add')(self), + addFromURL: require('./add-from-url')(self), addPullStream: require('./add-pull-stream')(self), addReadableStream: require('./add-readable-stream')(self), cat: require('./cat')(self), diff --git a/src/core/runtime/fetch-browser.js b/src/core/runtime/fetch-browser.js new file mode 100644 index 0000000000..b2f604db7c --- /dev/null +++ b/src/core/runtime/fetch-browser.js @@ -0,0 +1,3 @@ +/* eslint-env browser */ +'use strict' +module.exports = fetch diff --git a/src/core/runtime/fetch-nodejs.js b/src/core/runtime/fetch-nodejs.js new file mode 100644 index 0000000000..ca77ad8310 --- /dev/null +++ b/src/core/runtime/fetch-nodejs.js @@ -0,0 +1,2 @@ +'use strict' +module.exports = require('node-fetch') diff --git a/test/core/interface.spec.js b/test/core/interface.spec.js index 9d28ea3332..efabbc9850 100644 --- a/test/core/interface.spec.js +++ b/test/core/interface.spec.js @@ -79,15 +79,22 @@ describe('interface-ipfs-core tests', () => { }) tests.filesRegular(defaultCommonFactory, { - skip: [{ + only: ['addFromUrl'], + skip: isNode ? [{ name: 'addFromStream', reason: 'TODO: not implemented yet' }, { name: 'addFromFs', reason: 'TODO: not implemented yet' + }] : [{ + name: 'addFromStream', + reason: 'Not designed to run in the browser' + }, { + name: 'addFromFs', + reason: 'Not designed to run in the browser' }, { name: 'addFromUrl', - reason: 'TODO: not implemented yet' + reason: 'Not designed to run in the browser' }] })