Comparing version 8.0.2 to 8.0.3
@@ -0,3 +1,97 @@ | ||
/** | ||
* @packageDocumentation | ||
* | ||
* A suite of util methods that provides efficient validation. | ||
* | ||
* Detection of IPFS Paths and identifiers in URLs is a two-stage process: | ||
* | ||
* 1. `pathPattern`/`pathGatewayPattern`/`subdomainGatewayPattern` regex is applied to quickly identify potential candidates | ||
* 2. proper CID validation is applied to remove false-positives | ||
* | ||
* @example | ||
* | ||
* ```TypeScript | ||
* import * as isIPFS from 'is-ipfs' | ||
* | ||
* isIPFS.multihash('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.multihash('noop') // false | ||
* | ||
* isIPFS.cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true (CIDv0) | ||
* isIPFS.cid('bafybeiasb5vpmaounyilfuxbd3lryvosl4yefqrfahsb2esg46q6tu6y5q') // true (CIDv1 in Base32) | ||
* isIPFS.cid('zdj7WWeQ43G6JJvLWQWZpyHuAMq6uYWRjkBXFad11vE2LHhQ7') // true (CIDv1 in Base58btc) | ||
* isIPFS.cid('noop') // false | ||
* | ||
* isIPFS.base32cid('bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va') // true | ||
* isIPFS.base32cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* | ||
* isIPFS.url('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.url('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?filename=guardian.jpg') // true | ||
* isIPFS.url('https://ipfs.io/ipns/github.com') // true | ||
* isIPFS.url('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.url('http://en.wikipedia-on-ipfs.org.ipfs.localhost:8080') // true | ||
* isIPFS.url('https://github.com/ipfs/js-ipfs/blob/master/README.md') // false | ||
* isIPFS.url('https://google.com') // false | ||
* | ||
* isIPFS.path('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.path('/ipfs/QmbcBPAwCDxRMB1Qe7CRQmxdrTSkxKwM9y6rZw2FjGtbsb/?weird-filename=test.jpg') // true | ||
* isIPFS.path('/ipns/github.com') // true | ||
* isIPFS.path('/ipfs/js-ipfs/blob/master/README.md') // false | ||
* | ||
* isIPFS.urlOrPath('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.urlOrPath('https://ipfs.io/ipns/github.com') // true | ||
* isIPFS.urlOrPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.urlOrPath('/ipns/github.com') // true | ||
* isIPFS.urlOrPath('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.urlOrPath('https://google.com') // false | ||
* | ||
* isIPFS.ipfsUrl('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.ipfsUrl('https://ipfs.io/ipfs/invalid-hash') // false | ||
* | ||
* isIPFS.ipnsUrl('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.ipnsUrl('https://ipfs.io/ipns/github.com') // true | ||
* | ||
* isIPFS.ipfsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.ipfsPath('/ipfs/invalid-hash') // false | ||
* | ||
* isIPFS.ipnsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.ipnsPath('/ipns/github.com') // true | ||
* | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/path/to/file') // true | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/') // true | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.cidPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.cidPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/file') // false | ||
* | ||
* isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.subdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true | ||
* isIPFS.subdomain('http://www.bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // false | ||
* isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false | ||
* | ||
* isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false | ||
* | ||
* isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true | ||
* isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.dweb.link') // false | ||
* isIPFS.ipnsSubdomain('http://QmcNioXSC1bfJj1dcFErhUfyjFzoX2HodkRccsFFVJJvg8.ipns.dweb.link') // false | ||
* isIPFS.ipnsSubdomain('http://en.wikipedia-on-ipfs.org.ipns.localhost:8080') // true (assuming DNSLink) | ||
* isIPFS.ipnsSubdomain('http://en-wikipedia--on--ipfs-org.ipns.localhost:8080') // true (assuming inlined DNSLink) | ||
* isIPFS.ipnsSubdomain('http://hostname-without-tld-.ipns.dweb.link') // false (not a CID, invalid DNS label) | ||
* | ||
* isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234') // true | ||
* isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234/http') // true | ||
* isIPFS.multiaddr('/ip6/::1/udp/1234') // true | ||
* isIPFS.multiaddr('ip6/::1/udp/1234') // false | ||
* isIPFS.multiaddr('/yoloinvalid/::1/udp/1234') // false | ||
* | ||
* isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true | ||
* isIPFS.peerMultiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true (legacy notation) | ||
* isIPFS.peerMultiaddr('/ip4/127.0.0.1/tcp/1234/ws/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true | ||
* isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4/p2p-circuit/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true | ||
* isIPFS.peerMultiaddr('/dnsaddr/bootstrap.libp2p.io') // false (key missing, needs additional DNS lookup to tell if this is valid) | ||
* isIPFS.peerMultiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN') // true (key present, ip and port can be resolved later) | ||
* isIPFS.peerMultiaddr('/ip4/127.0.0.1/udp/1234') // false (key missing) | ||
* ``` | ||
*/ | ||
import { CID } from 'multiformats/cid'; | ||
import type { Multiaddr } from '@multiformats/multiaddr'; | ||
import { CID } from 'multiformats/cid'; | ||
export declare const pathGatewayPattern: RegExp; | ||
@@ -13,18 +107,89 @@ export declare const pathPattern: RegExp; | ||
declare function isPeerMultiaddr(input: string | Uint8Array | Multiaddr): boolean; | ||
/** | ||
* Returns `true` if the provided `url` string includes a valid IPFS subdomain | ||
* (case-insensitive CIDv1) or `false` otherwise. | ||
*/ | ||
export declare const ipfsSubdomain: (url: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided `url` string looks like a valid IPNS subdomain | ||
* (CIDv1 with `libp2p-key` multicodec or something that looks like a FQDN, for | ||
* example `en.wikipedia-on-ipfs.org.ipns.localhost:8080`) or `false` otherwise. | ||
* | ||
* **Note:** `ipnsSubdomain` method works in offline mode: it does not perform | ||
* actual IPNS record lookup over DHT or other content routing method. It may | ||
* return false-positives: | ||
* | ||
* - To ensure IPNS record exists, make a call to `/api/v0/name/resolve?arg=<ipnsid>` | ||
* - To ensure DNSLink exists, make a call to `/api/v0/dns?arg=<fqdn>` | ||
*/ | ||
export declare const ipnsSubdomain: (url: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided `url` string includes a valid IPFS, looks like | ||
* an IPNS/DNSLink subdomain or `false` otherwise. | ||
*/ | ||
export declare const subdomain: (url: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS url or `false` | ||
* otherwise. | ||
*/ | ||
export declare const ipfsUrl: (url: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid IPNS url or `false` | ||
* otherwise. | ||
*/ | ||
export declare const ipnsUrl: (url: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS url or `false` | ||
* otherwise. | ||
*/ | ||
export declare const url: (url: string | Uint8Array) => boolean; | ||
export declare const path: (path: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string or `Uint8Array` is a valid `multihash` | ||
* or `false` otherwise. | ||
*/ | ||
export { isMultihash as multihash }; | ||
/** | ||
* Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) | ||
* or `Uint8Array` represents a valid multiaddr or `false` otherwise. | ||
*/ | ||
export { isMultiaddr as multiaddr }; | ||
/** | ||
* Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) | ||
* or `Uint8Array` represents a valid libp2p peer multiaddr (matching [`P2P` | ||
* format from `mafmt`](https://github.com/multiformats/js-mafmt#api)) or | ||
* `false` otherwise. | ||
*/ | ||
export { isPeerMultiaddr as peerMultiaddr }; | ||
/** | ||
* Returns `true` if the provided string, `Uint8Array` or [`CID`](https://github.com/multiformats/js-multiformats/#readme) | ||
* object represents a valid [CID](https://docs.ipfs.io/guides/concepts/cid/) or | ||
* `false` otherwise. | ||
*/ | ||
export { isCID as cid }; | ||
/** | ||
* Returns `true` if the provided string is a valid `CID` in Base32 encoding or | ||
* `false` otherwise. | ||
*/ | ||
export declare const base32cid: (cid: CID | string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS path or `false` | ||
* otherwise. | ||
*/ | ||
export declare const ipfsPath: (path: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid IPNS path or `false` | ||
* otherwise. | ||
*/ | ||
export declare const ipnsPath: (path: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS url or path or | ||
* `false` otherwise. | ||
*/ | ||
export declare const urlOrPath: (x: string | Uint8Array) => boolean; | ||
/** | ||
* Returns `true` if the provided string is a valid "CID path" (IPFS path | ||
* without `/ipfs/` prefix) or `false` otherwise. | ||
*/ | ||
export declare const cidPath: (path: string | Uint8Array | CID) => boolean; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -0,8 +1,102 @@ | ||
/** | ||
* @packageDocumentation | ||
* | ||
* A suite of util methods that provides efficient validation. | ||
* | ||
* Detection of IPFS Paths and identifiers in URLs is a two-stage process: | ||
* | ||
* 1. `pathPattern`/`pathGatewayPattern`/`subdomainGatewayPattern` regex is applied to quickly identify potential candidates | ||
* 2. proper CID validation is applied to remove false-positives | ||
* | ||
* @example | ||
* | ||
* ```TypeScript | ||
* import * as isIPFS from 'is-ipfs' | ||
* | ||
* isIPFS.multihash('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.multihash('noop') // false | ||
* | ||
* isIPFS.cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true (CIDv0) | ||
* isIPFS.cid('bafybeiasb5vpmaounyilfuxbd3lryvosl4yefqrfahsb2esg46q6tu6y5q') // true (CIDv1 in Base32) | ||
* isIPFS.cid('zdj7WWeQ43G6JJvLWQWZpyHuAMq6uYWRjkBXFad11vE2LHhQ7') // true (CIDv1 in Base58btc) | ||
* isIPFS.cid('noop') // false | ||
* | ||
* isIPFS.base32cid('bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va') // true | ||
* isIPFS.base32cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* | ||
* isIPFS.url('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.url('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?filename=guardian.jpg') // true | ||
* isIPFS.url('https://ipfs.io/ipns/github.com') // true | ||
* isIPFS.url('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.url('http://en.wikipedia-on-ipfs.org.ipfs.localhost:8080') // true | ||
* isIPFS.url('https://github.com/ipfs/js-ipfs/blob/master/README.md') // false | ||
* isIPFS.url('https://google.com') // false | ||
* | ||
* isIPFS.path('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.path('/ipfs/QmbcBPAwCDxRMB1Qe7CRQmxdrTSkxKwM9y6rZw2FjGtbsb/?weird-filename=test.jpg') // true | ||
* isIPFS.path('/ipns/github.com') // true | ||
* isIPFS.path('/ipfs/js-ipfs/blob/master/README.md') // false | ||
* | ||
* isIPFS.urlOrPath('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.urlOrPath('https://ipfs.io/ipns/github.com') // true | ||
* isIPFS.urlOrPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.urlOrPath('/ipns/github.com') // true | ||
* isIPFS.urlOrPath('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.urlOrPath('https://google.com') // false | ||
* | ||
* isIPFS.ipfsUrl('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.ipfsUrl('https://ipfs.io/ipfs/invalid-hash') // false | ||
* | ||
* isIPFS.ipnsUrl('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.ipnsUrl('https://ipfs.io/ipns/github.com') // true | ||
* | ||
* isIPFS.ipfsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.ipfsPath('/ipfs/invalid-hash') // false | ||
* | ||
* isIPFS.ipnsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.ipnsPath('/ipns/github.com') // true | ||
* | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/path/to/file') // true | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/') // true | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.cidPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.cidPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/file') // false | ||
* | ||
* isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.subdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true | ||
* isIPFS.subdomain('http://www.bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // false | ||
* isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false | ||
* | ||
* isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false | ||
* | ||
* isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true | ||
* isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.dweb.link') // false | ||
* isIPFS.ipnsSubdomain('http://QmcNioXSC1bfJj1dcFErhUfyjFzoX2HodkRccsFFVJJvg8.ipns.dweb.link') // false | ||
* isIPFS.ipnsSubdomain('http://en.wikipedia-on-ipfs.org.ipns.localhost:8080') // true (assuming DNSLink) | ||
* isIPFS.ipnsSubdomain('http://en-wikipedia--on--ipfs-org.ipns.localhost:8080') // true (assuming inlined DNSLink) | ||
* isIPFS.ipnsSubdomain('http://hostname-without-tld-.ipns.dweb.link') // false (not a CID, invalid DNS label) | ||
* | ||
* isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234') // true | ||
* isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234/http') // true | ||
* isIPFS.multiaddr('/ip6/::1/udp/1234') // true | ||
* isIPFS.multiaddr('ip6/::1/udp/1234') // false | ||
* isIPFS.multiaddr('/yoloinvalid/::1/udp/1234') // false | ||
* | ||
* isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true | ||
* isIPFS.peerMultiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true (legacy notation) | ||
* isIPFS.peerMultiaddr('/ip4/127.0.0.1/tcp/1234/ws/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true | ||
* isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4/p2p-circuit/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true | ||
* isIPFS.peerMultiaddr('/dnsaddr/bootstrap.libp2p.io') // false (key missing, needs additional DNS lookup to tell if this is valid) | ||
* isIPFS.peerMultiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN') // true (key present, ip and port can be resolved later) | ||
* isIPFS.peerMultiaddr('/ip4/127.0.0.1/udp/1234') // false (key missing) | ||
* ``` | ||
*/ | ||
import * as mafmt from '@multiformats/mafmt'; | ||
import { multiaddr } from '@multiformats/multiaddr'; | ||
import { URL } from 'iso-url'; | ||
import { base32 } from 'multiformats/bases/base32'; | ||
import { base58btc } from 'multiformats/bases/base58'; | ||
import { base32 } from 'multiformats/bases/base32'; | ||
import { CID } from 'multiformats/cid'; | ||
import * as Digest from 'multiformats/hashes/digest'; | ||
import { multiaddr } from '@multiformats/multiaddr'; | ||
import * as mafmt from '@multiformats/mafmt'; | ||
import { CID } from 'multiformats/cid'; | ||
import { URL } from 'iso-url'; | ||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'; | ||
@@ -25,3 +119,3 @@ export const pathGatewayPattern = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/; | ||
try { | ||
Digest.decode(base58btc.decode('z' + formatted)); | ||
Digest.decode(base58btc.decode(`z${formatted}`)); | ||
} | ||
@@ -172,18 +266,89 @@ catch { | ||
} | ||
/** | ||
* Returns `true` if the provided `url` string includes a valid IPFS subdomain | ||
* (case-insensitive CIDv1) or `false` otherwise. | ||
*/ | ||
export const ipfsSubdomain = (url) => isIpfs(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch); | ||
/** | ||
* Returns `true` if the provided `url` string looks like a valid IPNS subdomain | ||
* (CIDv1 with `libp2p-key` multicodec or something that looks like a FQDN, for | ||
* example `en.wikipedia-on-ipfs.org.ipns.localhost:8080`) or `false` otherwise. | ||
* | ||
* **Note:** `ipnsSubdomain` method works in offline mode: it does not perform | ||
* actual IPNS record lookup over DHT or other content routing method. It may | ||
* return false-positives: | ||
* | ||
* - To ensure IPNS record exists, make a call to `/api/v0/name/resolve?arg=<ipnsid>` | ||
* - To ensure DNSLink exists, make a call to `/api/v0/dns?arg=<fqdn>` | ||
*/ | ||
export const ipnsSubdomain = (url) => isIpns(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch); | ||
/** | ||
* Returns `true` if the provided `url` string includes a valid IPFS, looks like | ||
* an IPNS/DNSLink subdomain or `false` otherwise. | ||
*/ | ||
export const subdomain = (url) => ipfsSubdomain(url) || ipnsSubdomain(url); | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS url or `false` | ||
* otherwise. | ||
*/ | ||
export const ipfsUrl = (url) => isIpfs(url, pathGatewayPattern) || ipfsSubdomain(url); | ||
/** | ||
* Returns `true` if the provided string is a valid IPNS url or `false` | ||
* otherwise. | ||
*/ | ||
export const ipnsUrl = (url) => isIpns(url, pathGatewayPattern) || ipnsSubdomain(url); | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS url or `false` | ||
* otherwise. | ||
*/ | ||
export const url = (url) => ipfsUrl(url) || ipnsUrl(url) || subdomain(url); | ||
export const path = (path) => isIpfs(path, pathPattern) || isIpns(path, pathPattern); | ||
/** | ||
* Returns `true` if the provided string or `Uint8Array` is a valid `multihash` | ||
* or `false` otherwise. | ||
*/ | ||
export { isMultihash as multihash }; | ||
/** | ||
* Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) | ||
* or `Uint8Array` represents a valid multiaddr or `false` otherwise. | ||
*/ | ||
export { isMultiaddr as multiaddr }; | ||
/** | ||
* Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) | ||
* or `Uint8Array` represents a valid libp2p peer multiaddr (matching [`P2P` | ||
* format from `mafmt`](https://github.com/multiformats/js-mafmt#api)) or | ||
* `false` otherwise. | ||
*/ | ||
export { isPeerMultiaddr as peerMultiaddr }; | ||
/** | ||
* Returns `true` if the provided string, `Uint8Array` or [`CID`](https://github.com/multiformats/js-multiformats/#readme) | ||
* object represents a valid [CID](https://docs.ipfs.io/guides/concepts/cid/) or | ||
* `false` otherwise. | ||
*/ | ||
export { isCID as cid }; | ||
/** | ||
* Returns `true` if the provided string is a valid `CID` in Base32 encoding or | ||
* `false` otherwise. | ||
*/ | ||
export const base32cid = (cid) => (isCID(cid) && isBase32EncodedMultibase(cid)); | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS path or `false` | ||
* otherwise. | ||
*/ | ||
export const ipfsPath = (path) => isIpfs(path, pathPattern); | ||
/** | ||
* Returns `true` if the provided string is a valid IPNS path or `false` | ||
* otherwise. | ||
*/ | ||
export const ipnsPath = (path) => isIpns(path, pathPattern); | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS url or path or | ||
* `false` otherwise. | ||
*/ | ||
export const urlOrPath = (x) => url(x) || path(x); | ||
/** | ||
* Returns `true` if the provided string is a valid "CID path" (IPFS path | ||
* without `/ipfs/` prefix) or `false` otherwise. | ||
*/ | ||
export const cidPath = (path) => isString(path) && !isCID(path) && isIpfs(`/ipfs/${path}`, pathPattern); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"pathGatewayPattern": "https://ipfs-shipyard.github.io/is-ipfs/variables/pathGatewayPattern.html", | ||
".:pathGatewayPattern": "https://ipfs-shipyard.github.io/is-ipfs/variables/pathGatewayPattern.html", | ||
"pathPattern": "https://ipfs-shipyard.github.io/is-ipfs/variables/pathPattern.html", | ||
".:pathPattern": "https://ipfs-shipyard.github.io/is-ipfs/variables/pathPattern.html", | ||
"subdomainGatewayPattern": "https://ipfs-shipyard.github.io/is-ipfs/variables/subdomainGatewayPattern.html", | ||
".:subdomainGatewayPattern": "https://ipfs-shipyard.github.io/is-ipfs/variables/subdomainGatewayPattern.html", | ||
"base32cid": "https://ipfs-shipyard.github.io/is-ipfs/functions/base32cid.html", | ||
".:base32cid": "https://ipfs-shipyard.github.io/is-ipfs/functions/base32cid.html", | ||
"cid": "https://ipfs-shipyard.github.io/is-ipfs/functions/cid.html", | ||
".:cid": "https://ipfs-shipyard.github.io/is-ipfs/functions/cid.html", | ||
"cidPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/cidPath.html", | ||
".:cidPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/cidPath.html", | ||
"ipfsPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipfsPath.html", | ||
".:ipfsPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipfsPath.html", | ||
"ipfsSubdomain": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipfsSubdomain.html", | ||
".:ipfsSubdomain": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipfsSubdomain.html", | ||
"ipfsUrl": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipfsUrl.html", | ||
".:ipfsUrl": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipfsUrl.html", | ||
"ipnsPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipnsPath.html", | ||
".:ipnsPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipnsPath.html", | ||
"ipnsSubdomain": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipnsSubdomain.html", | ||
".:ipnsSubdomain": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipnsSubdomain.html", | ||
"ipnsUrl": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipnsUrl.html", | ||
".:ipnsUrl": "https://ipfs-shipyard.github.io/is-ipfs/functions/ipnsUrl.html", | ||
"multiaddr": "https://ipfs-shipyard.github.io/is-ipfs/functions/multiaddr.html", | ||
".:multiaddr": "https://ipfs-shipyard.github.io/is-ipfs/functions/multiaddr.html", | ||
"multihash": "https://ipfs-shipyard.github.io/is-ipfs/functions/multihash.html", | ||
".:multihash": "https://ipfs-shipyard.github.io/is-ipfs/functions/multihash.html", | ||
"path": "https://ipfs-shipyard.github.io/is-ipfs/functions/path.html", | ||
".:path": "https://ipfs-shipyard.github.io/is-ipfs/functions/path.html", | ||
"peerMultiaddr": "https://ipfs-shipyard.github.io/is-ipfs/functions/peerMultiaddr.html", | ||
".:peerMultiaddr": "https://ipfs-shipyard.github.io/is-ipfs/functions/peerMultiaddr.html", | ||
"subdomain": "https://ipfs-shipyard.github.io/is-ipfs/functions/subdomain.html", | ||
".:subdomain": "https://ipfs-shipyard.github.io/is-ipfs/functions/subdomain.html", | ||
"url": "https://ipfs-shipyard.github.io/is-ipfs/functions/url.html", | ||
"urlOrPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/urlOrPath.html" | ||
".:url": "https://ipfs-shipyard.github.io/is-ipfs/functions/url.html", | ||
"urlOrPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/urlOrPath.html", | ||
".:urlOrPath": "https://ipfs-shipyard.github.io/is-ipfs/functions/urlOrPath.html" | ||
} |
{ | ||
"name": "is-ipfs", | ||
"version": "8.0.2", | ||
"version": "8.0.3", | ||
"description": "A set of utilities to help identify IPFS resources on the web", | ||
@@ -15,2 +15,6 @@ "author": "Francisco Dias <francisco@baiodias.com> (http://franciscodias.net/)", | ||
}, | ||
"publishConfig": { | ||
"access": "public", | ||
"provenance": true | ||
}, | ||
"keywords": [ | ||
@@ -23,6 +27,2 @@ "dnslink", | ||
], | ||
"engines": { | ||
"node": ">=16.0.0", | ||
"npm": ">=7.0.0" | ||
}, | ||
"type": "module", | ||
@@ -45,2 +45,3 @@ "types": "./dist/src/index.d.ts", | ||
"parserOptions": { | ||
"project": true, | ||
"sourceType": "module" | ||
@@ -135,14 +136,12 @@ } | ||
"scripts": { | ||
"clean": "aegir clean", | ||
"lint": "aegir lint", | ||
"dep-check": "aegir dep-check", | ||
"generate": "protons src/pb/peer.proto src/pb/tags.proto", | ||
"build": "aegir build", | ||
"test": "aegir test", | ||
"test:chrome": "aegir test -t browser", | ||
"test:node": "aegir test -t node --cov", | ||
"test:chrome": "aegir test -t browser --cov", | ||
"test:chrome-webworker": "aegir test -t webworker", | ||
"test:firefox": "aegir test -t browser -- --browser firefox", | ||
"test:firefox-webworker": "aegir test -t webworker -- --browser firefox", | ||
"test:node": "aegir test -t node", | ||
"test:electron-main": "aegir test -t electron-main", | ||
"lint": "aegir lint", | ||
"dep-check": "aegir dep-check", | ||
"release": "aegir release", | ||
@@ -159,7 +158,9 @@ "docs": "aegir docs" | ||
"devDependencies": { | ||
"aegir": "^37.10.1" | ||
"aegir": "^42.2.3" | ||
}, | ||
"browser": { | ||
"fs": false | ||
} | ||
"engines": { | ||
"node": ">=16.0.0", | ||
"npm": ">=7.0.0" | ||
}, | ||
"sideEffects": false | ||
} |
160
README.md
@@ -8,50 +8,14 @@ # is-ipfs <!-- omit in toc --> | ||
## Table of contents <!-- omit in toc --> | ||
# About | ||
- [Install](#install) | ||
- [Browser `<script>` tag](#browser-script-tag) | ||
- [Usage](#usage) | ||
- [API](#api) | ||
- [Content Identifiers](#content-identifiers) | ||
- [`isIPFS.multihash(hash)`](#isipfsmultihashhash) | ||
- [`isIPFS.cid(hash)`](#isipfscidhash) | ||
- [`isIPFS.base32cid(hash)`](#isipfsbase32cidhash) | ||
- [URLs](#urls) | ||
- [`isIPFS.url(url)`](#isipfsurlurl) | ||
- [`isIPFS.ipfsUrl(url)`](#isipfsipfsurlurl) | ||
- [`isIPFS.ipnsUrl(url)`](#isipfsipnsurlurl) | ||
- [Paths](#paths) | ||
- [`isIPFS.path(path)`](#isipfspathpath) | ||
- [`isIPFS.urlOrPath(path)`](#isipfsurlorpathpath) | ||
- [`isIPFS.ipfsPath(path)`](#isipfsipfspathpath) | ||
- [`isIPFS.ipnsPath(path)`](#isipfsipnspathpath) | ||
- [`isIPFS.cidPath(path)`](#isipfscidpathpath) | ||
- [Subdomains](#subdomains) | ||
- [`isIPFS.subdomain(url)`](#isipfssubdomainurl) | ||
- [`isIPFS.ipfsSubdomain(url)`](#isipfsipfssubdomainurl) | ||
- [`isIPFS.ipnsSubdomain(url)`](#isipfsipnssubdomainurl) | ||
- [Multiaddrs](#multiaddrs) | ||
- [`isIPFS.multiaddr(addr)`](#isipfsmultiaddraddr) | ||
- [`isIPFS.peerMultiaddr(addr)`](#isipfspeermultiaddraddr) | ||
- [API Docs](#api-docs) | ||
- [License](#license) | ||
- [Contribution](#contribution) | ||
A suite of util methods that provides efficient validation. | ||
## Install | ||
Detection of IPFS Paths and identifiers in URLs is a two-stage process: | ||
```console | ||
$ npm i is-ipfs | ||
``` | ||
1. `pathPattern`/`pathGatewayPattern`/`subdomainGatewayPattern` regex is applied to quickly identify potential candidates | ||
2. proper CID validation is applied to remove false-positives | ||
### Browser `<script>` tag | ||
## Example | ||
Loading this module through a script tag will make it's exports available as `IsIpfs` in the global namespace. | ||
```html | ||
<script src="https://unpkg.com/is-ipfs/dist/index.min.js"></script> | ||
``` | ||
## Usage | ||
```javascript | ||
```TypeScript | ||
import * as isIPFS from 'is-ipfs' | ||
@@ -138,107 +102,21 @@ | ||
## API | ||
# Install | ||
A suite of util methods that provides efficient validation. | ||
```console | ||
$ npm i is-ipfs | ||
``` | ||
Detection of IPFS Paths and identifiers in URLs is a two-stage process: | ||
## Browser `<script>` tag | ||
1. `pathPattern`/`pathGatewayPattern`/`subdomainGatewayPattern` regex is applied to quickly identify potential candidates | ||
2. proper CID validation is applied to remove false-positives | ||
Loading this module through a script tag will make it's exports available as `IsIpfs` in the global namespace. | ||
### Content Identifiers | ||
```html | ||
<script src="https://unpkg.com/is-ipfs/dist/index.min.js"></script> | ||
``` | ||
#### `isIPFS.multihash(hash)` | ||
# API Docs | ||
Returns `true` if the provided string or `Uint8Array` is a valid `multihash` or `false` otherwise. | ||
#### `isIPFS.cid(hash)` | ||
Returns `true` if the provided string, `Uint8Array` or [`CID`](https://github.com/multiformats/js-multiformats/#readme) object represents a valid [CID](https://docs.ipfs.io/guides/concepts/cid/) or `false` otherwise. | ||
#### `isIPFS.base32cid(hash)` | ||
Returns `true` if the provided string is a valid `CID` in Base32 encoding or `false` otherwise. | ||
### URLs | ||
#### `isIPFS.url(url)` | ||
Returns `true` if the provided string is a valid IPFS or IPNS url or `false` otherwise. | ||
#### `isIPFS.ipfsUrl(url)` | ||
Returns `true` if the provided string is a valid IPFS url or `false` otherwise. | ||
#### `isIPFS.ipnsUrl(url)` | ||
Returns `true` if the provided string is a valid IPNS url or `false` otherwise. | ||
### Paths | ||
Standalone validation of IPFS Paths: `/ip(f|n)s/<cid>/..` | ||
#### `isIPFS.path(path)` | ||
Returns `true` if the provided string is a valid IPFS or IPNS path or `false` otherwise. | ||
#### `isIPFS.urlOrPath(path)` | ||
Returns `true` if the provided string is a valid IPFS or IPNS url or path or `false` otherwise. | ||
#### `isIPFS.ipfsPath(path)` | ||
Returns `true` if the provided string is a valid IPFS path or `false` otherwise. | ||
#### `isIPFS.ipnsPath(path)` | ||
Returns `true` if the provided string is a valid IPNS path or `false` otherwise. | ||
#### `isIPFS.cidPath(path)` | ||
Returns `true` if the provided string is a valid "CID path" (IPFS path without `/ipfs/` prefix) or `false` otherwise. | ||
### Subdomains | ||
Validated subdomain convention: `cidv1b32.ip(f|n)s.domain.tld` | ||
#### `isIPFS.subdomain(url)` | ||
Returns `true` if the provided `url` string includes a valid IPFS, looks like IPNS/DNSLink subdomain or `false` otherwise. | ||
#### `isIPFS.ipfsSubdomain(url)` | ||
Returns `true` if the provided `url` string includes a valid IPFS subdomain (case-insensitive CIDv1) or `false` otherwise. | ||
#### `isIPFS.ipnsSubdomain(url)` | ||
Returns `true` if the provided `url` string looks like a valid IPNS subdomain | ||
(CIDv1 with `libp2p-key` multicodec or something that looks like a FQDN, for example `en.wikipedia-on-ipfs.org.ipns.localhost:8080`) or `false` | ||
otherwise. | ||
**Note:** `ipnsSubdomain` method works in offline mode: it does not perform | ||
actual IPNS record lookup over DHT or other content routing method. It may | ||
return false-positives: | ||
- To ensure IPNS record exists, make a call to `/api/v0/name/resolve?arg=<ipnsid>` | ||
- To ensure DNSLink exists, make a call to `/api/v0/dns?arg=<fqdn>` | ||
### Multiaddrs | ||
Below methods provide basic detection of [multiaddr](https://github.com/multiformats/multiaddr)s: composable and future-proof network addresses. | ||
Complex validation of multiaddr can be built using `isIPFS.multiaddr` and [`mafmt`](https://github.com/multiformats/js-mafmt) library. | ||
#### `isIPFS.multiaddr(addr)` | ||
Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) or `Uint8Array` represents a valid multiaddr or `false` otherwise. | ||
#### `isIPFS.peerMultiaddr(addr)` | ||
Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) or `Uint8Array` represents a valid libp2p peer multiaddr (matching [`P2P` format from `mafmt`](https://github.com/multiformats/js-mafmt#api)) or `false` otherwise. | ||
## API Docs | ||
- <https://ipfs-shipyard.github.io/is-ipfs> | ||
## License | ||
# License | ||
@@ -250,4 +128,4 @@ Licensed under either of | ||
## Contribution | ||
# Contribution | ||
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. |
222
src/index.ts
@@ -0,10 +1,105 @@ | ||
/** | ||
* @packageDocumentation | ||
* | ||
* A suite of util methods that provides efficient validation. | ||
* | ||
* Detection of IPFS Paths and identifiers in URLs is a two-stage process: | ||
* | ||
* 1. `pathPattern`/`pathGatewayPattern`/`subdomainGatewayPattern` regex is applied to quickly identify potential candidates | ||
* 2. proper CID validation is applied to remove false-positives | ||
* | ||
* @example | ||
* | ||
* ```TypeScript | ||
* import * as isIPFS from 'is-ipfs' | ||
* | ||
* isIPFS.multihash('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.multihash('noop') // false | ||
* | ||
* isIPFS.cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true (CIDv0) | ||
* isIPFS.cid('bafybeiasb5vpmaounyilfuxbd3lryvosl4yefqrfahsb2esg46q6tu6y5q') // true (CIDv1 in Base32) | ||
* isIPFS.cid('zdj7WWeQ43G6JJvLWQWZpyHuAMq6uYWRjkBXFad11vE2LHhQ7') // true (CIDv1 in Base58btc) | ||
* isIPFS.cid('noop') // false | ||
* | ||
* isIPFS.base32cid('bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va') // true | ||
* isIPFS.base32cid('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* | ||
* isIPFS.url('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.url('https://ipfs.io/ipfs/QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR?filename=guardian.jpg') // true | ||
* isIPFS.url('https://ipfs.io/ipns/github.com') // true | ||
* isIPFS.url('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.url('http://en.wikipedia-on-ipfs.org.ipfs.localhost:8080') // true | ||
* isIPFS.url('https://github.com/ipfs/js-ipfs/blob/master/README.md') // false | ||
* isIPFS.url('https://google.com') // false | ||
* | ||
* isIPFS.path('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.path('/ipfs/QmbcBPAwCDxRMB1Qe7CRQmxdrTSkxKwM9y6rZw2FjGtbsb/?weird-filename=test.jpg') // true | ||
* isIPFS.path('/ipns/github.com') // true | ||
* isIPFS.path('/ipfs/js-ipfs/blob/master/README.md') // false | ||
* | ||
* isIPFS.urlOrPath('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.urlOrPath('https://ipfs.io/ipns/github.com') // true | ||
* isIPFS.urlOrPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.urlOrPath('/ipns/github.com') // true | ||
* isIPFS.urlOrPath('https://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.urlOrPath('https://google.com') // false | ||
* | ||
* isIPFS.ipfsUrl('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.ipfsUrl('https://ipfs.io/ipfs/invalid-hash') // false | ||
* | ||
* isIPFS.ipnsUrl('https://ipfs.io/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.ipnsUrl('https://ipfs.io/ipns/github.com') // true | ||
* | ||
* isIPFS.ipfsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // true | ||
* isIPFS.ipfsPath('/ipfs/invalid-hash') // false | ||
* | ||
* isIPFS.ipnsPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.ipnsPath('/ipns/github.com') // true | ||
* | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/path/to/file') // true | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/') // true | ||
* isIPFS.cidPath('QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.cidPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o') // false | ||
* isIPFS.cidPath('/ipfs/QmYjtig7VJQ6XsnUjqqJvj7QaMcCAwtrgNdahSiFofrE7o/file') // false | ||
* | ||
* isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.subdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true | ||
* isIPFS.subdomain('http://www.bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // false | ||
* isIPFS.subdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false | ||
* | ||
* isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.ipfs.dweb.link') // true | ||
* isIPFS.ipfsSubdomain('http://bafybeie5gq4jxvzmsym6hjlwxej4rwdoxt7wadqvmmwbqi7r27fclha2va.dweb.link') // false | ||
* | ||
* isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.ipns.dweb.link') // true | ||
* isIPFS.ipnsSubdomain('http://bafybeiabc2xofh6tdi6vutusorpumwcikw3hf3st4ecjugo6j52f6xwc6q.dweb.link') // false | ||
* isIPFS.ipnsSubdomain('http://QmcNioXSC1bfJj1dcFErhUfyjFzoX2HodkRccsFFVJJvg8.ipns.dweb.link') // false | ||
* isIPFS.ipnsSubdomain('http://en.wikipedia-on-ipfs.org.ipns.localhost:8080') // true (assuming DNSLink) | ||
* isIPFS.ipnsSubdomain('http://en-wikipedia--on--ipfs-org.ipns.localhost:8080') // true (assuming inlined DNSLink) | ||
* isIPFS.ipnsSubdomain('http://hostname-without-tld-.ipns.dweb.link') // false (not a CID, invalid DNS label) | ||
* | ||
* isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234') // true | ||
* isIPFS.multiaddr('/ip4/127.0.0.1/udp/1234/http') // true | ||
* isIPFS.multiaddr('/ip6/::1/udp/1234') // true | ||
* isIPFS.multiaddr('ip6/::1/udp/1234') // false | ||
* isIPFS.multiaddr('/yoloinvalid/::1/udp/1234') // false | ||
* | ||
* isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true | ||
* isIPFS.peerMultiaddr('/ipfs/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4') // true (legacy notation) | ||
* isIPFS.peerMultiaddr('/ip4/127.0.0.1/tcp/1234/ws/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true | ||
* isIPFS.peerMultiaddr('/p2p/QmcgpsyWgH8Y8ajJz1Cu72KnS5uo2Aa2LpzU7kinSoooo4/p2p-circuit/p2p/QmUjNmr8TgJCn1Ao7DvMy4cjoZU15b9bwSCBLE3vwXiwgj') // true | ||
* isIPFS.peerMultiaddr('/dnsaddr/bootstrap.libp2p.io') // false (key missing, needs additional DNS lookup to tell if this is valid) | ||
* isIPFS.peerMultiaddr('/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN') // true (key present, ip and port can be resolved later) | ||
* isIPFS.peerMultiaddr('/ip4/127.0.0.1/udp/1234') // false (key missing) | ||
* ``` | ||
*/ | ||
import * as mafmt from '@multiformats/mafmt' | ||
import { multiaddr } from '@multiformats/multiaddr' | ||
import { URL } from 'iso-url' | ||
import { base32 } from 'multiformats/bases/base32' | ||
import { base58btc } from 'multiformats/bases/base58' | ||
import { base32 } from 'multiformats/bases/base32' | ||
import { CID } from 'multiformats/cid' | ||
import * as Digest from 'multiformats/hashes/digest' | ||
import { multiaddr } from '@multiformats/multiaddr' | ||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string' | ||
import type { Multiaddr } from '@multiformats/multiaddr' | ||
import * as mafmt from '@multiformats/mafmt' | ||
import { CID } from 'multiformats/cid' | ||
import { URL } from 'iso-url' | ||
import { toString as uint8ArrayToString } from 'uint8arrays/to-string' | ||
@@ -32,3 +127,3 @@ export const pathGatewayPattern = /^https?:\/\/[^/]+\/(ip[fn]s)\/([^/?#]+)/ | ||
try { | ||
Digest.decode(base58btc.decode('z' + formatted)) | ||
Digest.decode(base58btc.decode(`z${formatted}`)) | ||
} catch { | ||
@@ -100,3 +195,3 @@ return false | ||
*/ | ||
function isIpfs (input: string | Uint8Array, pattern: RegExp | string, protocolMatch: number = defaultProtocolMatch, hashMatch: number = defaultHashMath) { | ||
function isIpfs (input: string | Uint8Array, pattern: RegExp | string, protocolMatch: number = defaultProtocolMatch, hashMatch: number = defaultHashMath): boolean { | ||
const formatted = convertToString(input) | ||
@@ -135,3 +230,3 @@ if (formatted === false) { | ||
*/ | ||
function isIpns (input: string | Uint8Array, pattern: RegExp | string, protocolMatch: number = defaultProtocolMatch, hashMatch: number = defaultHashMath) { | ||
function isIpns (input: string | Uint8Array, pattern: RegExp | string, protocolMatch: number = defaultProtocolMatch, hashMatch: number = defaultHashMath): boolean { | ||
const formatted = convertToString(input) | ||
@@ -189,3 +284,3 @@ if (formatted === false) { | ||
*/ | ||
function convertToString (input: Uint8Array | string) { | ||
function convertToString (input: Uint8Array | string): string | false { | ||
if (input instanceof Uint8Array) { | ||
@@ -202,19 +297,102 @@ return uint8ArrayToString(input, 'base58btc') | ||
export const ipfsSubdomain = (url: string | Uint8Array) => isIpfs(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch) | ||
export const ipnsSubdomain = (url: string | Uint8Array) => isIpns(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch) | ||
export const subdomain = (url: string | Uint8Array) => ipfsSubdomain(url) || ipnsSubdomain(url) | ||
export const ipfsUrl = (url: string | Uint8Array) => isIpfs(url, pathGatewayPattern) || ipfsSubdomain(url) | ||
export const ipnsUrl = (url: string | Uint8Array) => isIpns(url, pathGatewayPattern) || ipnsSubdomain(url) | ||
export const url = (url: string | Uint8Array) => ipfsUrl(url) || ipnsUrl(url) || subdomain(url) | ||
export const path = (path: string | Uint8Array) => isIpfs(path, pathPattern) || isIpns(path, pathPattern) | ||
/** | ||
* Returns `true` if the provided `url` string includes a valid IPFS subdomain | ||
* (case-insensitive CIDv1) or `false` otherwise. | ||
*/ | ||
export const ipfsSubdomain = (url: string | Uint8Array): boolean => isIpfs(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch) | ||
/** | ||
* Returns `true` if the provided `url` string looks like a valid IPNS subdomain | ||
* (CIDv1 with `libp2p-key` multicodec or something that looks like a FQDN, for | ||
* example `en.wikipedia-on-ipfs.org.ipns.localhost:8080`) or `false` otherwise. | ||
* | ||
* **Note:** `ipnsSubdomain` method works in offline mode: it does not perform | ||
* actual IPNS record lookup over DHT or other content routing method. It may | ||
* return false-positives: | ||
* | ||
* - To ensure IPNS record exists, make a call to `/api/v0/name/resolve?arg=<ipnsid>` | ||
* - To ensure DNSLink exists, make a call to `/api/v0/dns?arg=<fqdn>` | ||
*/ | ||
export const ipnsSubdomain = (url: string | Uint8Array): boolean => isIpns(url, subdomainGatewayPattern, subdomainProtocolMatch, subdomainIdMatch) | ||
/** | ||
* Returns `true` if the provided `url` string includes a valid IPFS, looks like | ||
* an IPNS/DNSLink subdomain or `false` otherwise. | ||
*/ | ||
export const subdomain = (url: string | Uint8Array): boolean => ipfsSubdomain(url) || ipnsSubdomain(url) | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS url or `false` | ||
* otherwise. | ||
*/ | ||
export const ipfsUrl = (url: string | Uint8Array): boolean => isIpfs(url, pathGatewayPattern) || ipfsSubdomain(url) | ||
/** | ||
* Returns `true` if the provided string is a valid IPNS url or `false` | ||
* otherwise. | ||
*/ | ||
export const ipnsUrl = (url: string | Uint8Array): boolean => isIpns(url, pathGatewayPattern) || ipnsSubdomain(url) | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS url or `false` | ||
* otherwise. | ||
*/ | ||
export const url = (url: string | Uint8Array): boolean => ipfsUrl(url) || ipnsUrl(url) || subdomain(url) | ||
export const path = (path: string | Uint8Array): boolean => isIpfs(path, pathPattern) || isIpns(path, pathPattern) | ||
/** | ||
* Returns `true` if the provided string or `Uint8Array` is a valid `multihash` | ||
* or `false` otherwise. | ||
*/ | ||
export { isMultihash as multihash } | ||
/** | ||
* Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) | ||
* or `Uint8Array` represents a valid multiaddr or `false` otherwise. | ||
*/ | ||
export { isMultiaddr as multiaddr } | ||
/** | ||
* Returns `true` if the provided `string`, [`Multiaddr`](https://github.com/multiformats/js-multiaddr) | ||
* or `Uint8Array` represents a valid libp2p peer multiaddr (matching [`P2P` | ||
* format from `mafmt`](https://github.com/multiformats/js-mafmt#api)) or | ||
* `false` otherwise. | ||
*/ | ||
export { isPeerMultiaddr as peerMultiaddr } | ||
/** | ||
* Returns `true` if the provided string, `Uint8Array` or [`CID`](https://github.com/multiformats/js-multiformats/#readme) | ||
* object represents a valid [CID](https://docs.ipfs.io/guides/concepts/cid/) or | ||
* `false` otherwise. | ||
*/ | ||
export { isCID as cid } | ||
export const base32cid = (cid: CID | string | Uint8Array) => (isCID(cid) && isBase32EncodedMultibase(cid)) | ||
export const ipfsPath = (path: string | Uint8Array) => isIpfs(path, pathPattern) | ||
export const ipnsPath = (path: string | Uint8Array) => isIpns(path, pathPattern) | ||
export const urlOrPath = (x: string | Uint8Array) => url(x) || path(x) | ||
export const cidPath = (path: string | Uint8Array | CID) => isString(path) && !isCID(path) && isIpfs(`/ipfs/${path}`, pathPattern) | ||
/** | ||
* Returns `true` if the provided string is a valid `CID` in Base32 encoding or | ||
* `false` otherwise. | ||
*/ | ||
export const base32cid = (cid: CID | string | Uint8Array): boolean => (isCID(cid) && isBase32EncodedMultibase(cid)) | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS path or `false` | ||
* otherwise. | ||
*/ | ||
export const ipfsPath = (path: string | Uint8Array): boolean => isIpfs(path, pathPattern) | ||
/** | ||
* Returns `true` if the provided string is a valid IPNS path or `false` | ||
* otherwise. | ||
*/ | ||
export const ipnsPath = (path: string | Uint8Array): boolean => isIpns(path, pathPattern) | ||
/** | ||
* Returns `true` if the provided string is a valid IPFS or IPNS url or path or | ||
* `false` otherwise. | ||
*/ | ||
export const urlOrPath = (x: string | Uint8Array): boolean => url(x) || path(x) | ||
/** | ||
* Returns `true` if the provided string is a valid "CID path" (IPFS path | ||
* without `/ipfs/` prefix) or `false` otherwise. | ||
*/ | ||
export const cidPath = (path: string | Uint8Array | CID): boolean => isString(path) && !isCID(path) && isIpfs(`/ipfs/${path}`, pathPattern) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
128766
1182
129