import { s3 , listNestedPrefixes , upload , Bucket } from '../utils/s3' ; import { IssuePublicationIdentifier , IssueIdentifier } from '../../common' ; import { getPublishedId , getLocalId } from '../utils/path-builder' ; import { oc } from 'ts-optchain' ; export type IssuePublicationWithStatus = IssuePublicationIdentifier & { status : Status ; updated : Date ; } ; export const publishedStatuses = [ 'bundled' , 'proofed' , 'copied' , 'published' , 'editionsListUpdated' , 'notified' , ] as const ; export const statuses = [ ... publishedStatuses , 'started' , 'assembled' , 'errored' , ] as const ; export type Status = typeof statuses [ number ] ; export const isPublished = ( status ) : boolean => { return ( publishedStatuses as readonly Status [ ] ) . includes ( status ) ; } ; export const putStatus = ( issuePublication , status , bucket ) => { console . log ( `Changing state of ${ JSON . stringify ( issuePublication ) } to ${ status }` ) ; const publishedId = getPublishedId ( issuePublication ) ; const path = `${ publishedId }/status` ; return upload ( path , { status } , bucket , 'application/json' , undefined ) ; } ; const getStatus = async ( issuePublication , bucket ) : Promise < IssuePublicationWithStatus > => { console . log ( `getStatus for ${ JSON . stringify ( issuePublication ) }` ) ; const publishedId = getPublishedId ( issuePublication ) ; const response = await s3 . getObject ( { Bucket : bucket . name , Key : `${ publishedId }/status` } ) . promise ( ) . catch ( ( ) => { return undefined ; } ) ; const statusResponse = response && response . Body && response . Body . toString ( 'utf-8' ) ; console . log ( `Raw response for ${ JSON . stringify ( issuePublication ) } is ${ statusResponse }` ) ; if ( typeof statusResponse !== 'string' ) { console . log ( `Raw response for ${ JSON . stringify ( issuePublication ) } was not a string :( but was actually a ${ typeof statusResponse }` ) ; return { ... issuePublication , status : 'errored' , updated : new Date ( 0 ) } ; } const decodedStatus = JSON . parse ( statusResponse ) ; const status = statuses . find ( _ => _ === decodedStatus . status ) || 'errored' ; const updated = oc ( response ) . LastModified ( ) || new Date ( 0 ) ; console . log ( `Status for ${ JSON . stringify ( issuePublication ) } was ${ status } at ${ updated }` ) ; return { ... issuePublication , status , updated } ; } ; const getVersions = async ( issue , bucket ) : Promise < IssuePublicationIdentifier [ ] > => { console . log ( `getVersions for ${ JSON . stringify ( issue ) }` ) ; const root = getLocalId ( issue ) ; const versions = await listNestedPrefixes ( bucket , root ) ; return versions . map ( version => ( { ... issue , version , } ) ) ; } ; export const getStatuses = async ( issuePublication , bucket ) : Promise < IssuePublicationWithStatus [ ] > => { const allVersions = await getVersions ( issuePublication , bucket ) ; return Promise . all ( allVersions . map ( version => getStatus ( version , bucket ) ) ) ; } ;