mirror of https://github.com/Chocobozzz/PeerTube
				
				
				
			
		
			
				
	
	
		
			59 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			59 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
| import { Transform, TransformCallback } from 'stream'
 | |
| 
 | |
| // Thanks: https://stackoverflow.com/a/45126242
 | |
| class StreamReplacer extends Transform {
 | |
|   private pendingChunk: Buffer
 | |
| 
 | |
|   constructor (private readonly replacer: (line: string) => string) {
 | |
|     super()
 | |
|   }
 | |
| 
 | |
|   _transform (chunk: Buffer, _encoding: BufferEncoding, done: TransformCallback) {
 | |
|     try {
 | |
|       this.pendingChunk = this.pendingChunk?.length
 | |
|         ? Buffer.concat([ this.pendingChunk, chunk ])
 | |
|         : chunk
 | |
| 
 | |
|       let index: number
 | |
| 
 | |
|       // As long as we keep finding newlines, keep making slices of the buffer and push them to the
 | |
|       // readable side of the transform stream
 | |
|       while ((index = this.pendingChunk.indexOf('\n')) !== -1) {
 | |
|         // The `end` parameter is non-inclusive, so increase it to include the newline we found
 | |
|         const line = this.pendingChunk.slice(0, ++index)
 | |
| 
 | |
|         // `start` is inclusive, but we are already one char ahead of the newline -> all good
 | |
|         this.pendingChunk = this.pendingChunk.slice(index)
 | |
| 
 | |
|         // We have a single line here! Prepend the string we want
 | |
|         this.push(this.doReplace(line))
 | |
|       }
 | |
| 
 | |
|       return done()
 | |
|     } catch (err) {
 | |
|       return done(err)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   _flush (done: TransformCallback) {
 | |
|     // If we have any remaining data in the cache, send it out
 | |
|     if (!this.pendingChunk?.length) return done()
 | |
| 
 | |
|     try {
 | |
|       return done(null, this.doReplace(this.pendingChunk))
 | |
|     } catch (err) {
 | |
|       return done(err)
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   private doReplace (buffer: Buffer) {
 | |
|     const line = this.replacer(buffer.toString('utf8'))
 | |
| 
 | |
|     return Buffer.from(line, 'utf8')
 | |
|   }
 | |
| }
 | |
| 
 | |
| export {
 | |
|   StreamReplacer
 | |
| }
 |