Summary
Convert tl-api from JavaScript to TypeScript for JSR publishing. Need to determine the best crypto approach through benchmarking first.
Phase 1: Benchmark Crypto Options
Before implementation, test what Deno actually supports to make an informed decision.
Benchmark Script
Create scripts/crypto-benchmark.ts to test functionality and performance:
Tests to run:
-
Functionality tests (does it work at all?)
node:crypto RSA with RSA_NO_PADDING - critical, may not be supported
node:crypto MD5 hashing
node:crypto AES-128-CBC encrypt/decrypt
-
Performance benchmarks (ops/sec, 1000 iterations)
- AES-128-CBC encrypt 1KB payload
- MD5 hash 1KB payload
- RSA encrypt 128-byte chunk (modulus size)
-
Compare all viable options:
node:crypto (baseline)
@noble/ciphers + @noble/hashes + BigInt RSA
- Web Crypto + pure JS MD5 + BigInt RSA
Run with: deno run --allow-all scripts/crypto-benchmark.ts
Output format:
=== Functionality ===
node:crypto RSA_NO_PADDING: PASS/FAIL
node:crypto MD5: PASS/FAIL
...
=== Performance (ops/sec) ===
AES encrypt: node:crypto=X @noble=Y webCrypto=Z
MD5 hash: node:crypto=X @noble=Y pureJS=Z
RSA encrypt: node:crypto=X bigint=Y
Expected Outcomes
| Feature |
node:crypto on Deno |
Web Crypto |
@noble/* |
| AES-128-CBC |
Yes |
Yes (async) |
Yes |
| MD5 |
Likely yes |
No |
Yes |
| RSA_NO_PADDING |
Unknown |
No |
No (need BigInt impl) |
Candidate Solutions (pick ONE)
| Option |
AES |
MD5 |
RSA (no padding) |
Dependencies |
| A: node:crypto |
createCipheriv |
createHash('md5') |
publicEncrypt + RSA_NO_PADDING |
None |
| B: @noble |
@noble/ciphers |
@noble/hashes |
BigInt modPow |
2 JSR deps |
| C: Manual |
Web Crypto |
Pure JS MD5 |
BigInt modPow |
None |
Note: @std/crypto is NOT viable - it uses Web Crypto which lacks MD5 and RSA_NO_PADDING.
Decision After Benchmarking
Pick one solution based on:
- Functionality - Does it work for all required operations?
- Performance - Benchmark results (ops/sec for AES, MD5, RSA)
- Portability - Where does it run? (Node, Deno, browsers, edge)
Phase 2: Implementation (after benchmarking)
Step 1: Project Configuration
deno.json - Deno config with JSR imports
jsr.json - JSR registry config (@hertzg/tl-api)
- Keep
package.json for Node.js compatibility via JSR
Step 2: Buffer → Uint8Array Migration
Use web standard methods (no custom utils):
Uint8Array.prototype.toBase64() / Uint8Array.fromBase64() - ES2024
Uint8Array.prototype.toHex() / Uint8Array.fromHex() - ES2024
TextEncoder.encode() / TextDecoder.decode() - UTF-8
Uint8Array.of(), spread, set() - Concatenation
Note: These ES2024 methods require Deno 1.40+ / Node 22+. If older support needed, fall back to btoa/atob.
Step 3: Crypto Implementation (ONE of these, based on benchmark)
Option A: node:crypto
- Keep existing code structure, convert
.js → .ts
- Add types for crypto operations
- Requires Deno's node:crypto to support RSA_NO_PADDING
Option B: @noble libraries
@noble/ciphers for AES-CBC
@noble/hashes for MD5
- Implement
modPow(base, exp, mod) using BigInt for RSA
- Adds 2 dependencies but well-audited, works everywhere
Option C: Manual (pure JS)
- Web Crypto API for AES-CBC (async)
- Pure JS MD5 implementation (~150 lines)
- BigInt
modPow for RSA (~50 lines)
- Zero dependencies, maximum portability
Step 4: Convert All Files to TypeScript
| File |
Changes |
src/index.ts |
Re-exports with types |
src/authenticate.ts |
Add types |
src/execute.ts |
Add types |
src/payload.ts |
Types, ACT as const |
src/client/*.ts |
Buffer→Uint8Array, add types |
src/client/cipher/*.ts |
Crypto changes (per benchmark) |
Step 5: Testing
- Convert existing tests to TypeScript
- Run on Deno only:
deno test
Step 6: JSR Publishing
- CI workflow for
deno publish
- Version management via
jsr.json
Files to Modify/Create
| Action |
Path |
| Create |
scripts/crypto-benchmark.ts |
| Create |
deno.json |
| Create |
jsr.json |
| Convert |
All src/**/*.js → src/**/*.ts |
| Modify |
.github/workflows/test.yml (Deno only) |
| Create |
.github/workflows/publish.yml (JSR) |
Execution Order
- Benchmark first - Run crypto tests in Deno to determine what works
- Choose crypto strategy - Based on benchmark results
- Config setup - deno.json, jsr.json
- Convert to TypeScript - All source files
- Migrate Buffer → Uint8Array - Using web standards
- Update tests - Convert to TypeScript, run with
deno test
- CI/CD setup - Deno test + JSR publishing workflow
Summary
Convert
tl-apifrom JavaScript to TypeScript for JSR publishing. Need to determine the best crypto approach through benchmarking first.Phase 1: Benchmark Crypto Options
Before implementation, test what Deno actually supports to make an informed decision.
Benchmark Script
Create
scripts/crypto-benchmark.tsto test functionality and performance:Tests to run:
Functionality tests (does it work at all?)
node:cryptoRSA withRSA_NO_PADDING- critical, may not be supportednode:cryptoMD5 hashingnode:cryptoAES-128-CBC encrypt/decryptPerformance benchmarks (ops/sec, 1000 iterations)
Compare all viable options:
node:crypto(baseline)@noble/ciphers+@noble/hashes+ BigInt RSARun with:
deno run --allow-all scripts/crypto-benchmark.tsOutput format:
Expected Outcomes
Candidate Solutions (pick ONE)
createCipherivcreateHash('md5')publicEncrypt+RSA_NO_PADDING@noble/ciphers@noble/hashesmodPowmodPowNote:
@std/cryptois NOT viable - it uses Web Crypto which lacks MD5 and RSA_NO_PADDING.Decision After Benchmarking
Pick one solution based on:
Phase 2: Implementation (after benchmarking)
Step 1: Project Configuration
deno.json- Deno config with JSR importsjsr.json- JSR registry config (@hertzg/tl-api)package.jsonfor Node.js compatibility via JSRStep 2: Buffer → Uint8Array Migration
Use web standard methods (no custom utils):
Uint8Array.prototype.toBase64()/Uint8Array.fromBase64()- ES2024Uint8Array.prototype.toHex()/Uint8Array.fromHex()- ES2024TextEncoder.encode()/TextDecoder.decode()- UTF-8Uint8Array.of(), spread,set()- ConcatenationNote: These ES2024 methods require Deno 1.40+ / Node 22+. If older support needed, fall back to btoa/atob.
Step 3: Crypto Implementation (ONE of these, based on benchmark)
Option A: node:crypto
.js→.tsOption B: @noble libraries
@noble/ciphersfor AES-CBC@noble/hashesfor MD5modPow(base, exp, mod)using BigInt for RSAOption C: Manual (pure JS)
modPowfor RSA (~50 lines)Step 4: Convert All Files to TypeScript
src/index.tssrc/authenticate.tssrc/execute.tssrc/payload.tsACTas constsrc/client/*.tssrc/client/cipher/*.tsStep 5: Testing
deno testStep 6: JSR Publishing
deno publishjsr.jsonFiles to Modify/Create
scripts/crypto-benchmark.tsdeno.jsonjsr.jsonsrc/**/*.js→src/**/*.ts.github/workflows/test.yml(Deno only).github/workflows/publish.yml(JSR)Execution Order
deno test