import path from "path" ; import mkdirp from "mkdirp" ; import { Storage , GetFilesOptions } from "@google-cloud/storage" ; import { WorkingDirectoryInfo , PublisherPlugin , PluginCreateOptions } from "reg-suit-interface" ; import { AbstractPublisher , RemoteFileItem , FileItem , ObjectListResult } from "reg-suit-util" ; export interface PluginConfig { bucketName : string ; pattern ? : string ; customUri ? : string ; pathPrefix ? : string ; } export class GcsPublisherPlugin extends AbstractPublisher implements PublisherPlugin < PluginConfig > { name = "reg-publish-gcs-plugin" ; private _options ! : PluginCreateOptions < any > ; private _pluginConfig ! : PluginConfig ; private _gcsClient ! : Storage ; constructor ( ) { super ( ) ; } init ( config ) { this . noEmit = config . noEmit ; this . logger = config . logger ; this . _options = config ; this . _pluginConfig = { ... config . options , } ; this . _gcsClient = new Storage ( ) ; } async publish ( key ) { const { indexFile } = await this . publishInternal ( key ) ; const reportUrl = indexFile && `${ this . getUriPrefix ( ) }/${ this . resolveInBucket ( key ) }/${ indexFile . path }` ; return { reportUrl } ; } async fetch ( key ) { return this . fetchInternal ( key ) ; } protected getUriPrefix ( ) { const { customUri } = this . _pluginConfig ; if ( customUri ) { return customUri . endsWith ( "/" ) ? customUri . slice ( 0 , customUri . length - 1 ) : customUri ; } else { return `https://storage.googleapis.com/${ this . getBucketName ( ) }` ; } } protected getBucketRootDir ( ) { return this . _pluginConfig . pathPrefix ; } protected getBucketName ( ) { return this . _pluginConfig . bucketName ; } protected getLocalGlobPattern ( ) { return this . _pluginConfig . pattern ; } protected getWorkingDirs ( ) { return this . _options . workingDirs ; } protected async uploadItem ( key , item ) { await this . _gcsClient . bucket ( this . _pluginConfig . bucketName ) . upload ( item . absPath , { destination : `${ key }/${ item . path }` , gzip : true , } ) ; this . logger . verbose ( `Uploaded from ${ item . absPath } to ${ key }/${ item . path }` ) ; return item ; } protected async downloadItem ( { remotePath } , item ) { mkdirp . sync ( path . dirname ( item . absPath ) ) ; await this . _gcsClient . bucket ( this . _pluginConfig . bucketName ) . file ( remotePath ) . download ( { destination : item . absPath , validation : false , } ) ; this . logger . verbose ( `Downloaded from ${ remotePath } to ${ item . absPath }` ) ; return item ; } protected async listItems ( lastKey , prefix ) { return new Promise < ObjectListResult > ( ( resolve , reject ) => { this . _gcsClient . bucket ( this . _pluginConfig . bucketName ) . getFiles ( { prefix , maxResults : 1000 , pageToken : lastKey , } , ( err , files , nextQuery ) => { if ( err ) { reject ( err ) ; } const nextMarker = nextQuery && ( nextQuery as GetFilesOptions ) . pageToken ; resolve ( { isTruncated : nextMarker != null , contents : ! files ? [ ] : files . map ( f => ( { key : f . name } ) ) , nextMarker : nextMarker , } as ObjectListResult ) ; } ) ; } ) ; } }