@helia/verified-fetch
Version:
A fetch-like API for obtaining verified & trustless IPFS content on the web
150 lines • 4.64 kB
JavaScript
import { code as dagCborCode } from '@ipld/dag-cbor';
import { code as dagJsonCode } from '@ipld/dag-json';
import { code as dagPbCode } from '@ipld/dag-pb';
import { code as jsonCode } from 'multiformats/codecs/json';
import { code as rawCode } from 'multiformats/codecs/raw';
/**
* This maps supported response types for each codec supported by verified-fetch
*/
const CID_TYPE_MAP = {
[dagCborCode]: [
'application/json',
'application/vnd.ipld.dag-cbor',
'application/cbor',
'application/vnd.ipld.dag-json',
'application/octet-stream',
'application/vnd.ipld.raw',
'application/vnd.ipfs.ipns-record',
'application/vnd.ipld.car',
'text/html'
],
[dagJsonCode]: [
'application/json',
'application/vnd.ipld.dag-cbor',
'application/cbor',
'application/vnd.ipld.dag-json',
'application/octet-stream',
'application/vnd.ipld.raw',
'application/vnd.ipfs.ipns-record',
'application/vnd.ipld.car'
],
[jsonCode]: [
'application/json',
'application/vnd.ipld.dag-cbor',
'application/cbor',
'application/vnd.ipld.dag-json',
'application/octet-stream',
'application/vnd.ipld.raw',
'application/vnd.ipfs.ipns-record',
'application/vnd.ipld.car'
],
[dagPbCode]: [
'application/octet-stream',
'application/json',
'application/vnd.ipld.dag-cbor',
'application/cbor',
'application/vnd.ipld.dag-json',
'application/vnd.ipld.raw',
'application/vnd.ipfs.ipns-record',
'application/vnd.ipld.car',
'application/x-tar'
],
[rawCode]: [
'application/octet-stream',
'application/vnd.ipld.raw',
'application/vnd.ipfs.ipns-record',
'application/vnd.ipld.dag-json',
'application/vnd.ipld.car',
'application/x-tar'
]
};
/**
* Selects an output mime-type based on the CID and a passed `Accept` header
*/
export function selectOutputType(cid, accept) {
const cidMimeTypes = CID_TYPE_MAP[cid.code];
if (accept != null) {
return chooseMimeType(accept, cidMimeTypes);
}
}
function chooseMimeType(accept, validMimeTypes) {
const requestedMimeTypes = accept
.split(',')
.map(s => {
const parts = s.trim().split(';');
return {
mimeType: `${parts[0]}`.trim(),
weight: parseQFactor(parts[1])
};
})
.sort((a, b) => {
if (a.weight === b.weight) {
return 0;
}
if (a.weight > b.weight) {
return -1;
}
return 1;
})
.map(s => s.mimeType);
for (const headerFormat of requestedMimeTypes) {
for (const mimeType of validMimeTypes) {
if (headerFormat.includes(mimeType)) {
return mimeType;
}
if (headerFormat === '*/*') {
return mimeType;
}
if (headerFormat.startsWith('*/') && mimeType.split('/')[1] === headerFormat.split('/')[1]) {
return mimeType;
}
if (headerFormat.endsWith('/*') && mimeType.split('/')[0] === headerFormat.split('/')[0]) {
return mimeType;
}
}
}
}
/**
* Parses q-factor weighting from the accept header to allow letting some mime
* types take precedence over others.
*
* If the q-factor for an acceptable mime representation is omitted it defaults
* to `1`.
*
* All specified values should be in the range 0-1.
*
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept#q
*/
function parseQFactor(str) {
if (str != null) {
str = str.trim();
}
if (str?.startsWith('q=') !== true) {
return 1;
}
const factor = parseFloat(str.replace('q=', ''));
if (isNaN(factor)) {
return 0;
}
return factor;
}
export const FORMAT_TO_MIME_TYPE = {
raw: 'application/vnd.ipld.raw',
car: 'application/vnd.ipld.car',
'dag-json': 'application/vnd.ipld.dag-json',
'dag-cbor': 'application/vnd.ipld.dag-cbor',
json: 'application/json',
cbor: 'application/cbor',
'ipns-record': 'application/vnd.ipfs.ipns-record',
tar: 'application/x-tar'
};
/**
* Converts a `format=...` query param to a mime type as would be found in the
* `Accept` header, if a valid mapping is available
*/
export function queryFormatToAcceptHeader(format) {
if (format != null) {
return FORMAT_TO_MIME_TYPE[format];
}
}
//# sourceMappingURL=select-output-type.js.map