Skip to content

Commit

Permalink
chore: working on chapter 6
Browse files Browse the repository at this point in the history
  • Loading branch information
lmammino committed Nov 25, 2024
1 parent 71bd828 commit cef07de
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 0 deletions.
2 changes: 2 additions & 0 deletions 06-coding-with-streams/22-combined-stream/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.gz.enc
package-uppercase.json
11 changes: 11 additions & 0 deletions 06-coding-with-streams/22-combined-stream/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 22-combined-stream

This example shows how to create a combined stream.

## Run

To run the example:

```bash
node archive.js <a_password> <path/to/a/file>
```
21 changes: 21 additions & 0 deletions 06-coding-with-streams/22-combined-stream/archive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { randomBytes } from 'node:crypto'
import { createReadStream, createWriteStream } from 'node:fs'
import { pipeline } from 'node:stream'
import { createCompressAndEncrypt } from './combined-streams.js'

const [, , password, source] = process.argv
const iv = randomBytes(16)
const destination = `${source}.gz.enc`

pipeline(
createReadStream(source),
createCompressAndEncrypt(password, iv),
createWriteStream(destination),
err => {
if (err) {
console.error(err)
process.exit(1)
}
console.log(`${destination} created with iv: ${iv.toString('hex')}`)
}
)
23 changes: 23 additions & 0 deletions 06-coding-with-streams/22-combined-stream/combined-streams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createCipheriv, createDecipheriv, scryptSync } from 'node:crypto'
import { compose } from 'node:stream'
import { createGunzip, createGzip } from 'node:zlib'

function createKey(password) {
return scryptSync(password, 'salt', 24)
}

export function createCompressAndEncrypt(password, iv) {
const key = createKey(password)
const combinedStream = compose(
createGzip(),
createCipheriv('aes192', key, iv)
)
combinedStream.iv = iv

return combinedStream
}

export function createDecryptAndDecompress(password, iv) {
const key = createKey(password)
return compose(createDecipheriv('aes192', key, iv), createGunzip())
}
97 changes: 97 additions & 0 deletions 06-coding-with-streams/22-combined-stream/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions 06-coding-with-streams/22-combined-stream/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "22-combined-stream",
"version": "1.0.0",
"description": "This example shows how to create a combined stream",
"type": "module",
"scripts": {},
"engines": {
"node": ">=22"
},
"engineStrict": true,
"keywords": [],
"author": "Luciano Mammino and Mario Casciaro",
"license": "MIT",
"dependencies": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import assert from 'node:assert/strict'
import { createReadStream, createWriteStream } from 'node:fs'
import { Transform, pipeline } from 'node:stream'

const streamA = createReadStream('package.json')
const streamB = new Transform({
transform(chunk, _enc, done) {
this.push(chunk.toString().toUpperCase())
done()
},
})
const streamC = createWriteStream('package-uppercase.json')

const pipelineReturn = pipeline(streamA, streamB, streamC, () => {
// handle errors here
})
// biome-ignore lint/suspicious/noMisplacedAssertion: Not an actual unit test
assert.equal(streamC, pipelineReturn) // valid

const pipeReturn = streamA.pipe(streamB).pipe(streamC)

// biome-ignore lint/suspicious/noMisplacedAssertion: Not an actual unit test
assert.equal(streamC, pipeReturn) // valid
22 changes: 22 additions & 0 deletions 06-coding-with-streams/22-combined-stream/unarchive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createReadStream, createWriteStream } from 'node:fs'
import { pipeline } from 'node:stream'
import { createDecryptAndDecompress } from './combined-streams.js'

// usage: node unarchive.js <password> <ivHex> <sourceFile> <destFile>
// example:
// node unarchive.js alovelypassword 158bc6bb3648afc1415371ae0c240715 package.json.gz.enc decoded-package.json
const [, , password, ivHex, source, destination] = process.argv
const iv = Buffer.from(ivHex, 'hex')

pipeline(
createReadStream(source),
createDecryptAndDecompress(password, iv),
createWriteStream(destination),
err => {
if (err) {
console.error(err)
process.exit(1)
}
console.log(`${destination} created`)
}
)
2 changes: 2 additions & 0 deletions 06-coding-with-streams/23-forking-streams/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.md5
*.sha1
11 changes: 11 additions & 0 deletions 06-coding-with-streams/23-forking-streams/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 23-forking-streams

This example shows how to fork a stream.

## Run

To run the example:

```bash
node generate-hashes.js <path/to/a/file>
```
12 changes: 12 additions & 0 deletions 06-coding-with-streams/23-forking-streams/generate-hashes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createHash } from 'node:crypto'
import { createReadStream, createWriteStream } from 'node:fs'

const filename = process.argv[2]
const sha1Stream = createHash('sha1').setEncoding('hex')
const md5Stream = createHash('md5').setEncoding('hex')

const inputStream = createReadStream(filename)

inputStream.pipe(sha1Stream).pipe(createWriteStream(`${filename}.sha1`))

inputStream.pipe(md5Stream).pipe(createWriteStream(`${filename}.md5`))
15 changes: 15 additions & 0 deletions 06-coding-with-streams/23-forking-streams/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "23-forking-streams",
"version": "1.0.0",
"description": "This example shows how to fork a stream.",
"type": "module",
"scripts": {},
"engines": {
"node": ">=22"
},
"engineStrict": true,
"keywords": [],
"author": "Luciano Mammino and Mario Casciaro",
"license": "MIT",
"dependencies": {}
}
11 changes: 11 additions & 0 deletions 06-coding-with-streams/24-merging-streams/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# 24-merging-streams

This example shows how to merge streams.

## Run

To run the example:

```bash
node merge-lines.js <destination> <source1> <source2> <source3> ...
```
25 changes: 25 additions & 0 deletions 06-coding-with-streams/24-merging-streams/merge-lines.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { createReadStream, createWriteStream } from 'node:fs'
import { createInterface } from 'node:readline'
import { Readable, Transform } from 'node:stream'

const [, , dest, ...sources] = process.argv
const destStream = createWriteStream(dest)

let endCount = 0
for (const source of sources) {
const sourceStream = createReadStream(source, { highWaterMark: 16 })
const linesStream = Readable.from(createInterface({ input: sourceStream }))
const addLineEnd = new Transform({
transform(chunk, _encoding, cb) {
cb(null, `${chunk}\n`)
},
})

sourceStream.on('end', () => {
if (++endCount === sources.length) {
destStream.end()
console.log(`${dest} created`)
}
})
linesStream.pipe(addLineEnd).pipe(destStream, { end: false })
}
15 changes: 15 additions & 0 deletions 06-coding-with-streams/24-merging-streams/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "24-merging-streams",
"version": "1.0.0",
"description": "This example shows how to merge streams",
"type": "module",
"scripts": {},
"engines": {
"node": ">=22"
},
"engineStrict": true,
"keywords": [],
"author": "Luciano Mammino and Mario Casciaro",
"license": "MIT",
"dependencies": {}
}

0 comments on commit cef07de

Please sign in to comment.