cbyte 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/99367107.cbyte +1 -1
- package/README.md +11 -203
- package/cbyte-1.13.0.tgz +0 -0
- package/cbyte.js +93 -164
- package/package.json +8 -27
- package/style-0.0.3.tgz +0 -0
package/99367107.cbyte
CHANGED
package/README.md
CHANGED
|
@@ -1,208 +1,16 @@
|
|
|
1
|
-
# cbyte
|
|
1
|
+
# cbyte v1.13
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
---
|
|
3
|
+
cbyte is an offline, content-addressed, deduplicated file packer built on Helia.
|
|
6
4
|
|
|
7
5
|
## Features
|
|
6
|
+
- Streaming chunking (large-file safe)
|
|
7
|
+
- Deterministic manifests
|
|
8
|
+
- Persistent deduplicated blockstore
|
|
9
|
+
- No IPFS daemon, no networking
|
|
10
|
+
- Clean CLI exit
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* Deterministic `.cbyte` manifests
|
|
13
|
-
* Parallel unpacking with safe ordered writes
|
|
14
|
-
* ASCII progress bar during unpack
|
|
15
|
-
* CLI commands: `pack`, `unpack`, `verify`, `pin`
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Requirements
|
|
20
|
-
|
|
21
|
-
* Node.js >= 20
|
|
22
|
-
* npm
|
|
23
|
-
* IPFS (Kubo) >= 0.21
|
|
24
|
-
* Linux environment (POSIX-compliant filesystem)
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Installation
|
|
29
|
-
|
|
30
|
-
### Using npm
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npm install -g cbyte
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
### Manual (from GitHub or tarball)
|
|
37
|
-
|
|
38
|
-
```bash
|
|
39
|
-
git clone https://github.com/yourusername/cbyte.git
|
|
40
|
-
cd cbyte
|
|
41
|
-
npm install
|
|
42
|
-
chmod +x cbyte.js
|
|
43
|
-
sudo ln -sf $(pwd)/cbyte.js /usr/local/bin/cbyte
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Ensure IPFS daemon is running:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
ipfs daemon &
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## CLI Usage
|
|
55
|
-
|
|
56
|
-
```text
|
|
57
|
-
cbyte <command> [options]
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### Commands
|
|
61
|
-
|
|
62
|
-
| Command | Description |
|
|
63
|
-
| ----------------- | ------------------------------------------- |
|
|
64
|
-
| pack <file> | Pack a file into a `.cbyte` manifest |
|
|
65
|
-
| unpack <manifest> | Reconstruct the original file from manifest |
|
|
66
|
-
| verify <manifest> | Verify availability & integrity of blocks |
|
|
67
|
-
| pin <manifest> | Pin all blocks referenced by manifest |
|
|
68
|
-
|
|
69
|
-
### Options
|
|
70
|
-
|
|
71
|
-
* `-o, --output <file>`: specify output file (manifest or restored file)
|
|
72
|
-
* `--chunk-size <bytes>`: size of chunks in bytes (default 4096)
|
|
73
|
-
* `--pin`: automatically pin blocks during pack
|
|
74
|
-
* `-h, --help`: show help for command
|
|
75
|
-
|
|
76
|
-
---
|
|
77
|
-
|
|
78
|
-
## Examples
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
# Pack a file
|
|
82
|
-
cbyte pack bigfile.bin -o bigfile.cbyte --chunk-size 4096 --pin
|
|
83
|
-
|
|
84
|
-
# Unpack with ASCII progress
|
|
85
|
-
cbyte unpack bigfile.cbyte -o bigfile_restored.bin
|
|
86
|
-
|
|
87
|
-
# Verify blocks
|
|
88
|
-
cbyte verify bigfile.cbyte
|
|
89
|
-
|
|
90
|
-
# Pin all blocks
|
|
91
|
-
cbyte pin bigfile.cbyte
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
ASCII progress bar example during unpack:
|
|
95
|
-
|
|
96
|
-
```
|
|
97
|
-
[====================== ] 62.5% (500/800)
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Manifest Format
|
|
103
|
-
|
|
104
|
-
```json
|
|
105
|
-
{
|
|
106
|
-
"format": "cbyte",
|
|
107
|
-
"version": 1,
|
|
108
|
-
"chunk_size": 4096,
|
|
109
|
-
"original_size": 5242880,
|
|
110
|
-
"chunks": [
|
|
111
|
-
{ "cid": "bafkreigh2akiscaildcg...", "length": 4096, "count": 2 }
|
|
112
|
-
]
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
* `cid`: IPFS content identifier
|
|
117
|
-
* `length`: bytes in the chunk
|
|
118
|
-
* `count`: repeated occurrences
|
|
119
|
-
* `chunk_size`: chunk size used during packing
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## Testing
|
|
124
|
-
|
|
125
|
-
```bash
|
|
126
|
-
# Small file
|
|
127
|
-
echo "test data" > testfile.txt
|
|
128
|
-
cbyte pack testfile.txt -o testfile.cbyte --chunk-size 32 --pin
|
|
129
|
-
cbyte unpack testfile.cbyte -o restored.txt
|
|
130
|
-
diff testfile.txt restored.txt
|
|
131
|
-
|
|
132
|
-
# Large file
|
|
133
|
-
dd if=/dev/urandom of=bigfile.bin bs=1M count=5
|
|
134
|
-
cbyte pack bigfile.bin -o bigfile.cbyte --chunk-size 4096 --pin
|
|
135
|
-
cbyte unpack bigfile.cbyte -o bigfile_restored.bin
|
|
136
|
-
diff bigfile.bin bigfile_restored.bin
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## Safety Notes
|
|
142
|
-
|
|
143
|
-
* Fetching or unpacking fails if any block is missing
|
|
144
|
-
* Parallel fetching does not reorder writes; output is deterministic
|
|
145
|
-
* CID ensures cryptographic integrity
|
|
146
|
-
* Use `--pin` to persist blocks on your IPFS node
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## License
|
|
151
|
-
|
|
152
|
-
MIT
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## Repository and Issues
|
|
157
|
-
|
|
158
|
-
* GitHub: [https://github.com/yourusername/cbyte](https://github.com/yourusername/cbyte)
|
|
159
|
-
* Issues: [https://github.com/yourusername/cbyte/issues](https://github.com/yourusername/cbyte/issues)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
**cbyte** is a Node.js CLI utility for content-addressed, deduplicated storage using IPFS. It allows you to pack files into manifests (`.cbyte`), reconstruct them, verify integrity, and manage IPFS pinning.
|
|
163
|
-
|
|
164
|
-
## Features
|
|
165
|
-
- Deduplicated storage using SHA-256 hashes
|
|
166
|
-
- Fixed-size chunking for large files
|
|
167
|
-
- IPFS raw block backend (no UnixFS overhead)
|
|
168
|
-
- Deterministic `.cbyte` manifests
|
|
169
|
-
- Parallel unpacking with safe ordered writes
|
|
170
|
-
- ASCII progress bar during unpack
|
|
171
|
-
- CLI commands: `pack`, `unpack`, `verify`, `pin`
|
|
172
|
-
|
|
173
|
-
## Installation
|
|
174
|
-
|
|
175
|
-
### Using npm
|
|
176
|
-
```
|
|
177
|
-
npm install -g cbyte
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Manual
|
|
181
|
-
```
|
|
182
|
-
git clone https://github.com/yourusername/cbyte.git
|
|
183
|
-
cd cbyte
|
|
184
|
-
npm install
|
|
185
|
-
chmod +x cbyte.js
|
|
186
|
-
sudo ln -sf $(pwd)/cbyte.js /usr/local/bin/cbyte
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
Ensure IPFS daemon is running:
|
|
190
|
-
```
|
|
191
|
-
ipfs daemon &
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## CLI Usage
|
|
195
|
-
```
|
|
196
|
-
cbyte <command> [options]
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
Commands: `pack`, `unpack`, `verify`, `pin`
|
|
200
|
-
|
|
201
|
-
## Examples
|
|
202
|
-
```
|
|
203
|
-
cbyte pack bigfile.bin -o bigfile.cbyte --chunk-size 4096 --pin
|
|
204
|
-
cbyte unpack bigfile.cbyte -o bigfile_restored.bin
|
|
205
|
-
cbyte verify bigfile.cbyte
|
|
206
|
-
cbyte pin bigfile.cbyte
|
|
207
|
-
```
|
|
12
|
+
## Usage
|
|
13
|
+
cbyte pack file.bin
|
|
14
|
+
cbyte unpack file.bin.cbyte
|
|
208
15
|
|
|
16
|
+
Requires Node.js >= 20.8.0
|
package/cbyte-1.13.0.tgz
ADDED
|
Binary file
|
package/cbyte.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import * as Block from 'multiformats/block';
|
|
10
|
-
import * as rawCodec from 'multiformats/codecs/raw';
|
|
11
|
-
import * as sha256 from 'multiformats/hashes/sha2';
|
|
12
|
-
import os from 'os';
|
|
13
|
-
import path from 'path';
|
|
14
|
-
|
|
15
|
-
evt.defaultMaxListeners = 6000;
|
|
16
|
-
|
|
17
|
-
const program = new Command();
|
|
18
|
-
let helia = null;
|
|
19
|
-
|
|
20
|
-
// ---- Promise.withResolvers polyfill (Node < 22) ----
|
|
3
|
+
const [NODE_MAJOR, NODE_MINOR] = process.versions.node.split('.').map(Number)
|
|
4
|
+
if (NODE_MAJOR < 20 || (NODE_MAJOR === 20 && NODE_MINOR < 8)) {
|
|
5
|
+
console.error('cbyte requires Node.js >= 20.8.0')
|
|
6
|
+
process.exit(1)
|
|
7
|
+
}
|
|
8
|
+
|
|
21
9
|
if (typeof Promise.withResolvers !== 'function') {
|
|
22
10
|
Promise.withResolvers = function () {
|
|
23
11
|
let resolve, reject
|
|
@@ -29,174 +17,115 @@ if (typeof Promise.withResolvers !== 'function') {
|
|
|
29
17
|
}
|
|
30
18
|
}
|
|
31
19
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
20
|
+
const fs = require('fs')
|
|
21
|
+
const path = require('path')
|
|
22
|
+
const os = require('os')
|
|
23
|
+
const crypto = require('crypto')
|
|
24
|
+
const { program } = require('commander')
|
|
25
|
+
const { EventEmitter } = require('events')
|
|
26
|
+
|
|
27
|
+
EventEmitter.defaultMaxListeners = 6000
|
|
28
|
+
|
|
29
|
+
async function createHeliaNode(storePath) {
|
|
30
|
+
const { createHelia } = await import('helia')
|
|
31
|
+
const { FsBlockstore } = await import('blockstore-fs')
|
|
38
32
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const ratio = completed / total;
|
|
43
|
-
const filled = Math.floor(ratio * width);
|
|
44
|
-
const bar = '='.repeat(filled) + ' '.repeat(width - filled);
|
|
45
|
-
process.stderr.write(`\r${label} [${bar}] ${(ratio * 100).toFixed(1)}% (${completed}/${total})`);
|
|
33
|
+
const blockstore = new FsBlockstore(storePath)
|
|
34
|
+
const helia = await createHelia({ blockstore, libp2p: false })
|
|
35
|
+
return { helia, blockstore }
|
|
46
36
|
}
|
|
47
37
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
function sha256(buf) {
|
|
39
|
+
return crypto.createHash('sha256').update(buf).digest('hex')
|
|
40
|
+
}
|
|
51
41
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
42
|
+
function renderProgress(label, done, total) {
|
|
43
|
+
const width = 40
|
|
44
|
+
const ratio = total === 0 ? 1 : done / total
|
|
45
|
+
const filled = Math.floor(ratio * width)
|
|
46
|
+
const bar = '='.repeat(filled) + ' '.repeat(width - filled)
|
|
47
|
+
process.stderr.write(`\r${label} [${bar}] ${(ratio * 100).toFixed(1)}%`)
|
|
48
|
+
}
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
const
|
|
50
|
+
async function pack(inputFile, outputFile, chunkSize) {
|
|
51
|
+
const storeDir = path.join(os.homedir(), '.cbyte', 'blocks')
|
|
52
|
+
fs.mkdirSync(storeDir, { recursive: true })
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const hashVal = crypto.createHash('sha256').update(chunk).digest();
|
|
63
|
-
const hash = Buffer.from(hashVal).toString('hex');
|
|
64
|
-
if (!chunksMap[hash]) chunksMap[hash] = { chunk, count: 0 };
|
|
65
|
-
chunksMap[hash].count++;
|
|
66
|
-
}
|
|
54
|
+
const { helia, blockstore } = await createHeliaNode(storeDir)
|
|
55
|
+
const stat = fs.statSync(inputFile)
|
|
67
56
|
|
|
68
57
|
const manifest = {
|
|
69
58
|
format: 'cbyte',
|
|
70
|
-
version: 1.
|
|
59
|
+
version: '1.13',
|
|
60
|
+
original_size: stat.size,
|
|
71
61
|
chunk_size: chunkSize,
|
|
72
|
-
|
|
73
|
-
original_ext: path.extname(filePath),
|
|
62
|
+
extension: path.extname(inputFile),
|
|
74
63
|
chunks: []
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const hashes = Object.keys(chunksMap);
|
|
78
|
-
let uploaded = 0;
|
|
79
|
-
|
|
80
|
-
const concurrency = Math.max(1, Math.min(8, os.cpus().length));
|
|
81
|
-
for (let i = 0; i < hashes.length; i += concurrency) {
|
|
82
|
-
const batch = hashes.slice(i, i + concurrency);
|
|
83
|
-
await Promise.all(batch.map(async (h) => {
|
|
84
|
-
const info = chunksMap[h];
|
|
85
|
-
|
|
86
|
-
// Create a raw block; multiformats block API
|
|
87
|
-
const block = await Block.encode({
|
|
88
|
-
value: info.chunk,
|
|
89
|
-
codec: rawCodec,
|
|
90
|
-
hasher: sha256.sha256
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
await helia.blockstore.put(block.cid, block.bytes);
|
|
94
|
-
|
|
95
|
-
manifest.chunks.push({
|
|
96
|
-
cid: block.cid.toString(),
|
|
97
|
-
length: info.chunk.length,
|
|
98
|
-
count: info.count
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
uploaded++;
|
|
102
|
-
renderProgress(uploaded, hashes.length, 'Packing ...');
|
|
103
|
-
}));
|
|
104
64
|
}
|
|
105
|
-
process.stderr.write('\n');
|
|
106
65
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
66
|
+
const seen = new Map()
|
|
67
|
+
let processed = 0
|
|
68
|
+
|
|
69
|
+
const stream = fs.createReadStream(inputFile, { highWaterMark: chunkSize })
|
|
70
|
+
for await (const chunk of stream) {
|
|
71
|
+
const hash = sha256(chunk)
|
|
72
|
+
let entry = seen.get(hash)
|
|
73
|
+
if (!entry) {
|
|
74
|
+
const cid = await blockstore.put(chunk)
|
|
75
|
+
entry = { cid: cid.toString(), length: chunk.length, count: 0 }
|
|
76
|
+
seen.set(hash, entry)
|
|
77
|
+
manifest.chunks.push(entry)
|
|
78
|
+
}
|
|
79
|
+
entry.count++
|
|
80
|
+
processed += chunk.length
|
|
81
|
+
renderProgress('Packing', processed, stat.size)
|
|
82
|
+
}
|
|
110
83
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
84
|
+
process.stderr.write('\n')
|
|
85
|
+
manifest.manifest_hash = sha256(Buffer.from(JSON.stringify(manifest)))
|
|
86
|
+
fs.writeFileSync(outputFile, JSON.stringify(manifest, null, 2))
|
|
87
|
+
console.log(`Packed -> ${outputFile}`)
|
|
88
|
+
await helia.stop()
|
|
89
|
+
process.exit(0)
|
|
90
|
+
}
|
|
114
91
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const ext = manifest.original_ext || '.bin';
|
|
119
|
-
outFile = `${base}${ext}`;
|
|
120
|
-
}
|
|
92
|
+
async function unpack(manifestPath, outputFile) {
|
|
93
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath))
|
|
94
|
+
if (!outputFile) outputFile = `output${manifest.extension || ''}`
|
|
121
95
|
|
|
122
|
-
const
|
|
123
|
-
const
|
|
124
|
-
let completed = 0;
|
|
125
|
-
|
|
126
|
-
const concurrency = Math.max(1, Math.min(8, os.cpus().length));
|
|
127
|
-
for (let i = 0; i < manifest.chunks.length; i += concurrency) {
|
|
128
|
-
const batch = manifest.chunks.slice(i, i + concurrency);
|
|
129
|
-
await Promise.all(batch.map(async (entry) => {
|
|
130
|
-
const blockBytes = await helia.blockstore.get(entry.cid);
|
|
131
|
-
for (let j = 0; j < entry.count; j++) {
|
|
132
|
-
fs.writeSync(fd, blockBytes.slice(0, entry.length));
|
|
133
|
-
completed++;
|
|
134
|
-
renderProgress(completed, total, 'Unpacking... ');
|
|
135
|
-
}
|
|
136
|
-
}));
|
|
137
|
-
}
|
|
138
|
-
process.stderr.write('\n');
|
|
96
|
+
const storeDir = path.join(os.homedir(), '.cbyte', 'blocks')
|
|
97
|
+
const { helia, blockstore } = await createHeliaNode(storeDir)
|
|
139
98
|
|
|
140
|
-
fs.
|
|
141
|
-
|
|
142
|
-
console.log(`Unpacked -> ${outFile}`);
|
|
143
|
-
}
|
|
99
|
+
const fd = fs.openSync(outputFile, 'w')
|
|
100
|
+
let written = 0
|
|
144
101
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
try {
|
|
152
|
-
await helia.blockstore.get(cid);
|
|
153
|
-
checked++;
|
|
154
|
-
renderProgress(checked, manifest.chunks.length, 'Verifying');
|
|
155
|
-
} catch {
|
|
156
|
-
console.error(`Missing block ${cid}`);
|
|
157
|
-
process.exit(1);
|
|
102
|
+
for (const entry of manifest.chunks) {
|
|
103
|
+
const data = await blockstore.get(entry.cid)
|
|
104
|
+
for (let i = 0; i < entry.count; i++) {
|
|
105
|
+
fs.writeSync(fd, data.slice(0, entry.length))
|
|
106
|
+
written += entry.length
|
|
107
|
+
renderProgress('Unpacking', written, manifest.original_size)
|
|
158
108
|
}
|
|
159
109
|
}
|
|
160
|
-
process.stderr.write('\n');
|
|
161
|
-
console.log('All blocks verified');
|
|
162
|
-
}
|
|
163
110
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
await helia.pin.add(cid);
|
|
171
|
-
pinned++;
|
|
172
|
-
renderProgress(pinned, manifest.chunks.length, 'Pinning...');
|
|
173
|
-
}
|
|
174
|
-
process.stderr.write('\n');
|
|
175
|
-
console.log('All blocks pinned');
|
|
111
|
+
fs.ftruncateSync(fd, manifest.original_size)
|
|
112
|
+
fs.closeSync(fd)
|
|
113
|
+
process.stderr.write('\n')
|
|
114
|
+
console.log(`Unpacked -> ${outputFile}`)
|
|
115
|
+
await helia.stop()
|
|
116
|
+
process.exit(0)
|
|
176
117
|
}
|
|
177
118
|
|
|
178
|
-
|
|
179
|
-
program.
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
.option('--pin', 'Pin blocks after pack', false)
|
|
186
|
-
.action((file, opts) => pack(file, opts.output, parseInt(opts['chunkSize']), opts.pin));
|
|
187
|
-
|
|
188
|
-
program
|
|
189
|
-
.command('unpack <manifest>')
|
|
190
|
-
.option('-o, --output <file>', 'Output file')
|
|
191
|
-
.action((m, opts) => unpack(m, opts.output));
|
|
192
|
-
|
|
193
|
-
program
|
|
194
|
-
.command('verify <manifest>')
|
|
195
|
-
.action((m) => verify(m));
|
|
196
|
-
|
|
197
|
-
program
|
|
198
|
-
.command('pin <manifest>')
|
|
199
|
-
.action((m) => pin(m));
|
|
119
|
+
program.version('1.13')
|
|
120
|
+
program.command('pack <file>')
|
|
121
|
+
.option('-o, --output <file>')
|
|
122
|
+
.option('-c, --chunk-size <bytes>', 'Chunk size', '4096')
|
|
123
|
+
.action((file, opts) => {
|
|
124
|
+
pack(file, opts.output || path.basename(file) + '.cbyte', parseInt(opts.chunkSize))
|
|
125
|
+
})
|
|
200
126
|
|
|
201
|
-
program.
|
|
127
|
+
program.command('unpack <manifest>')
|
|
128
|
+
.option('-o, --output <file>')
|
|
129
|
+
.action((m, opts) => unpack(m, opts.output))
|
|
202
130
|
|
|
131
|
+
program.parse(process.argv)
|
package/package.json
CHANGED
|
@@ -1,33 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cbyte",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"cbyte": "cbyte.js"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"test": "node test.js"
|
|
12
|
-
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
"ipfs",
|
|
15
|
-
"cli",
|
|
16
|
-
"deduplication",
|
|
17
|
-
"storage",
|
|
18
|
-
"content-addressed"
|
|
19
|
-
],
|
|
20
|
-
"author": "Coperbyte <coperbyte@coperbyte.com>",
|
|
21
|
-
"license": "MIT",
|
|
3
|
+
"version": "1.13.0",
|
|
4
|
+
"description": "Content-addressed deduplicated packer using embedded Helia (offline)",
|
|
5
|
+
"bin": { "cbyte": "./cbyte.js" },
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"engines": { "node": ">=20.8.0" },
|
|
22
8
|
"dependencies": {
|
|
23
|
-
"@helia/unixfs": "^7.0.1",
|
|
24
9
|
"commander": "^11.0.0",
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"multiformats": "^13.4.2",
|
|
28
|
-
"undici": "^6.0.0"
|
|
10
|
+
"helia": "^4.0.0",
|
|
11
|
+
"blockstore-fs": "^2.0.0"
|
|
29
12
|
},
|
|
30
|
-
"
|
|
31
|
-
"node": ">=20.8.0"
|
|
32
|
-
}
|
|
13
|
+
"license": "MIT"
|
|
33
14
|
}
|
package/style-0.0.3.tgz
ADDED
|
Binary file
|