UNPKG

@sanity/asset-utils

Version:

<!-- This file is AUTO-GENERATED, edit _README.template.md or tweak scripts/generateDocs.ts -->

190 lines (168 loc) 5.63 kB
import {isCdnUrl} from './asserters.js' import { fileAssetIdPattern, imageAssetFilenamePattern, imageAssetIdPattern, pathPattern, } from './constants.js' import {isValidFilename, tryGetUrlFilename} from './paths.js' import type { SanityAssetIdParts, SanityAssetUrlParts, SanityFileAssetIdParts, SanityFileUrlParts, SanityImageAssetIdParts, SanityImageUrlParts, } from './types.js' /** * @internal */ const exampleFileId = 'file-027401f31c3ac1e6d78c5d539ccd1beff72b9b11-pdf' /** * @internal */ const exampleImageId = 'image-027401f31c3ac1e6d78c5d539ccd1beff72b9b11-2000x3000-jpg' /** * Parses a Sanity asset document ID into individual parts (type, id, extension, width/height etc) * * @param documentId - Document ID to parse into named parts * @returns Object of named properties * @public * @throws If document ID is invalid */ export function parseAssetId(documentId: string): SanityAssetIdParts { if (imageAssetIdPattern.test(documentId)) { return parseImageAssetId(documentId) } if (fileAssetIdPattern.test(documentId)) { return parseFileAssetId(documentId) } throw new Error(`Invalid image/file asset ID: ${documentId}`) } /** * Parses a Sanity file asset document ID into individual parts (type, id, extension) * * @param documentId - File asset document ID to parse into named parts * @returns Object of named properties * @public * @throws If document ID invalid */ export function parseFileAssetId(documentId: string): SanityFileAssetIdParts { if (!fileAssetIdPattern.test(documentId)) { throw new Error( `Malformed file asset ID '${documentId}'. Expected an id like "${exampleFileId}"`, ) } const [, assetId, extension] = documentId.split('-') return {type: 'file', assetId, extension} } /** * Parses a Sanity image asset document ID into individual parts (type, id, extension, width, height) * * @param documentId - Image asset document ID to parse into named parts * @returns Object of named properties * @public * @throws If document ID invalid */ export function parseImageAssetId(documentId: string): SanityImageAssetIdParts { const [, assetId, dimensionString, extension] = documentId.split('-') const [width, height] = (dimensionString || '').split('x').map(Number) if (!assetId || !dimensionString || !extension || !(width > 0) || !(height > 0)) { throw new Error(`Malformed asset ID '${documentId}'. Expected an id like "${exampleImageId}".`) } return {type: 'image', assetId, width, height, extension} } /** * Parses a Sanity asset filename into individual parts (type, id, extension, width, height) * * @param filename - Filename to parse into named parts * @returns Object of named properties * @public * @throws If image/filename is invalid */ export function parseAssetFilename(filename: string): SanityAssetIdParts { const file = tryGetUrlFilename(filename) || '' if (!isValidFilename(file)) { throw new Error(`Invalid image/file asset filename: ${filename}`) } try { const type = imageAssetFilenamePattern.test(file) ? 'image' : 'file' const assetId = file.replace(/\.([a-z0-9+]+)$/i, '-$1') return parseAssetId(`${type}-${assetId}`) } catch (err) { throw new Error(`Invalid image/file asset filename: ${filename}`) } } /** * Parses a full Sanity asset URL into individual parts * (type, project ID, dataset, id, extension, width, height) * * @param url - Full URL to parse into named parts * @returns Object of named properties * @public * @throws If URL is invalid or not a Sanity asset URL */ export function parseAssetUrl(url: string): SanityAssetUrlParts { if (!isCdnUrl(url)) { throw new Error(`URL is not a valid Sanity asset URL: ${url}`) } const path = new URL(url).pathname.replace(/^\/+/, '') const [projectPath, , projectId, dataset] = path.match(pathPattern) || [] if (!projectPath || !projectId || !dataset) { throw new Error(`URL is not a valid Sanity asset URL: ${url}`) } const [filename, vanityFilename] = path.slice(projectPath.length).split('/') const parsed = parseAssetFilename(filename) return { ...parsed, projectId, dataset, vanityFilename, } } /** * Parses a full Sanity image asset URL into individual parts * (type, project ID, dataset, id, extension, width, height) * * @param url - Full URL to parse into named parts * @returns Object of named properties * @public * @throws If URL is invalid or not a Sanity image asset URL */ export function parseImageAssetUrl(url: string): SanityImageUrlParts { const parsed = parseAssetUrl(url) if (parsed.type !== 'image') { throw new Error(`URL is not a valid Sanity image asset URL: ${url}`) } return parsed } /** * Parses a full Sanity file asset URL into individual parts * (type, project ID, dataset, id, extension, width, height) * * @param url - Full URL to parse into named parts * @returns Object of named properties * @public * @throws If URL is invalid or not a Sanity file asset URL */ export function parseFileAssetUrl(url: string): SanityFileUrlParts { const parsed = parseAssetUrl(url) if (parsed.type !== 'file') { throw new Error(`URL is not a valid Sanity file asset URL: ${url}`) } return parsed } /** * Validates that a given URL is a Sanity asset URL, and returns the asset type if valid. * * @param url - URL to extract asset type from * @returns Asset type if valid URL, false otherwise * @public */ export function getAssetUrlType(url: string): 'image' | 'file' | false { try { return parseAssetUrl(url).type } catch (err) { return false } }