UNPKG

@cross-nft-marketplace/auction-house-nft-components

Version:
177 lines (176 loc) 7.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.fetchContentMimeTypes = exports.fetchContentMimeType = exports.resolveURIGateways = exports.getAppropriateMedia = exports.getMediaType = exports.getMediaSizeForRendering = void 0; const auction_house_nft_hooks_1 = require("@cross-nft-marketplace/auction-house-nft-hooks"); const RendererConfig_1 = require("./RendererConfig"); const FetchWithTimeout_1 = require("@cross-nft-marketplace/auction-house-nft-hooks/dist/fetcher/FetchWithTimeout"); const TAKE_LEFT = -1; const TAKE_RIGHT = 1; const INDEX_MISSED = -1; function getCdnIndex(uri, cdnHostsSortedByPriority) { let url = new URL(uri); let host = url.hostname; //example: lh3.googleusercontent.com return cdnHostsSortedByPriority.findIndex(cdn => host.endsWith(cdn)); } function getMediaSizeForRendering(renderingContext) { return renderingContext === "FULL" ? auction_house_nft_hooks_1.MediaSize.ORIGINAL : auction_house_nft_hooks_1.MediaSize.THUMBNAIL; } exports.getMediaSizeForRendering = getMediaSizeForRendering; const MEDIA_TYPES_FULL = [ auction_house_nft_hooks_1.MediaType.MODEL, auction_house_nft_hooks_1.MediaType.VIDEO, auction_house_nft_hooks_1.MediaType.IMAGE, auction_house_nft_hooks_1.MediaType.DOCUMENT, auction_house_nft_hooks_1.MediaType.AUDIO, auction_house_nft_hooks_1.MediaType.TEXT, auction_house_nft_hooks_1.MediaType.UNKNOWN ]; const MEDIA_TYPES_PREVIEW = [ auction_house_nft_hooks_1.MediaType.VIDEO, auction_house_nft_hooks_1.MediaType.IMAGE, auction_house_nft_hooks_1.MediaType.DOCUMENT, auction_house_nft_hooks_1.MediaType.AUDIO, auction_house_nft_hooks_1.MediaType.MODEL, auction_house_nft_hooks_1.MediaType.TEXT, auction_house_nft_hooks_1.MediaType.UNKNOWN ]; function getMediaType(mimeType) { if (mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.IMAGE_GIF) || mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.VIDEO)) { return auction_house_nft_hooks_1.MediaType.VIDEO; //todo rename to "ANIMATION" } if (mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.IMAGE)) { return auction_house_nft_hooks_1.MediaType.IMAGE; } if (mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.AUDIO)) { return auction_house_nft_hooks_1.MediaType.AUDIO; } if (mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.HTML) || mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.PDF_DOCUMENT)) { return auction_house_nft_hooks_1.MediaType.DOCUMENT; } if (mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.MODEL)) { return auction_house_nft_hooks_1.MediaType.MODEL; } if (mimeType.startsWith(RendererConfig_1.MIME_TYPES_CONTENT.TEXT)) { return auction_house_nft_hooks_1.MediaType.TEXT; } return auction_house_nft_hooks_1.MediaType.UNKNOWN; } exports.getMediaType = getMediaType; //todo support unknown size // Stages: // 1) Filter by supported mimeTypes // 2) Do not give preference big medias for preview and preview media for full // 3) Sort by MediaType // 4) Sort by CDN function getAppropriateMedia(medias, target, options) { let mediasWithMediaType = medias.filter((media) => { if (media.meta.mimeType == "") { return false; } return target.mimeTypes.some(mimeType => media.meta.mimeType.startsWith(mimeType)); }); if (mediasWithMediaType.length == 0) { //todo handle no mimeType (ex: cors), possible use mediaType instead. } let sortedMedias = mediasWithMediaType.sort((first, second) => { if (target.mediaSize == auction_house_nft_hooks_1.MediaSize.THUMBNAIL) { if (first.meta.sizeInBytes != null) { if (second.meta.sizeInBytes != null) { if (first.meta.sizeInBytes < options.maxPreviewSizeInBytes && second.meta.sizeInBytes > options.maxPreviewSizeInBytes) { return TAKE_LEFT; } if (first.meta.sizeInBytes > options.maxPreviewSizeInBytes && second.meta.sizeInBytes < options.maxPreviewSizeInBytes) { return TAKE_RIGHT; } } else { //todo } } else { //todo } } //sort by MediaSize //dont use preview for nft-full if (target.mediaSize == auction_house_nft_hooks_1.MediaSize.ORIGINAL) { if (first.mediaSize != auction_house_nft_hooks_1.MediaSize.THUMBNAIL && second.mediaSize == auction_house_nft_hooks_1.MediaSize.THUMBNAIL) { return TAKE_LEFT; } if (first.mediaSize == auction_house_nft_hooks_1.MediaSize.THUMBNAIL && second.mediaSize != auction_house_nft_hooks_1.MediaSize.THUMBNAIL) { return TAKE_RIGHT; } } //sort by MediaType //todo only from supported renderers let mediaTypeFirst = getMediaType(first.meta.mimeType); let mediaTypeSecond = getMediaType(second.meta.mimeType); let priorityList = target.mediaSize == auction_house_nft_hooks_1.MediaSize.THUMBNAIL ? MEDIA_TYPES_PREVIEW : MEDIA_TYPES_FULL; let mediaTypeIndexFirst = priorityList.indexOf(mediaTypeFirst); let mediaTypeIndexSecond = priorityList.indexOf(mediaTypeSecond); if (mediaTypeIndexFirst < mediaTypeIndexSecond) { return TAKE_LEFT; } else if (mediaTypeIndexFirst > mediaTypeIndexSecond) { return TAKE_RIGHT; } //sort by CDN let cdnIndexFirst = getCdnIndex(first.url, options.cdnHosts); let cdnIndexSecond = getCdnIndex(second.url, options.cdnHosts); if (cdnIndexFirst != INDEX_MISSED && cdnIndexSecond == INDEX_MISSED) { return TAKE_LEFT; } else if (cdnIndexFirst == INDEX_MISSED && cdnIndexSecond != INDEX_MISSED) { return TAKE_RIGHT; } else if (cdnIndexFirst != cdnIndexSecond) { return cdnIndexFirst - cdnIndexSecond; } else { return 0; } }); return sortedMedias[0]; } exports.getAppropriateMedia = getAppropriateMedia; function resolveURIGateways(uri, preferredIPFSGateway) { if (uri.startsWith("ipfs://")) { return uri.replace("ipfs://", preferredIPFSGateway || "https://ipfs.io/ipfs/"); } if (uri.includes("/ipfs/") && preferredIPFSGateway) { return `${preferredIPFSGateway}${uri.replace(/^.+\/ipfs\//, "")}`; } if (uri.startsWith("ar://")) { return uri.replace("ar://", "https://arweave.net/"); } return uri; } exports.resolveURIGateways = resolveURIGateways; async function fetchContentMimeType(url, preferredIPFSGateway) { const response = await new FetchWithTimeout_1.FetchWithTimeout(2000).fetch(resolveURIGateways(url, preferredIPFSGateway), { method: 'HEAD', }); const mimeType = response.headers.get('content-type'); let size = undefined; let sizeHeader = response.headers.get('content-length'); if (sizeHeader) { let parsedSize = parseInt(sizeHeader); if (!isNaN(parsedSize)) { size = parsedSize; } } return { mimeType: mimeType || "", sizeInBytes: size }; } exports.fetchContentMimeType = fetchContentMimeType; async function fetchContentMimeTypes(urls, preferredIPFSGateway) { let promises = urls.map(url => fetchContentMimeType(url, preferredIPFSGateway).catch(_ => { return { mimeType: "" }; })); let mimeTypes = await Promise.all(promises); return mimeTypes; } exports.fetchContentMimeTypes = fetchContentMimeTypes;