Giter VIP home page Giter VIP logo

js-ipfs-utils's Introduction

ipfs-utils

ipfs.tech Discuss codecov CI

Package to aggregate shared logic and dependencies for the IPFS ecosystem

Table of contents

Install

$ npm i ipfs-utils

Browser <script> tag

Loading this module through a script tag will make it's exports available as IpfsUtils in the global namespace.

<script src="https://unpkg.com/ipfs-utils/dist/index.min.js"></script>

ipfs-utils aims to provide single function default export per file (with a few exceptions) scoped in 3 general categories:

  • General use
  • Data structs wrangling (arrays, objects, streams, etc)
  • IPFS core subsystems

General use and Data structs wrangling should try to be just re-exports of community packages.

The IPFS ecosystem has lots of repos with it comes several problems like:

  • Domain logic dedupe - all interface-core implementations shared a lot of logic like validation, streams handling, etc.
  • Dependencies management - it's really easy with so many repos for dependencies to go out of control, they become outdated, different repos use different modules to do the same thing (like merging defaults options), browser bundles ends up with multiple versions of the same package, bumping versions is cumbersome to do because we need to go through several repos, etc.

These problems are the motivation for this package, having shared logic in this package avoids creating cyclic dependencies, centralizes common use modules/functions (exactly like aegir does for the tooling), semantic versioning for 3rd party dependencies is handled in one single place (a good example is going from streams 2 to 3) and maintainers should only care about having ipfs-utils updated.

Usage

Each function should be imported directly.

const validateAddInput = require('ipfs-utils/src/files/add-input-validation')

validateAddInput(Buffer.from('test'))
// true

API Docs

License

Licensed under either of

Contribute

Contributions welcome! Please check out the issues.

Also see our contributing document for more information on how we work, and about contributing in general.

Please be aware that all interactions related to this repo are subject to the IPFS Code of Conduct.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

js-ipfs-utils's People

Contributors

achingbrain avatar alanshaw avatar bluelovers avatar dependabot-preview[bot] avatar dependabot[bot] avatar gobengo avatar gozala avatar hsanjuan avatar hugomrdias avatar ipfs-mgmt-read-write[bot] avatar leoherzog avatar lidel avatar oliveriosousa avatar roderik avatar semantic-release-bot avatar vasco-santos avatar web-flow avatar web3-bot avatar yurtsiv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-ipfs-utils's Issues

TypeError: RequestInit: duplex option is required when sending a body.

Updating to node v18.14.0
NPM: 9.4.2

I have this error when pushing files to IPFS

error - TypeError: RequestInit: duplex option is required when sending a body.

at Object.fetch (node:internal/deps/undici/undici:14152:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Client.fetch (/node_modules/ipfs-utils/src/http.js:132:22)
at async Object.addAll (/node_modules/ipfs-http-client/src/add-all.js:36:17)
at async handler (webpack-internal:///(api)/./src/pages/api/sendToIPFS.ts:35:22)

Add API docs

I'm using this module all the time now and would rather not have to refer to the code each time I need to check where something is or what it's called or how it works.

Move http class into ipfs-http-client

Do we use this anywhere else? Does it really need to be here? We need to do things that make it less of a general-purpose http request module like restrict it only to POST requests etc so I'm not sure it belongs here any more.

node-fetch missing in the dependency list

Problem

This lib requires native-fetch which declares node-fetch as its peerDep. But node-fetch is not in the deps list of this lib. Should we expect the app that requires this lib to install node-fetch or should we add node-fetch to this lib's deps list?

Disclaimer: I did not require this lib directly but installed it when using ipfs. So I am not sure at which level in the dependency tree should we add node-fetch as a direct dependency. I am asking here because this lib directly requires native-fetch

`electron-fetch` dependency is not ESM compatible

This issue originated on the js-ipfs repo, where a bug was reported that the library wouldn't properly run with Vite, as electron somehow got required (ipfs/js-ipfs#4011 (comment)).

After some diging, I found that electron-fetch is a dependency in this (js-ipfs-utils) library and that is a Node library, importing things like url and http, which are not usable in a browser.

I think for the ESM build of this package, electron-fetch shouldn't be included at all, but I'm not too familiar with how the different builds (in combination with environments) work.

TypeScript declarations broken in 9.0.4

Hello,

after recent clean install of project dependencies (after removal of package-lock) we stumbled upon a build failure:

node_modules/ipfs-utils/dist/src/files/glob-source.d.ts:10:14 - error TS2503: Cannot find namespace 'fs'.

10     content: fs.ReadStream | undefined;

After examining the contents of that file, it looks like the fs has no reference. It worked in 9.0.2, so I downgraded and found that there's a missing part at the top:

/// <reference types="node" />

that causes the build to fail.

I'm not too sure what changed between the versions, but the downgrade definitely did the trick.

HTTPOptions body type does not allow FormData

The HTTPOptions type extends FetchOptions which extends RequestInit from electron-fetch, which has a body type of Stream | string | Blob | Buffer | null which does not include FormData.

In js-IPFS we transform multipart requests into FormData objects in the browser, which TS then says cannot be used with the http module exported by this module, since the types in electron-fetch say FormData is not a supported body type.

Bug: Too much event listeners attached to an AbortSignal

Let's assume you call ipfs.dag.get(cid, '/s/o/m/e/v/e/r/y/l/o/n/g/p/a/t/h', {signal: abortSignal}) where ipfs is an IPFS HTTP Client. The control flow would eventually go to ipfs-http-client resolve function, and then end up in src/http.js fetch function of this package.

Every path element would add an event listener to the original abortSignal. Eventually, if the path is long enough, Node.js starts emitting MaxListenersExceededWarning warnings. I consider this a bug.

Now any-signal library allows you to clear event listeners after use. The solution to the warnings problem might be to call signal.clear after response is done. I would happily contribute, yet any-signal can not really be used here due to CJS/ESM incompatibility: You can not use ESM any-signal from CJS js-ipfs-utils package. See also: #266

Defer to native-fetch whenever `ELECTRON_RUN_AS_NODE` is set

You guys are using electron-fetch whenever the is-electron package detects if it is running in an electron process (particularly, the main process). However, is-electron seems to be returning true even when in a process that has been forked from electron's main process as a node server.

This is currently what I am trying to set up in my own application, however, since you can't access electron from within a forked process, attempting to load electron-fetch results in an error wherein electron claims that it hasn't been installed properly.

The environment variable ELECTRON_RUN_AS_NODE is used to observe when a process is running as a fork from main, so I was thinking an additional condition could be added to defer to native-fetch whenever it is set.

NodeJS and Electron conflict

Env:

  • Debian Buster
  • latest nvm
  • latest yarn
  • node v15
  • latest ipfs-core

I try to use js-ipfs while testing with NodeJS.
As a dependency of ipfs-core, ipfs-utils is installed (dev dependency)
https://github.com/ipfs/js-ipfs-utils/blob/master/src/http/fetch.js

This code check whether or not XMLHttpRequest is available in node and redirect to fetch.browser when available.
However my environment is node and ipfs-utils crashes as fetch.browser requires the global browser fetch.
I could suggest to enhance the initial statement with the following to redirect to fetch.node

if (typeof XMLHttpRequest === 'function' && typeof fetch === 'function') {
  module.exports = require('./fetch.browser')

Thanks

auto-installing peerDependencies in npm@7 means `ipfs-utils` installs `react-native` everywhere.

npm ls react-native 
[email protected] /Users/oli/Code/vasco-santos/ipfs-car
└─┬ [email protected]
  └─┬ [email protected]
    └─┬ [email protected]
      └─┬ [email protected]
        └─┬ [email protected]

a trimmed down look at the node_modules dir after npm install with npm@7 in a project that depends on ipfs-utils now has >100MiB of react-native deps forced on it.

ncdu 1.15.1
--- /Users/oli/Code/vasco-santos/ipfs-car/node_modules ---   
   40.2 MiB [######    ] /react-native
   38.3 MiB [######    ] /jsc-android
   20.1 MiB [###       ] /hermes-engine
    6.7 MiB [#         ] /@react-native-community
    4.1 MiB [          ] /react-devtools-core
    3.1 MiB [          ] /flow-parser

npm@7 started forcing everyone to install the cumulative peerDependencies for any that are not explcitly depended on.

Automatically installing peer dependencies is an exciting new feature introduced in npm 7.
– https://github.blog/2021-02-02-npm-7-is-now-generally-available/#peer-dependencies

the workaround is to npm i --legacy-peer-deps but it seems awkward to expect all consumers to do that.

The culprit (aside from npm@7) is (at least) the dep on react-native-fetch-api which brings in rn as a peerDep:
https://github.com/react-native-community/fetch/blob/8903bb7ee2c673da52f2e84172bef0752f2bedc5/package.json#L61-L62

We might PR that repo to remove the peerDependency, now npm@7 is the current default installed with node@16, but it's not an unreasonable thing for a react-native extention to do... it's exactly what peerDependecies are for. It we can't upstream that change we should fork, as it's not reasonable for something like ipfs-core-types to bring the entire react-native party due to a transitive dep on ipfs-utils

Building docs fails during release

[13:23:33] Generating documentation [started]
Loaded plugin /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir/src/ts/typedoc-plugin.js

Using TypeScript 4.1.3 from /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typescript/lib
Warning: You are running in an unsupported TypeScript version! TypeDoc supports 3.9.x || 4.0.x
/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/context.js:56
            throw new Error(`Expected a symbol for node with kind ${ts.SyntaxKind[node.kind]}`);
            ^

Error: Expected a symbol for node with kind Identifier
    at Context.expectSymbolAtLocation (/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/context.js:56:19)
    at /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/nodes/export.js:79:69
    at Array.forEach (<anonymous>)
    at ExportDeclarationConverter.convert (/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/nodes/export.js:76:40)
    at Converter.convertNode (/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/converter.js:117:53)
    at /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/nodes/block.js:66:28
    at Array.forEach (<anonymous>)
    at BlockConverter.convertStatements (/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/nodes/block.js:65:24)
    at BlockConverter.convert (/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/nodes/block.js:34:18)
    at Converter.convertNode (/Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/typedoc/dist/lib/converter/converter.js:117:53)
[13:23:37] Generating documentation [failed]
[13:23:37] → Command failed with exit code 1: typedoc --inputfiles /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/dist --mode modules --out docs --excludeExternals --includeDeclarations --hideGenerator --includeVersion --gitRevision master --disableSources --plugin /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir/src/ts/typedoc-plugin.js --theme /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir-typedoc-theme/bin/default
[13:23:37] Publish documentation [failed]
[13:23:37] → Command failed with exit code 1: typedoc --inputfiles /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/dist --mode modules --out docs --excludeExternals --includeDeclarations --hideGenerator --includeVersion --gitRevision master --disableSources --plugin /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir/src/ts/typedoc-plugin.js --theme /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir-typedoc-theme/bin/default
Command failed with exit code 1: typedoc --inputfiles /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/dist --mode modules --out docs --excludeExternals --includeDeclarations --hideGenerator --includeVersion --gitRevision master --disableSources --plugin /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir/src/ts/typedoc-plugin.js --theme /Users/alex/Documents/Workspaces/ipfs/js-ipfs-utils/node_modules/aegir-typedoc-theme/bin/default

Identifier 'global' has already been declared when run with jest

import useIPFS, { ICachedObject } from 'use-ipfs';
import { IIPFSPromiseApi } from 'ipfs-types';
import checkAll from '../index';

it('check local', async () =>
{
	return useIPFS({
		disposable: true,
	})
		.then(async ({
			ipfs,
			ipfsType,
			stop,
			ipfsd,
		}: ICachedObject<IIPFSPromiseApi>) => {

			let ret = await checkAll(ipfs)

			expect(ret).toMatchSnapshot();

			return stop();
		})
	;
});
  ● Test suite failed to run

    node_modules\ipfs-utils\src\http.js:7
    const global = require('./globalthis')
          ^

    SyntaxError: Identifier 'global' has already been declared

      at Runtime._execModule (../../node_modules/jest-runtime/build/index.js:1009:58)
      at Object.<anonymous> (../../node_modules/ipfs-utils/src/files/url-source.js:3:14)

native-fetch types are made up

[email protected] shipped with types support which basically just re-exports types from node-fetch - this module has it's own version of types for native-fetch and they do not align.

This module should not re-type native-fetch and should use the types it exposes.

HTTPError causes structured cloning algorithm to throw

I have quite a bit time figuring out why some of the tests were failing (in ipfs/js-ipfs#3081) on Firefox. Turns out structured clone algorithm throws when HTTError is being posted over message channel

class HTTPError extends Error {
constructor (response) {
super(response.statusText)
this.name = 'HTTPError'
this.response = response
}
}

There are multiple issues:

  1. Firefox does not yet support native Error types https://bugzilla.mozilla.org/show_bug.cgi?id=1556604
  2. Even with the above resolved response: Response still creates an issue.

I'm not sure what the appropriate course of action would be here, but here are few options:

  1. Making response non-enumerable property, which would be ignored.
  2. Instead of attaching Response instance extend HTTPError to include relevant data e.g:
    class HTTPError extends Error {
      constructor (response) {
        super(response.statusText)
        this.name = 'HTTPError'
        this.statusText = response.statusText
        this.responseType = response.type
        this.url = response.url
        this.status = response.status
        this.redirected = response.redirected
      }
    }

fetch and http requests

This module exposes a HTTP class that lets you make HTTP requests. It accepts and returns interfaces from the browser fetch spec. Internally it juggles multiple fetch implementations between browsers, node, electron, and react native.

The types of all of these implementations differ to the degree that they are largely incompatible which means we @ts-ignore a bunch of stuff which lets us move on but gives us no type safety and causes all sorts of weird bugs and code gymnastics in other parts of the codebase.

We don't use or need the entirety of the fetch specification. Instead lets stop trying to be a general-purpose polymorphic fetch implementation and instead just expose the bits of the fetch API we use and have each implementation just service those bits.

Fetch only takes a string, not a UrlWithLegacySupport

In https://github.com/ipfs/js-ipfs-utils/blob/master/src/http.js#L134-L159 the call to make is put into iso-url which returns a UrlWithLegacySupport.

A few lines lower, this is passed into fetch.

This throws the following error:

TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received an instance of URLWithLegacySupport
    at validateString (internal/validators.js:124:11)
    at Url.parse (url.js:159:3)
    at urlParse (url.js:154:13)
    at new Request (/home/coder/project/node_modules/node-fetch/lib/request.js:27:16)
    at /home/coder/project/node_modules/node-fetch/index.js:51:17
    at new Promise (<anonymous>)
    at new Fetch (/home/coder/project/node_modules/node-fetch/index.js:49:9)
    at Fetch (/home/coder/project/node_modules/node-fetch/index.js:37:10)
    at Client.fetch (/home/coder/project/node_modules/ipfs-utils/src/http.js:148:36)
    at Client.fetch (/home/coder/project/node_modules/ipfs-http-client/src/lib/core.js:162:20)
    at Client.post (/home/coder/project/node_modules/ipfs-utils/src/http.js:190:17)
    at addAll (/home/coder/project/node_modules/ipfs-http-client/src/add-all.js:22:27)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at last (/home/coder/project/node_modules/it-last/index.js:15:20)
    at Object.add (/home/coder/project/node_modules/ipfs-http-client/src/add.js:18:14)

Changing the fetch call to the following fixes this, but I'm wondering how this code has been in use in this repo for a long time and suddenly it starts erroring out for me.

    const response = await timeout(fetch(url.href, {

I tried Node 12 and 14, no difference there. (I was hoping url.parse was changed)

Problem when importing fetch in new version of native-fetch

module.exports = require('native-fetch')

When using the browser compile of this, the system ultimately imports "native-fetch" but the API of native-fetch doesn't have fetch as the default export, but rather as { fetch } on the exports.

The implementation is here https://github.com/achingbrain/native-fetch/blob/master/src/index.js
So either this code should be changed to not use default here

const { Response, Request, Headers, default: fetch } = require('../fetch')

Or request native-fetch to export fetch as default in addition to { fetch }

How can i build es Modules with rollup ?

I try add ipfs in mu react project

git reposetory
My app

import React from 'react';
import logo from './logo.svg';
import './App.css';
import * as IPFS from 'ipfs'

function App() {
  console.log('----------------------------', IPFS)
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;


rollup.js config

import serve from "rollup-plugin-serve";
import livereload from "rollup-plugin-livereload";
import babel from '@rollup/plugin-babel';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import image from '@rollup/plugin-image';
import postcss from 'rollup-plugin-postcss';
import json from '@rollup/plugin-json';
import webWorkerLoader from 'rollup-plugin-web-worker-loader';
import nodePolyfills from 'rollup-plugin-polyfill-node';
const extensions = ['.js','.mjs', '.ts', '.tsx'];

export default {
    input: "src/index.js",
    output: {
        file: "modules/index.mjs",
        format: "es",
        sourcemap: true,
    },
    plugins: [
        image(),
        json(),
        webWorkerLoader(),
        postcss({
            extensions: [".css"],
            plugins: [
            ]
        }),
        replace({
            preventAssignment: true,
            'process.env.NODE_ENV': JSON.stringify( 'development' )
        }),
        babel({
            extensions,
            exclude: /node_modules/,
            babelrc: false,
            babelHelpers: 'runtime',
            presets: [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-typescript',
            ],
            plugins: [
                'react-require',
                '@babel/plugin-syntax-dynamic-import',
                '@babel/plugin-proposal-class-properties',
                ['@babel/plugin-proposal-object-rest-spread', {
                    useBuiltIns: true,
                }],
                ['@babel/plugin-transform-runtime', {
                    corejs: 3,
                    helpers: true,
                    regenerator: true,
                    useESModules: true,
                }],
            ],
        }),
        nodePolyfills(),
        nodeResolve(),
        commonjs( {
            include: /node_modules/
        }),
        serve({
            open: false,
            verbose: true,
            contentBase: [""],
            host: "localhost",
            port: 3012,
        }),
        livereload({ watch: "dist" }),
    ]
};

I am getting an error on build.

[!] (plugin commonjs--resolver) SyntaxError: Unexpected token (13:121) in /home/sergey/Desktop/newkind/inProgerss/react-rollup-starter/node_modules/ipfs-utils/src/env.js
node_modules/ipfs-utils/src/env.js (13:121)
11: // @ts-ignore - we either ignore worker scope or dom scope
12: const IS_WEBWORKER = typeof importScripts === 'function' && typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope
13: const IS_TEST = typeof globalThis.process !== 'undefined' && typeof globalThis.process.env !== 'undefined' && globalThis.process.env.NODE_ENV === 'test'
                                                                                                                             ^
14: const IS_REACT_NATIVE = typeof navigator !== 'undefined' && navigator.product === 'ReactNative'
SyntaxError: Unexpected token (13:121) in /home/sergey/Desktop/newkind/inProgerss/react-rollup-starter/node_modules/ipfs-utils/src/env.js

Tell me please. Where can I find the answer, how to fix it?

reduce strictness of WebRTC support check

Hi, I have read the code of the new ipfs-utils/src/support.js. I found a problem below:
7a5edc3a6c84a58bb3a4476d393d0b0f35c2a0ff

getUserMedia is not supported in Chrome on IOS, because of WkWebview in IOS. But in some case, we don’t use getUserMedia function, but just want to use WebRTC for text message. So if use the support.js, some application will not work on chrome in IOS. Maybe we should consider to relaxation of conditions for checking WebRTC support?

P.S there is a reply on stack overflow:

WebRTC has three main JavaScript APIs:

  • MediaStream (aka getUserMedia)
  • RTCPeerConnection
  • RTCDataChannel

For apps running inside Safari App, iOS11+, all WebRTC APIs are supported. That includes getUserMedia . Be sure to use adapter.js library for best compatibility, since each browser - including Safari - uses a different name for its implementation. For example, in Safari it's navigator.mediaDevices.getUserMedia() .

But, when using WKWebView or SFSafariViewController , it's a different story:

You can still stream video & audio from local storage or consume live media captured by a peer. Hopefully in iOS 12 we'll see some progress...

Custom node-fetch causes builds to fail

Recently we removed the ipfs dependency in our repository to opt-in for the lightweight ipfs-core package for our tests. Our repository already has node-fetch package and following the installation of [email protected] and subsequently [email protected] our builds started to fail.

The reason seems to be the custom node package used in this repo: node-fetch@npm:@achingbrain/[email protected]. Our other node-fetch packages had @^2.6.x and since the latest official package is 2.6.6 the custom @acingbrain/[email protected] overrides others.

uzdogan@kuzdogan-UX331UN:~/repos/sourcify$ npm ls node-fetch
[email protected] /home/kuzdogan/repos/sourcify
├─┬ @ethereum-sourcify/[email protected]
│ └── node-fetch@npm:@achingbrain/[email protected] deduped
├─┬ @ethereum-sourcify/[email protected]
│ └── node-fetch@npm:@achingbrain/[email protected] deduped
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │   └── node-fetch@npm:@achingbrain/[email protected] deduped
│ └─┬ [email protected]
│   ├─┬ [email protected]
│   │ └── node-fetch@npm:@achingbrain/[email protected] deduped
│   └── node-fetch@npm:@achingbrain/[email protected] deduped
├─┬ [email protected]
│ └─┬ @lerna/[email protected]
│   ├─┬ @lerna/[email protected]
│   │ └─┬ @octokit/[email protected]
│   │   └─┬ @octokit/[email protected]
│   │     └── node-fetch@npm:@achingbrain/[email protected] deduped
│   └─┬ @lerna/[email protected]
│     └── node-fetch@npm:@achingbrain/[email protected] deduped
└── node-fetch@npm:@achingbrain/[email protected]

We get the following error in our builds.

npx lerna bootstrap
npx: installed 673 in 35.178s
lerna notice cli v4.0.0
lerna info ci enabled
lerna info Bootstrapping 4 packages
lerna info Installing external dependencies
lerna ERR! npm ci --no-package-lock exited 1 in 'ethereum-sourcify'
lerna ERR! npm ci --no-package-lock stderr:
npm ERR! Invalid Version: npm:@achingbrain/[email protected]

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/circleci/.npm/_logs/2021-11-29T13_58_42_504Z-debug.log
lerna ERR! npm ci --no-package-lock exited 1 in 'ethereum-sourcify'
lerna WARN complete Waiting for 3 child processes to exit. CTRL-C to exit immediately

Reproducing

To reproduce follow these steps.

Our builds are on CircleCI. Spin up the CircleCI node container

$ docker run -it circleci/node:14

In the container terminal cd into circleci folder

$ cd home/circleci

Clone the repository and cd

$ git clone https://github.com/ethereum/sourcify.git && cd sourcify

Checkout the relevant commit. (See the branch on GitHub )

$ git checkout a8c696082165ad7230d9a825563b165d18dc15d9

Install dependencies

$ npx lerna bootstrap --ci

Note that --ci flag is used. This is automatically detected in the CircleCI build environment. Local installs without this flag will not fail.

Fix

I was able to fix the issue by setting the node-fetch@^2.6.1 on our repo to fixed [email protected]. Then removing the package-lock.json files and running an npm install.

This results with two different node-fetch modules being used as intended:

$ npm ls node-fetch
[email protected] /home/kuzdogan/repos/sourcify
├─┬ @ethereum-sourcify/[email protected]
│ └── [email protected] deduped
├─┬ @ethereum-sourcify/[email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected] deduped
│ └─┬ [email protected]
│   ├─┬ [email protected]
│   │ └── [email protected] deduped
│   └── node-fetch@npm:@achingbrain/[email protected]
├─┬ [email protected]
│ └─┬ @lerna/[email protected]
│   ├─┬ @lerna/[email protected]
│   │ └─┬ @octokit/[email protected]
│   │   └─┬ @octokit/[email protected]
│   │     └── [email protected] deduped
│   └─┬ @lerna/[email protected]
│     └── [email protected] deduped
└── [email protected]

A better way to handle this would be to name the custom node-fetch in this repo with an alias so that it does not interfere with other node-fetch versions.

Error related to fetch.js and Webpack

I'm getting an error in Next.js, which is using ipfs-utils at some point. ipfs-utisl is imported by co2-storage.
I tried changing the line const fetch = require(implName) to const fetch = require('./fetch.node'), but it didn't help.

Import trace for requested module:
./node_modules/ipfs-utils/src/http/fetch.js
./node_modules/ipfs-utils/src/http.js
./node_modules/ipfs-http-client/src/files/rm.js
./node_modules/ipfs-http-client/src/files/index.js
./node_modules/ipfs-http-client/src/index.js
./node_modules/@co2-storage/js-api/src/js/storage/FGStorage.js
./node_modules/@co2-storage/js-api/src/js/index.js
./app/api/create-action-plan/route.ts

  • error Error: Cannot find module './fetch.node'
    at webpackEmptyContext (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:22:10)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-utils/src/http/fetch.js:14:118)
    at (rsc)/./node_modules/ipfs-utils/src/http/fetch.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:2173:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-utils/src/http.js:2:37)
    at (rsc)/./node_modules/ipfs-utils/src/http.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:2151:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-http-client/src/lib/core.js:11:80)
    at (rsc)/./node_modules/ipfs-http-client/src/lib/core.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:8012:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-http-client/src/lib/configure.js:5:66)
    at (rsc)/./node_modules/ipfs-http-client/src/lib/configure.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:8001:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-http-client/src/bitswap/wantlist.js:6:75)
    at (rsc)/./node_modules/ipfs-http-client/src/bitswap/wantlist.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:7253:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-http-client/src/bitswap/index.js:5:70)
    at (rsc)/./node_modules/ipfs-http-client/src/bitswap/index.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:7209:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/ipfs-http-client/src/index.js:18:75)
    at (rsc)/./node_modules/ipfs-http-client/src/index.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:7880:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/@co2-storage/js-api/src/js/storage/FGStorage.js:5:74)
    at (rsc)/./node_modules/@co2-storage/js-api/src/js/storage/FGStorage.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:4250:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/@co2-storage/js-api/src/js/index.js:7:79)
    at (rsc)/./node_modules/@co2-storage/js-api/src/js/index.js (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:4239:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./app/api/create-action-plan/route.ts:8:77)
    at (rsc)/./app/api/create-action-plan/route.ts (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:282:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at eval (webpack-internal:///(rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fcreate-action-plan%2Froute&page=%2Fapi%2Fcreate-action-plan%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fcreate-action-plan%2Froute.ts&appDir=%2Fhome%2Fwebdev%2Fnftreesbrasil%2Fnextjs%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2Fhome%2Fwebdev%2Fnftreesbrasil%2Fnextjs&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D!:16:127)
    at (rsc)/./node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fcreate-action-plan%2Froute&page=%2Fapi%2Fcreate-action-plan%2Froute&appPaths=&pagePath=private-next-app-dir%2Fapi%2Fcreate-action-plan%2Froute.ts&appDir=%2Fhome%2Fwebdev%2Fnftreesbrasil%2Fnextjs%2Fapp&pageExtensions=tsx&pageExtensions=ts&pageExtensions=jsx&pageExtensions=js&rootDir=%2Fhome%2Fwebdev%2Fnftreesbrasil%2Fnextjs&isDev=true&tsconfigPath=tsconfig.json&basePath=&assetPrefix=&nextConfigOutput=&preferredRegion=&middlewareConfig=e30%3D! (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:260:1)
    at webpack_require (/home/webdev/nftreesbrasil/nextjs/.next/server/webpack-runtime.js:33:43)
    at webpack_exec (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:12059:39)
    at /home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:12060:28
    at Object. (/home/webdev/nftreesbrasil/nextjs/.next/server/app/api/create-action-plan/route.js:12063:3)
    at Module._compile (node:internal/modules/cjs/loader:1233:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1287:10)
    at Module.load (node:internal/modules/cjs/loader:1091:32)
    at Module._load (node:internal/modules/cjs/loader:938:12)
    at Module.require (node:internal/modules/cjs/loader:1115:19)
    at require (node:internal/modules/helpers:130:18)
    at requirePage (/home/webdev/nftreesbrasil/nextjs/node_modules/next/dist/server/require.js:112:75)
    at /home/webdev/nftreesbrasil/nextjs/node_modules/next/dist/server/load-components.js:80:84
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async loadComponentsImpl (/home/webdev/nftreesbrasil/nextjs/node_modules/next/dist/server/load-components.js:80:26)
    at async DevServer.findPageComponentsImpl (/home/webdev/nftreesbrasil/nextjs/node_modules/next/dist/server/next-server.js:434:36) {
    digest: undefined
    }

Convert to ESM

Right now ipfs-utils is written with CommonJS, which creates issues when using with Deno. Also, ipfs-http-client and other modules are already ESM, so I think it'd be nice to have ipfs-utils as ESM as well.

I've just submitted a PR with ESM rewrite: #265

Right now node and browser works, electron doesn't work because it doesn't support es modules yet (a PR with it's support has appeared 2 weeks ago though)

npm install failed

Node Version: 16.15.1

Error:

Error: [[email protected][email protected][email protected] › node-fetch@https://registry.npmjs.org/@achingbrain/node-fetch/-/node-fetch-2.6.7.tgz] Invalid Package, expected node-fetch but found @achingbrain/node-fetch

image

Why add achingbrain/node-fetch as the dependency? It is a temporary fork of node-fetch. It will not be updated or maintained.

Unable to import ipfs-http-client due to ipfs-utils using require statement

Hello team,

I'm receiving an error whenever I try to import ipfs-http-client. I realize this is js-ipfs-utils repo but the error is orignating from this repo's code.

My code

import { create } from 'ipfs-http-client'

Error when I run mocha test

Error [ERR_REQUIRE_ESM]: require() of ES Module plebbit/plebbit.js/node_modules/node-fetch/src/index.js from plebbit/plebbit.js/node_modules/native-fetch/src/index.js not supported.
Instead change the require of plebbit/plebbit.js/node_modules/node-fetch/src/index.js in plebbit/plebbit.js/node_modules/native-fetch/src/index.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (plebbit/plebbit.js/node_modules/native-fetch/src/index.js:12:14)
    at Object.<anonymous> (plebbit/plebbit.js/node_modules/ipfs-utils/src/fetch.js:9:20)
    at Object.<anonymous> (plebbit/plebbit.js/node_modules/ipfs-utils/src/http/fetch.node.js:2:62)
    at Object.<anonymous> (plebbit/plebbit.js/node_modules/ipfs-utils/src/http/fetch.js:8:20)
    at Object.<anonymous> (plebbit/plebbit.js/node_modules/ipfs-utils/src/http.js:4:37)
    at async Promise.all (index 0)
    at async formattedImport (plebbit/plebbit.js/node_modules/mocha/lib/nodejs/esm-utils.js:7:14)
    at async Object.exports.requireOrImport (plebbit/plebbit.js/node_modules/mocha/lib/nodejs/esm-utils.js:48:32)
    at async Object.exports.loadFilesAsync (plebbit/plebbit.js/node_modules/mocha/lib/nodejs/esm-utils.js:103:20)
    at async singleRun (plebbit/plebbit.js/node_modules/mocha/lib/cli/run-helpers.js:125:3)
    at async Object.exports.handler (plebbit/plebbit.js/node_modules/mocha/lib/cli/run.js:374:5)

The line in ipfs-utils/src/fetch.js(9) using require and causing the problem

  module.exports = require('native-fetch')

My package.json

{
  "name": "plebbit.js",
  "version": "0.0.1",
  "description": "plebbit.js will be an NPM module to wrap around the IPFS APIs used by Plebbit. It will be used in all clients: CLI, Electron (Desktop GUI) and Web.",
  "main": "src/Plebbit.js",
  "scripts": {
    "test": "mocha --timeout 5000"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/plebbit/plebbit-js.git"
  },
  "keywords": [
    "plebbit"
  ],
  "author": "Esteban Abaroa, Rinse",
  "license": "GPL-2.0-only",
  "bugs": {
    "url": "https://github.com/plebbit/plebbit-js/issues"
  },
  "homepage": "https://github.com/plebbit/plebbit-js#readme",
  "dependencies": {
    "ipfs-http-client": "^55.0.0"
  },
  "devDependencies": {
    "mocha": "^9.1.4"
  },
  "type": "module"
}

unable to run in functions because of use of 'fs'

I'm trying to use this in an azure function with a ipfs node hosted there as well.

A small issue, which is not related but just to note it, is that I had to set "esModuleInterop": true, in my tsconfig as the exports are old-style. But I'm sure that will change when it needs to, its not my issue.

I get this error:

 npm start

> [email protected] prestart
> npm run build


> [email protected] build
> tsc

node_modules/ipfs-utils/dist/src/files/glob-source.d.ts:10:14 - error TS2503: Cannot find namespace 'fs'.

10     content: fs.ReadStream | undefined;
                ~~


Found 1 error in node_modules/ipfs-utils/dist/src/files/glob-source.d.ts:10

MacBook-Pro-2:fn-ipfs-broker robertotomas$ 

I think in this case we really don't need a local file. The filesize is limited to 100MiB, it can safely be processed in memory. I'm getting it from an HTTP multipart post using parse-multipart, so my buffer is the full in memory copy of the file in a buffer.

I can manually remove the fs from the d.ts file (replace with any) and get it to run. :)

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.