import { NodeMaterialsManager , KeyringNode , } from '@aws-crypto/material-management-node' ; import { _decryptStream } from './decrypt_stream' ; import { DecryptParameters } from './types' ; import { finished } from 'readable-stream' ; import { Readable , Duplex } from 'stream' ; import { MessageHeader } from '@aws-crypto/serialize' ; export interface DecryptOutput { plaintext : Buffer ; messageHeader : MessageHeader ; } export interface DecryptOptions { encoding ? : BufferEncoding ; maxBodySize ? : number ; } export async function _decrypt ( decryptParameters , cmm , ciphertext , { encoding , maxBodySize } = { } ) { const stream = _decryptStream ( decryptParameters , cmm , { maxBodySize , } ) ; const plaintext = [ ] ; let messageHeader = false ; stream . once ( 'MessageHeader' , ( header ) => { messageHeader = header ; } ) . on ( 'data' , ( chunk ) => plaintext . push ( chunk ) ) ; if ( ciphertext instanceof Uint8Array ) { stream . end ( ciphertext ) ; } else if ( typeof ciphertext === 'string' ) { stream . end ( Buffer . from ( ciphertext , encoding ) ) ; } else if ( ciphertext . readable ) { ciphertext . pipe ( stream ) ; } else { throw new Error ( 'Unsupported ciphertext format' ) ; } await finishedAsync ( stream ) ; if ( ! messageHeader ) throw new Error ( 'Unknown format' ) ; return { plaintext : Buffer . concat ( plaintext ) , messageHeader , } ; } async function finishedAsync ( stream ) { return new Promise < void > ( ( resolve , reject ) => { finished ( stream , ( err ) => ( err ? reject ( err ) : resolve ( ) ) ) ; } ) ; }