PageSourceSearch

https://www.paulmitchell.com/cdn/shop/t/424/assets/lib-storefront.js?v=77550925278960261731783361503

js paulmitchell.com collected 2026-10-01 12:07:48 UTC 6,190 bytes, 2 lines download raw bytes

1import{GetProductById,GetProductsByBatch,GetVariantById}from"@nova/queries";import{isStringifiedArray}from"@nova/utils";import"@vendor/storefront-client";const registerGlobal=window.DNARegisterGlobal;class StorefrontClient{constructor(storeDomain=__NOVA_GLOBAL__.domain,apiVersion="2024-04",publicAccessToken=__NOVA_GLOBAL__.storefrontToken){this.client=ShopifyStorefrontAPIClient.createStorefrontApiClient({storeDomain,apiVersion,publicAccessToken})}async getProductById(id){const response=await this.client.request(GetProductById,{variables:{id:`gid://shopify/Product/${id}`}});return cleanUpProductData(response?.data?.node)}async getVariantById(id){const response=await this.client.request(GetVariantById,{variables:{id:`gid://shopify/ProductVariant/${id}`}});return cleanUpVariantData(response?.data?.node)}async getProductsByBatch(ids){const structuredIds=[];for(let i=0;i<ids.length;i++)structuredIds.push(`gid://shopify/Product/${ids[i]}`);const response=await this.client.request(GetProductsByBatch,{variables:{ids:structuredIds}});return cleanUpProductsData(response?.data)}}const normalizePrice=price=>[null,void 0].includes(price)?null:Number(price)*100;function stripGID(value){const gidPattern=/^gid:\/\/shopify\/\w+\//;return gidPattern.test(value)?value.replace(gidPattern,""):value}function cleanUpMetafields(rawMetafields){return rawMetafields?rawMetafields.filter(m=>m!==null).reduce((acc,metafield)=>{acc[metafield.namespace]||(acc[metafield.namespace]={});let value;return Object.keys(metafield.reference||{}).includes("image")?value=metafield.reference.image.originalSrc:Object.keys(metafield.reference||{}).includes("url")?value=metafield.reference.url:isStringifiedArray(metafield.value)?value=JSON.parse(metafield.value).map(i=>stripGID(i)):value=stripGID(metafield.value),acc[metafield.namespace][metafield.key]=value,acc},{}):{}}function cleanupMetaobjects(metaobjects){return Array.isArray(metaobjects)?metaobjects.map(edge=>{if(!edge||!edge.node)return console.warn("Invalid metaobject edge. Skipping."),null;const{node}=edge,{id,handle,type,updatedAt,onlineStoreUrl,fields}=node,cleanedFields=Array.isArray(fields)?fields.reduce((acc,field)=>!field||!field.key?(console.warn("Invalid field data. Skipping."),acc):(acc[field.key]=field.value,acc),{}):{};return{id:stripGID(id),handle,type,updatedAt,onlineStoreUrl,fields:cleanedFields}}).filter(Boolean):(console.warn("Invalid metaobjects data. Expected an array."),[])}function cleanUpProductData(rawProduct){if(!rawProduct)return null;const variantsSortedByPrice=rawProduct.variants?.edges?.sort((a,b)=>{const priceA=Number.parseFloat(a.node.priceV2.amount),priceB=Number.parseFloat(a.node.priceV2.amount);return priceA<priceB?-1:priceA>priceB?1:0})||[],lowestPriceVariant=variantsSortedByPrice[0];let compareAtPrice=null;if(variantsSortedByPrice.length){const compareAtPriceProperty=lowestPriceVariant.node.compareAtPriceV2?.amount;compareAtPriceProperty&&(compareAtPrice=Number.parseFloat(compareAtPriceProperty))}return{id:stripGID(rawProduct.id),available:rawProduct.availableForSale,title:rawProduct.title,description:rawProduct.descriptionHtml,minPrice:normalizePrice(rawProduct.priceRange?.minVariantPrice?.amount),maxPrice:normalizePrice(rawProduct.priceRange?.maxVariantPrice?.amount),compareAtPrice:normalizePrice(compareAtPrice),handle:rawProduct.handle,type:rawProduct.productType,vendor:rawProduct.vendor,createdAt:new Date(rawProduct.createdAt),updatedAt:new Date(rawProduct.updatedAt),publishedAt:new Date(rawProduct.publishedAt),onlineStoreUrl:rawProduct.onlineStoreUrl,tags:rawProduct.tags,media:rawProduct?.media?.edges.map(edge=>cleanUpMediaData(edge.node)),options:rawProduct.options,collections:rawProduct.collections?.edges.map(edge=>cleanUpCollectionData(edge)),variants:rawProduct.variants?.edges.map(edge=>cleanUpVariantData(edge.node)),metafields:cleanUpMetafields(rawProduct.metafields),isDiscounted:rawProduct.variants?.edges.some(variantEdge=>{const variant=variantEdge.node,originalPrice=Number.parseFloat(variant.priceV2.amount);return Number.parseFloat(variant.compareAtPriceV2?.amount)>originalPrice})}}function cleanUpProductsData(rawData){return rawData?rawData.nodes.map(product=>cleanUpProductData(product)):null}function cleanUpMediaData(rawMedia){if(!rawMedia)return null;const type=rawMedia?.mediaContentType.toLowerCase();switch(type){case"image":return{type,url:rawMedia?.image?.url,alt:rawMedia?.alt};case"video":return{type,url:rawMedia?.sources[0]?.url,alt:rawMedia?.alt,poster:rawMedia?.previewImage?.url}}}function cleanUpVariantData(rawVariant){return rawVariant?{id:stripGID(rawVariant?.id),title:rawVariant?.t
1itle,price:normalizePrice(rawVariant?.priceV2?.amount),compareAtPrice:normalizePrice(rawVariant?.compareAtPriceV2?.amount),currencyCode:rawVariant?.priceV2?.currencyCode,available:rawVariant?.availableForSale,sku:rawVariant?.sku,selectedOptions:rawVariant?.selectedOptions,quantityAvailable:rawVariant?.quantityAvailable,currentlyNotInStock:rawVariant?.currentlyNotInStock,metafields:cleanUpMetafields(rawVariant?.metafields)}:null}function cleanUpSearchData(rawData){return rawData?rawData.products.edges.map(product=>cleanUpProductData(product)):null}function cleanUpCollectionData(rawData){if(!rawData||!rawData.node)return null;const rawCollection=rawData.node;return{id:stripGID(rawCollection.id),title:rawCollection.title,handle:rawCollection.handle,description:rawCollection.descriptionHtml,updatedAt:new Date(rawCollection.updatedAt),publishedAt:new Date(rawCollection.publishedAt),image:rawCollection.image,products:rawCollection.products?.edges.map(edge=>cleanUpProductData(edge)),metafields:cleanUpMetafields(rawCollection.metafields)}}export function mapMetaobjectsByHandle(metaobjects){return Array.isArray(metaobjects)?metaobjects.reduce((acc,metaobject)=>{if(!metaobject||!metaobject.handle)return console.warn("Invalid metaobject data. Skipping."),acc;const{handle,...rest}=metaobject;return acc[handle]=rest,acc},{}):(console.warn("Invalid metaobjects data. Expected an array."),{})}export const storefrontClient=new StorefrontClient;
2//# sourceMappingURL=/cdn/shop/t/424/assets/lib-storefront.js.map?v=77550925278960261731783361503

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.