Skip to content

Commit

Permalink
feat(cli): add qifi command and parse args
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleSound committed Oct 11, 2024
1 parent f70f0b1 commit 6a3a8d3
Show file tree
Hide file tree
Showing 11 changed files with 269 additions and 114 deletions.
1 change: 1 addition & 0 deletions cspell.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ words:
- luby
- Nuxt
- pako
- Positionals
- qifi
- QRCODE
- Soliton
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"nuxt": "^3.13.2",
"ohash": "^1.1.4",
"pinia": "^2.2.4",
"tsx": "^4.19.1",
"typescript": "^5.6.2",
"unbuild": "^2.0.0",
"vitest": "^2.1.1",
Expand Down
33 changes: 5 additions & 28 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# @qifi/generate
# QiFi CLI

<!-- Some beautiful tags -->
<p align="left">
Expand All @@ -9,11 +9,11 @@
<img alt="docs" src="https://img.shields.io/badge/-docs%20%26%20demos-1e8a7a">
</a>
<a href="https://github.com/sponsors/LittleSound">
<img alt="docs" src="https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86">
<img alt="sponsors" src="https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86">
</a>
</p>

Stream Generated QR Codes for data transmission
Stream Generated QR Codes for file transmission in your terminal

## Sponsors

Expand All @@ -31,29 +31,6 @@ Stream Generated QR Codes for data transmission

## Usage

```javascript
import {
createGeneraterANSI,
createGeneraterUnicode,
createGeneraterUnicodeCompact,
createGeneraterSVG,
createGeneraterQRCodeArray,
} from '@qifi/generate'

const generaterSvg = createGeneraterSVG(new Uint8Array(file.buffer))

const generaterANSI = createGeneraterANSI(new Uint8Array(file.buffer), {
// Size of each data slice
sliceSize: 250,
// Error correction level
ecc: 'L',
// Border width
border: 2,
})

// display QR Code in terminal
for (const blockQRCode of generaterANSI()) {
console.log(blockQRCode)
}

```bash
npx qifi <file> [options]
```
5 changes: 5 additions & 0 deletions packages/cli/bin/qifi.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env node
'use strict'
import { main } from '../dist/cli.mjs'

main()
1 change: 1 addition & 0 deletions packages/cli/build.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
entries: [
'src/index.ts',
'src/cli.ts',
],
declaration: true,
rollup: {
Expand Down
9 changes: 6 additions & 3 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"bin": {
"qifi": "./bin/qifi.mjs"
},
"files": [
"dist"
],
"scripts": {
"dev": "tsx ./src",
"dev": "tsx ./src/cli",
"build": "unbuild",
"stub": "unbuild --stub"
},
"dependencies": {
"@qifi/generate": "workspace:*",
"mime": "^4.0.4",
"tsx": "^4.19.1"
"cac": "^6.7.14",
"mime": "^4.0.4"
}
}
85 changes: 85 additions & 0 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import readline from 'node:readline'
import { appendFileHeaderMetaToBuffer, createGeneraterANSI, createGeneraterUnicode, createGeneraterUnicodeCompact } from '@qifi/generate'

Check failure on line 5 in packages/cli/src/cli.ts

View workflow job for this annotation

GitHub Actions / typecheck

Cannot find module '@qifi/generate' or its corresponding type declarations.
import mime from 'mime'
import {
black,
boostEcc,
border,
compact,
contentType,
ecc,
fps,
invert,
maskPattern,
maxVersion,
minVersion,
positional,
prefix,
sliceSize,
unicode,
white,
} from './parse-args'
import { handleArgsError } from './shared'

function chooseGenerater() {
if (compact) {
return createGeneraterUnicodeCompact
}
if (unicode) {
return createGeneraterUnicode
}
return createGeneraterANSI
}

// Function to read file and generate QR codes
export async function main() {
const fullPath = path.resolve(positional)

console.log('fullPath:', fullPath)
await new Promise(resolve => setTimeout(resolve, 1000))
if (!fs.existsSync(fullPath)) {
handleArgsError(new TypeError(`File not found: ${fullPath}`))
}

const fileBuffer = fs.readFileSync(fullPath)
const data = new Uint8Array(fileBuffer)
const meta = {
filename: path.basename(fullPath),
contentType: contentType || mime.getType(fullPath) || 'application/octet-stream',
}

const merged = appendFileHeaderMetaToBuffer(data, meta)

const generator = chooseGenerater()(merged, {
sliceSize,
urlPrefix: prefix,
...{
whiteChar: white,
blackChar: black,
} as any,
invert,
ecc,
maskPattern,
boostEcc,
minVersion,
maxVersion,
border,
})

// Clear console function
const clearConsole = () => {
readline.cursorTo(process.stdout, 0, 0)
readline.clearScreenDown(process.stdout)
}

// Display QR codes
for (const blockQRCode of generator.fountain()) {
clearConsole()
process.stdout.write(`${blockQRCode}\n`)
process.stdout.write(`${meta.filename} (${meta.contentType}) | size: ${data.length} bytes`)
await new Promise(resolve => setTimeout(resolve, 1000 / fps))
}
}
69 changes: 2 additions & 67 deletions packages/cli/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,67 +1,2 @@
#!/usr/bin/env tsx

import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import readline from 'node:readline'
import { appendFileHeaderMetaToBuffer, createGeneraterANSI } from '@qifi/generate'
import mime from 'mime'

// Function to read file and generate QR codes
async function generateQRCodes(filePath: string, sliceSize: number = 80, fps: number = 20) {
const fullPath = path.resolve(filePath)

console.log('fullPath:', fullPath)
await new Promise(resolve => setTimeout(resolve, 1000))
if (!fs.existsSync(fullPath)) {
console.error(`File not found: ${fullPath}`)
process.exit(1)
}

const fileBuffer = fs.readFileSync(fullPath)
const data = new Uint8Array(fileBuffer)
const meta = {
filename: path.basename(fullPath),
contentType: mime.getType(fullPath) || 'application/octet-stream',
}

const merged = appendFileHeaderMetaToBuffer(data, meta)

const generator = createGeneraterANSI(merged, {
urlPrefix: 'https://qrss.netlify.app/#',
sliceSize,
border: 2,
})

// Clear console function
const clearConsole = () => {
readline.cursorTo(process.stdout, 0, 0)
readline.clearScreenDown(process.stdout)
}

// Display QR codes
for (const blockQRCode of generator.fountain()) {
clearConsole()
process.stdout.write(`${blockQRCode}\n`)
process.stdout.write(`${meta.filename} (${meta.contentType}) | size: ${data.length} bytes`)
await new Promise(resolve => setTimeout(resolve, 1000 / fps))
}
}

// Parse command line arguments
const args = process.argv.slice(2)
if (args.length < 1) {
console.error('Usage: qr-file-transfer <file-path> [slice-size]')
process.exit(1)
}

const [filePath, sliceSizeStr, fpsStr] = args
const sliceSize = sliceSizeStr ? Number.parseInt(sliceSizeStr, 10) : undefined
const fps = fpsStr ? Number.parseInt(fpsStr, 10) : undefined

if (!filePath) {
console.error('File path is required')
process.exit(1)
}

generateQRCodes(filePath, sliceSize, fps)
console.warn('qifi is a cli package, it should not be imported in other packages')
export default function () {}
Loading

0 comments on commit 6a3a8d3

Please sign in to comment.