-
Notifications
You must be signed in to change notification settings - Fork 3
Publish to Deno JSR #10
Description
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:cryptoRSA withRSA_NO_PADDING- critical, may not be supportednode:cryptoMD5 hashingnode:cryptoAES-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 importsjsr.json- JSR registry config (@hertzg/tl-api)- Keep
package.jsonfor Node.js compatibility via JSR
Step 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()- 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/ciphersfor AES-CBC@noble/hashesfor 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
modPowfor 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