2020-06-18 16:50:53 +00:00
require ( 'dotenv' ) . config ( )
const algoliasearch = require ( 'algoliasearch' )
const glob = require ( 'glob' )
const path = require ( 'path' )
const matter = require ( 'gray-matter' )
// In addition to the content of the page,
// define additional front matter attributes that will be search-indexable
const SEARCH _DIMENSIONS = [ 'page_title' , 'description' ]
main ( )
async function main ( ) {
const pagesFolder = path . join ( _ _dirname , '../pages' )
// Grab all search-indexable content and format for Algolia
const searchObjects = glob
. sync ( path . join ( pagesFolder , '**/*.mdx' ) )
. map ( ( fullPath ) => {
const { content , data } = matter . read ( fullPath )
// Get path relative to `pages`
const _ _resourcePath = fullPath . replace ( ` ${ pagesFolder } / ` , '' )
// Use clean URL for Algolia id
const objectID = _ _resourcePath . replace ( '.mdx' , '' )
const searchableDimensions = Object . keys ( data )
. filter ( ( key ) => SEARCH _DIMENSIONS . includes ( key ) )
. map ( ( dimension ) => ( {
[ dimension ] : data [ dimension ] ,
} ) )
return {
... searchableDimensions ,
content ,
_ _resourcePath ,
objectID ,
}
} )
try {
await indexSearchContent ( searchObjects )
} catch ( e ) {
console . error ( e )
process . exit ( 1 )
}
}
async function indexSearchContent ( objects ) {
const {
2020-06-18 19:22:30 +00:00
NEXT _PUBLIC _ALGOLIA _APP _ID : appId ,
NEXT _PUBLIC _ALGOLIA _INDEX : index ,
2020-06-18 16:50:53 +00:00
ALGOLIA _API _KEY : apiKey ,
} = process . env
if ( ! apiKey || ! appId || ! index ) {
throw new Error (
` [*** Algolia Search Indexing Error ***] Received: ALGOLIA_API_KEY= ${ apiKey } ALGOLIA_APP_ID= ${ appId } ALGOLIA_INDEX= ${ index } \n Please ensure all Algolia Search-related environment vars are set in CI settings. `
)
}
console . log ( ` updating ${ objects . length } indices... ` )
try {
const searchClient = algoliasearch ( appId , apiKey )
const searchIndex = searchClient . initIndex ( index )
await searchIndex . partialUpdateObjects ( objects , {
createIfNotExists : true ,
} )
// Remove indices for items that aren't included in the new batch
const newObjectIds = objects . map ( ( { objectID } ) => objectID )
let staleObjects = [ ]
await searchIndex . browseObjects ( {
query : '' ,
batch : ( batch ) => {
staleObjects = staleObjects . concat (
batch . filter ( ( { objectID } ) => ! newObjectIds . includes ( objectID ) )
)
} ,
} )
const staleIds = staleObjects . map ( ( { objectID } ) => objectID )
if ( staleIds . length > 0 ) {
console . log ( ` deleting ${ staleIds . length } stale indices: ` )
console . log ( staleIds )
await searchIndex . deleteObjects ( staleIds )
}
console . log ( 'done' )
process . exit ( 0 )
} catch ( error ) {
throw new Error ( error )
}
}