import { Starter , BatchPayload } from '@prisma/photon' ; import { Task } from 'algoliasearch' ; import * as e from 'fp-ts/lib/Either' ; import hash from 'object-hash' ; import { Octokit , Context } from 'probot' ; import { StarterConfiguration , getConfig } from '../../configuration' ; import { EmmaStarter } from '../../models' ; import { Sources } from '../../sources' ; import { withDefault } from '../../utils' ; param sources export const syncRepository = ( sources ) => async ( ctx ) => { const owner = ctx . payload . repository . owner . login ; const repo = ctx . payload . repository . name ; const ref = ctx . payload . ref ; const masterRef = `refs/heads/${ ctx . payload . repository . default_branch }` ; if ( masterRef !== ref ) { ctx . log . info ( `Ignoring ref: ${ ref }. Default ref: ${ masterRef }` ) ; return ; } const config = await getConfig ( sources ) ( ctx . github , owner , repo ) ; if ( config === null ) { ctx . log . debug ( `Couldn't load ${ owner }/${ repo } configuration.` ) ; return ; } ctx . log . debug ( { config , owner , repo } , 'received configuration' ) ; try { const starters = await Promise . all ( config . starters . map < Promise < EmmaStarter > > ( sc => loadStarter ( ctx . github , { repo , owner , ref } , sc ) ) ) ; const saveRes = await Promise . all ( starters . map ( starter => saveStarter ( sources , starter ) ) ) ; const cleanRes = await cleanStarters ( sources , { repo , owner } , starters ) ; ctx . log . debug ( { repo , owner , saveRes , cleanRes } , `Synced Repository` ) ; } catch ( err ) { ctx . log . warn ( err ) ; } } ; param github param param param config async function loadStarter ( github , { repo , owner , ref } , config ) { const res = await github . repos . getContents ( { owner : owner , repo : repo , ref : ref , path : `${ config . path }/package.json` , } ) ; switch ( res . status ) { case 200 : { if ( Array . isArray ( res . data ) || ! res . data . content ) { throw new Error ( `Expected a file at ${ config . path } received ${ typeof res . data }` ) ; } const buffer = Buffer . from ( res . data . content , 'base64' ) . toString ( ) ; const pkg = JSON . parse ( buffer ) ; if ( ! pkg . name || ! pkg . dependencies ) { throw new Error ( `Missing a starter name or dependencies.` ) ; } return { repo : repo , owner : owner , signature : hash ( { owner , repo , name : config . name , ref : ref } ) , path : config . path , ref : ref , name : config . name , description : withDefault ( pkg . description , config . description ) , dependencies : Object . keys ( pkg . dependencies ) , } ; } default : { throw new Error ( `[${ res . status }] Couldn't load package.json at ${ config . path }.` ) ; } } } param photon param starter async function saveStarter ( { prisma , algolia } , starter ) { const prismaRes = await prisma . photon . starters . upsert ( { where : { signature : starter . signature } , create : { signature : starter . signature , repo : starter . repo , owner : starter . owner , path : starter . path , ref : starter . ref , name : starter . name , description : starter . description , dependencies : { set : starter . dependencies } , } , update : { repo : starter . repo , owner : starter . owner , path : starter . path , ref : starter . ref , name : starter . name , description : starter . description , dependencies : { set : starter . dependencies } , } , } ) ; const algoliaRes = await algolia . indices . starters . addObject ( { objectID : starter . signature , owner : starter . owner , repo : starter . repo , name : starter . name , description : starter . description , downloads : 0 , dependencies : starter . dependencies , } ) ; return [ prismaRes , algoliaRes ] ; } param starters async function cleanStarters ( { prisma , algolia } , { repo , owner } , starters ) { const startersNames = starters . map ( starter => starter . name ) ; const dbStarters = await prisma . photon . starters . findMany ( { where : { repo : repo , owner : owner , name : { notIn : startersNames } , } , } ) ; const algoliaRes = await algolia . indices . starters . deleteObjects ( dbStarters . map ( starter => starter . signature ) ) ; const prismaRes = await prisma . photon . starters . deleteMany ( { where : { repo : repo , owner : owner , name : { notIn : startersNames } , } , } ) ; return [ dbStarters , algoliaRes , prismaRes ] ; }