import { readFileSync } from 'fs' ; import { join } from 'path' ; import slugify from 'slugify' ; import type { ParentSpanPluginArgs } from 'gatsby' ; import { PLUGIN } from '../../../constants' ; import { fetchVTEX } from '../../../fetch' ; import { api } from '../../../api' ; import type { Brand , Category } from '../../../types' ; import type { VTEXOptions as Options } from '../../../fetch' ; type CollectionType = 'Department' | 'Category' | 'Brand' | 'Cluster' ; export interface StoreCollection { id : string ; remoteId : string ; seo : { title : string ; description : string ; } ; meta : { selectedFacets : Array < { key : string ; value : string ; } > ; } ; slug : string ; parent ? : string ; children ? : string [ ] ; type : CollectionType ; } interface Config { gatsbyApi : ParentSpanPluginArgs ; options : Options ; } const gatsbyPath = ( path ) => slugify ( path , { replacement : '-' , lower : true } ) ; export const typeDefs = readFileSync ( join ( __dirname , '../src/graphql/types/collection/typeDefs.graphql' ) ) . toString ( ) ; const typeName = `StoreCollection` ; const createNodeId = ( id , type , gatsbyApi ) => gatsbyApi . createNodeId ( `${ typeName }:${ type }:${ id }` ) ; export const createNode = ( gatsbyApi , node ) => { const id = createNodeId ( node . id , node . type , gatsbyApi ) ; const parentType = node . type === 'Category' ? 'Department' : node . type ; const childType = node . type === 'Department' ? 'Category' : node . type ; const data = { ... node , slug : node . slug . replace ( /^\//g , '' ) . split ( '/' ) . map ( gatsbyPath ) . join ( '/' ) , id , parent : node . parent && createNodeId ( node . parent , parentType , gatsbyApi ) , children : node . children ?. map ( ( child ) => createNodeId ( child , childType , gatsbyApi ) ) , } ; gatsbyApi . actions . createNode ( { ... data , internal : { type : typeName , content : JSON . stringify ( data ) , contentDigest : gatsbyApi . createContentDigest ( data ) , } , } , { name : PLUGIN } ) ; return id ; } ; const brandToStoreCollection = ( node ) : StoreCollection => ( { id : `${ node . id }` , remoteId : `${ node . id }` , seo : { title : node . title ?? '' , description : node . metaTagDescription ?? '' , } , type : 'Brand' , slug : node . name , meta : { selectedFacets : [ { key : 'b' , value : node . name } ] , } , } ) ; const categoryToStoreCollection = ( node , parent ) : StoreCollection => { const slug = new URL ( node . url ) . pathname . slice ( 1 ) ; return { id : `${ node . id }` , remoteId : `${ node . id }` , parent , children : node . children . map ( ( child ) => `${ child . id }` ) , seo : { title : node . Title ?? '' , description : node . MetaTagDescription ?? '' , } , type : parent === undefined ? 'Department' : 'Category' , slug , meta : { selectedFacets : slug . split ( '/' ) . map ( ( segment ) => ( { key : 'c' , value : segment , } ) ) , } , } ; } ; export const fetchAllNodes = async ( { gatsbyApi , options , } ) : Promise < StoreCollection [ ] > => { const activity = gatsbyApi . reporter . activityTimer ( `[gatsby-source-vtex]: fetching Categories/Brands` ) ; activity . start ( ) ; const [ tree , brands ] = await Promise . all ( [ fetchVTEX < Category [ ] > ( api . catalog . category . tree ( 4 ) , options ) , fetchVTEX < Brand [ ] > ( api . catalog . brand . list ( { page : 0 , pageSize : 1000 } ) , options ) , ] ) ; const collectionCategories = [ ] ; const dfs = ( node , collections , parent ) => { const collection = categoryToStoreCollection ( node , parent ) ; collections . push ( collection ) ; for ( const child of node . children ) { dfs ( child , collections , `${ node . id }` ) ; } } ; for ( const node of tree ) { dfs ( node , collectionCategories , undefined ) ; } const collectionBrands = brands . filter ( ( x ) => x . isActive ) . map ( brandToStoreCollection ) ; activity . end ( ) ; return [ ... collectionCategories , ... collectionBrands ] ; } ; export const sourceAllNodes = async ( config ) => { const { gatsbyApi } = config ; const nodes = await fetchAllNodes ( config ) ; for ( const node of nodes ) { createNode ( gatsbyApi , node ) ; } } ;