@bcts/hubert 1.0.0-alpha.18 → 1.0.0-alpha.19
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/dist/{arid-derivation-1CJuU-kZ.cjs → arid-derivation-CNfUKUp-.cjs} +2 -2
- package/dist/{arid-derivation-1CJuU-kZ.cjs.map → arid-derivation-CNfUKUp-.cjs.map} +1 -1
- package/dist/bin/hubert.cjs +18 -20
- package/dist/bin/hubert.cjs.map +1 -1
- package/dist/bin/hubert.mjs +3 -5
- package/dist/bin/hubert.mjs.map +1 -1
- package/dist/{chunk-CbDLau6x.cjs → chunk-C0xms8kb.cjs} +1 -1
- package/dist/hybrid/index.cjs +14 -13
- package/dist/hybrid/index.d.cts +1 -1
- package/dist/hybrid/index.d.mts +2 -2
- package/dist/hybrid/index.mjs +2 -2
- package/dist/index.cjs +48 -45
- package/dist/index.d.cts +8 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +9 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +7 -5
- package/dist/ipfs/index.cjs +3 -3
- package/dist/ipfs/index.d.cts +1 -1
- package/dist/ipfs/index.d.mts +2 -2
- package/dist/ipfs/index.mjs +0 -1
- package/dist/{kv-yjvQa_LH.cjs → kv-1qBQRbV5.cjs} +3 -3
- package/dist/{kv-yjvQa_LH.cjs.map → kv-1qBQRbV5.cjs.map} +1 -1
- package/dist/{index-T1LHanIb.d.mts → kv-BS5Z28iJ.d.mts} +2 -2
- package/dist/kv-BS5Z28iJ.d.mts.map +1 -0
- package/dist/{index-jyzuOhFB.d.cts → kv-BXu_sOvl.d.cts} +1 -1
- package/dist/kv-BXu_sOvl.d.cts.map +1 -0
- package/dist/{index-CV6lZJqY.d.cts → kv-BZB64lt0.d.cts} +1 -1
- package/dist/kv-BZB64lt0.d.cts.map +1 -0
- package/dist/{index-C2F6ugLL.d.mts → kv-BcjifWIY.d.mts} +2 -2
- package/dist/kv-BcjifWIY.d.mts.map +1 -0
- package/dist/{server-DVyk9gqU.mjs → kv-BhFoL8bc.mjs} +1 -1
- package/dist/kv-BhFoL8bc.mjs.map +1 -0
- package/dist/{kv-BAmhmMOo.cjs → kv-BmCAYeR7.cjs} +3 -3
- package/dist/{kv-BAmhmMOo.cjs.map → kv-BmCAYeR7.cjs.map} +1 -1
- package/dist/{index-CY3TCzIm.d.cts → kv-Bv__Pl2s.d.cts} +1 -1
- package/dist/kv-Bv__Pl2s.d.cts.map +1 -0
- package/dist/{index-BEzpUC7r.d.mts → kv-CVvMuP73.d.mts} +2 -2
- package/dist/kv-CVvMuP73.d.mts.map +1 -0
- package/dist/{hybrid-BZhumygj.mjs → kv-CmxPWVB1.mjs} +2 -2
- package/dist/kv-CmxPWVB1.mjs.map +1 -0
- package/dist/{index-DEr4SR1J.d.cts → kv-DPTr4DWU.d.cts} +1 -1
- package/dist/kv-DPTr4DWU.d.cts.map +1 -0
- package/dist/{kv-C-emxv0w.mjs → kv-DVYfnjvh.mjs} +1 -1
- package/dist/{kv-C-emxv0w.mjs.map → kv-DVYfnjvh.mjs.map} +1 -1
- package/dist/{hybrid-dX5JLumO.cjs → kv-DfzRmYtR.cjs} +4 -4
- package/dist/kv-DfzRmYtR.cjs.map +1 -0
- package/dist/{server-BBNRZ30D.cjs → kv-DmjKQe11.cjs} +2 -2
- package/dist/kv-DmjKQe11.cjs.map +1 -0
- package/dist/{index-CUnDouMb.d.mts → kv-akxfGRZi.d.mts} +2 -2
- package/dist/kv-akxfGRZi.d.mts.map +1 -0
- package/dist/{kv-store-DmngWWuw.d.mts → kv-store-nL8CboDh.d.mts} +1 -1
- package/dist/{kv-store-DmngWWuw.d.mts.map → kv-store-nL8CboDh.d.mts.map} +1 -1
- package/dist/mainline/index.cjs +3 -3
- package/dist/mainline/index.d.cts +1 -1
- package/dist/mainline/index.d.mts +2 -2
- package/dist/mainline/index.mjs +1 -2
- package/dist/server/index.cjs +14 -13
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.mjs +1 -1
- package/package.json +9 -9
- package/dist/hybrid-BZhumygj.mjs.map +0 -1
- package/dist/hybrid-dX5JLumO.cjs.map +0 -1
- package/dist/index-BEzpUC7r.d.mts.map +0 -1
- package/dist/index-C2F6ugLL.d.mts.map +0 -1
- package/dist/index-CUnDouMb.d.mts.map +0 -1
- package/dist/index-CV6lZJqY.d.cts.map +0 -1
- package/dist/index-CY3TCzIm.d.cts.map +0 -1
- package/dist/index-DEr4SR1J.d.cts.map +0 -1
- package/dist/index-T1LHanIb.d.mts.map +0 -1
- package/dist/index-jyzuOhFB.d.cts.map +0 -1
- package/dist/ipfs-BRMMCBjv.mjs +0 -1
- package/dist/ipfs-CetOVQcO.cjs +0 -0
- package/dist/mainline-D_jfeFMh.cjs +0 -0
- package/dist/mainline-cFIuXbo-.mjs +0 -1
- package/dist/server-BBNRZ30D.cjs.map +0 -1
- package/dist/server-DVyk9gqU.mjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-
|
|
1
|
+
const require_chunk = require('./chunk-C0xms8kb.cjs');
|
|
2
2
|
let _bcts_crypto = require("@bcts/crypto");
|
|
3
3
|
let _noble_ciphers_chacha_js = require("@noble/ciphers/chacha.js");
|
|
4
4
|
|
|
@@ -147,4 +147,4 @@ Object.defineProperty(exports, 'obfuscateWithArid', {
|
|
|
147
147
|
return obfuscateWithArid;
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
|
-
//# sourceMappingURL=arid-derivation-
|
|
150
|
+
//# sourceMappingURL=arid-derivation-CNfUKUp-.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arid-derivation-
|
|
1
|
+
{"version":3,"file":"arid-derivation-CNfUKUp-.cjs","names":[],"sources":["../src/arid-derivation.ts"],"sourcesContent":["/**\n * ARID key derivation and obfuscation utilities.\n *\n * Port of arid_derivation.rs from hubert-rust.\n *\n * @module\n */\n\nimport { type ARID } from \"@bcts/components\";\nimport { hkdfHmacSha256 } from \"@bcts/crypto\";\nimport { chacha20 } from \"@noble/ciphers/chacha.js\";\n\n/**\n * Derive a deterministic key from an ARID using a specific salt.\n *\n * Uses HKDF to derive key material from the ARID, ensuring that:\n * - Same ARID always produces same key for a given salt\n * - Keys are cryptographically derived (not guessable)\n * - Collision resistance inherited from ARID\n * - No identifying information in the key (fully anonymized)\n *\n * Port of `derive_key()` from arid_derivation.rs lines 8-29.\n *\n * @param salt - Domain-specific salt to ensure different backends derive different keys\n * @param arid - The ARID to derive from\n * @param outputLen - Length of output in bytes (typically 20 or 32)\n * @returns Derived key bytes\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const key = deriveKey(new TextEncoder().encode(\"my-salt\"), arid, 32);\n * ```\n */\nexport function deriveKey(salt: Uint8Array, arid: ARID, outputLen: number): Uint8Array {\n const aridBytes = arid.data();\n // Note: @bcts/crypto hkdfHmacSha256 takes (keyMaterial, salt, keyLen)\n // Rust bc-crypto takes (salt, ikm, keyLen)\n return hkdfHmacSha256(aridBytes, salt, outputLen);\n}\n\n/**\n * Salt for IPFS IPNS key derivation.\n * @internal\n */\nconst IPFS_KEY_NAME_SALT = new TextEncoder().encode(\"hubert-ipfs-ipns-v1\");\n\n/**\n * Salt for Mainline DHT key derivation.\n * @internal\n */\nconst MAINLINE_KEY_SALT = new TextEncoder().encode(\"hubert-mainline-dht-v1\");\n\n/**\n * Salt for obfuscation key derivation.\n * @internal\n */\nconst OBFUSCATION_SALT = new TextEncoder().encode(\"hubert-obfuscation-v1\");\n\n/**\n * Derive an IPNS key name from an ARID.\n *\n * Returns a 64-character hex string suitable for use as an IPFS key name.\n *\n * Port of `derive_ipfs_key_name()` from arid_derivation.rs lines 31-37.\n *\n * @param arid - The ARID to derive from\n * @returns 64-character hex string\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const keyName = deriveIpfsKeyName(arid);\n * // => \"a1b2c3d4e5f6...\" (64 hex characters)\n * ```\n */\nexport function deriveIpfsKeyName(arid: ARID): string {\n const keyBytes = deriveKey(IPFS_KEY_NAME_SALT, arid, 32);\n return bytesToHex(keyBytes);\n}\n\n/**\n * Derive Mainline DHT key material from an ARID.\n *\n * Returns 20 bytes of key material (SHA-1 compatible length).\n *\n * Port of `derive_mainline_key()` from arid_derivation.rs lines 39-45.\n *\n * @param arid - The ARID to derive from\n * @returns 20 bytes of key material\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const key = deriveMainlineKey(arid);\n * // => Uint8Array(20) [...]\n * ```\n */\nexport function deriveMainlineKey(arid: ARID): Uint8Array {\n return deriveKey(MAINLINE_KEY_SALT, arid, 20);\n}\n\n/**\n * Obfuscate or deobfuscate data using ChaCha20 with an ARID-derived key.\n *\n * This function uses ChaCha20 as a stream cipher to XOR the data with a\n * keystream derived from the ARID. Since XOR is symmetric, the same function\n * is used for both obfuscation and deobfuscation.\n *\n * The result appears as uniform random data to anyone who doesn't have the\n * ARID, hiding both the structure and content of the reference envelope.\n *\n * Port of `obfuscate_with_arid()` from arid_derivation.rs lines 47-91.\n *\n * @param arid - The ARID used to derive the obfuscation key\n * @param data - The data to obfuscate or deobfuscate\n * @returns The obfuscated (or deobfuscated) data\n * @category ARID Derivation\n *\n * @example\n * ```typescript\n * const obfuscated = obfuscateWithArid(arid, plaintext);\n * const deobfuscated = obfuscateWithArid(arid, obfuscated);\n * // deobfuscated === plaintext\n * ```\n */\nexport function obfuscateWithArid(arid: ARID, data: Uint8Array): Uint8Array {\n if (data.length === 0) {\n return new Uint8Array(0);\n }\n\n // Derive a 32-byte key from the ARID using HKDF with domain-specific salt\n const key = deriveKey(OBFUSCATION_SALT, arid, 32);\n\n // Derive IV from the key (last 12 bytes, reversed)\n // Match Rust: key.iter().rev().take(12).copied().collect()\n const iv = new Uint8Array(12);\n for (let i = 0; i < 12; i++) {\n iv[i] = key[31 - i];\n }\n\n // Use ChaCha20 to XOR the data\n // @noble/ciphers chacha20 takes (key, nonce, data) and returns encrypted data\n return chacha20(key, iv, data);\n}\n\n/**\n * Convert bytes to lowercase hex string.\n * @internal\n */\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,UAAU,MAAkB,MAAY,WAA+B;AAIrF,yCAHkB,KAAK,MAAM,EAGI,MAAM,UAAU;;;;;;AAOnD,MAAM,qBAAqB,IAAI,aAAa,CAAC,OAAO,sBAAsB;;;;;AAM1E,MAAM,oBAAoB,IAAI,aAAa,CAAC,OAAO,yBAAyB;;;;;AAM5E,MAAM,mBAAmB,IAAI,aAAa,CAAC,OAAO,wBAAwB;;;;;;;;;;;;;;;;;;AAmB1E,SAAgB,kBAAkB,MAAoB;AAEpD,QAAO,WADU,UAAU,oBAAoB,MAAM,GAAG,CAC7B;;;;;;;;;;;;;;;;;;;AAoB7B,SAAgB,kBAAkB,MAAwB;AACxD,QAAO,UAAU,mBAAmB,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;AA2B/C,SAAgB,kBAAkB,MAAY,MAA8B;AAC1E,KAAI,KAAK,WAAW,EAClB,QAAO,IAAI,WAAW,EAAE;CAI1B,MAAM,MAAM,UAAU,kBAAkB,MAAM,GAAG;CAIjD,MAAM,KAAK,IAAI,WAAW,GAAG;AAC7B,MAAK,IAAI,IAAI,GAAG,IAAI,IAAI,IACtB,IAAG,KAAK,IAAI,KAAK;AAKnB,+CAAgB,KAAK,IAAI,KAAK;;;;;;AAOhC,SAAS,WAAW,OAA2B;AAC7C,QAAO,MAAM,KAAK,MAAM,CACrB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAC3C,KAAK,GAAG"}
|
package/dist/bin/hubert.cjs
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_chunk = require('../chunk-
|
|
2
|
+
const require_chunk = require('../chunk-C0xms8kb.cjs');
|
|
3
3
|
const require_logging = require('../logging-qc9uMgil.cjs');
|
|
4
|
-
require('../arid-derivation-
|
|
5
|
-
const
|
|
6
|
-
const require_kv = require('../kv-
|
|
7
|
-
require('../
|
|
8
|
-
const require_kv$
|
|
9
|
-
require('../mainline-D_jfeFMh.cjs');
|
|
10
|
-
const require_hybrid = require('../hybrid-dX5JLumO.cjs');
|
|
4
|
+
require('../arid-derivation-CNfUKUp-.cjs');
|
|
5
|
+
const require_kv = require('../kv-DmjKQe11.cjs');
|
|
6
|
+
const require_kv$1 = require('../kv-1qBQRbV5.cjs');
|
|
7
|
+
const require_kv$2 = require('../kv-BmCAYeR7.cjs');
|
|
8
|
+
const require_kv$3 = require('../kv-DfzRmYtR.cjs');
|
|
11
9
|
require('../index.cjs');
|
|
12
10
|
let path = require("path");
|
|
13
11
|
path = require_chunk.__toESM(path);
|
|
@@ -67,7 +65,7 @@ function generateRandomEnvelope(size) {
|
|
|
67
65
|
*/
|
|
68
66
|
async function checkMainline() {
|
|
69
67
|
try {
|
|
70
|
-
await (await require_kv$
|
|
68
|
+
await (await require_kv$2.MainlineDhtKv.create()).destroy();
|
|
71
69
|
console.log("✓ Mainline DHT is available");
|
|
72
70
|
} catch (e) {
|
|
73
71
|
throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);
|
|
@@ -126,7 +124,7 @@ async function checkServer(host, port) {
|
|
|
126
124
|
* Port of `put_mainline()` from bin/hubert.rs lines 207-221.
|
|
127
125
|
*/
|
|
128
126
|
async function putMainline(arid, envelope, verbose) {
|
|
129
|
-
const store = await require_kv$
|
|
127
|
+
const store = await require_kv$2.MainlineDhtKv.create();
|
|
130
128
|
try {
|
|
131
129
|
await store.put(arid, envelope, void 0, verbose);
|
|
132
130
|
if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
|
|
@@ -140,7 +138,7 @@ async function putMainline(arid, envelope, verbose) {
|
|
|
140
138
|
* Port of `put_ipfs()` from bin/hubert.rs lines 223-250.
|
|
141
139
|
*/
|
|
142
140
|
async function putIpfs(arid, envelope, port, pin, verbose) {
|
|
143
|
-
const result = await new require_kv.IpfsKv(`http://127.0.0.1:${port}`).withPinContent(pin).put(arid, envelope, void 0, verbose);
|
|
141
|
+
const result = await new require_kv$1.IpfsKv(`http://127.0.0.1:${port}`).withPinContent(pin).put(arid, envelope, void 0, verbose);
|
|
144
142
|
if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
|
|
145
143
|
if (pin) {
|
|
146
144
|
const cidPart = result.split("ipfs://")[1];
|
|
@@ -154,7 +152,7 @@ async function putIpfs(arid, envelope, port, pin, verbose) {
|
|
|
154
152
|
*/
|
|
155
153
|
async function putHybrid(arid, envelope, port, pin, verbose) {
|
|
156
154
|
const url = `http://127.0.0.1:${port}`;
|
|
157
|
-
const store = (await
|
|
155
|
+
const store = (await require_kv$3.HybridKv.create(url)).withPinContent(pin);
|
|
158
156
|
try {
|
|
159
157
|
const result = await store.put(arid, envelope, void 0, verbose);
|
|
160
158
|
if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
|
|
@@ -172,7 +170,7 @@ async function putHybrid(arid, envelope, port, pin, verbose) {
|
|
|
172
170
|
* Port of `put_server()` from bin/hubert.rs lines 324-344.
|
|
173
171
|
*/
|
|
174
172
|
async function putServer(host, port, arid, envelope, ttl, verbose) {
|
|
175
|
-
await new
|
|
173
|
+
await new require_kv.ServerKvClient(`http://${host}:${port}`).put(arid, envelope, ttl, verbose);
|
|
176
174
|
if (verbose) require_logging.verbosePrintln("✓ Stored envelope at ARID");
|
|
177
175
|
}
|
|
178
176
|
/**
|
|
@@ -181,7 +179,7 @@ async function putServer(host, port, arid, envelope, ttl, verbose) {
|
|
|
181
179
|
* Port of `get_mainline()` from bin/hubert.rs lines 252-262.
|
|
182
180
|
*/
|
|
183
181
|
async function getMainline(arid, timeout, verbose) {
|
|
184
|
-
const store = await require_kv$
|
|
182
|
+
const store = await require_kv$2.MainlineDhtKv.create();
|
|
185
183
|
try {
|
|
186
184
|
return await store.get(arid, timeout, verbose);
|
|
187
185
|
} finally {
|
|
@@ -194,7 +192,7 @@ async function getMainline(arid, timeout, verbose) {
|
|
|
194
192
|
* Port of `get_ipfs()` from bin/hubert.rs lines 264-276.
|
|
195
193
|
*/
|
|
196
194
|
async function getIpfs(arid, timeout, port, verbose) {
|
|
197
|
-
return await new require_kv.IpfsKv(`http://127.0.0.1:${port}`).get(arid, timeout, verbose);
|
|
195
|
+
return await new require_kv$1.IpfsKv(`http://127.0.0.1:${port}`).get(arid, timeout, verbose);
|
|
198
196
|
}
|
|
199
197
|
/**
|
|
200
198
|
* Get envelope from Hybrid storage.
|
|
@@ -203,7 +201,7 @@ async function getIpfs(arid, timeout, port, verbose) {
|
|
|
203
201
|
*/
|
|
204
202
|
async function getHybrid(arid, timeout, port, verbose) {
|
|
205
203
|
const url = `http://127.0.0.1:${port}`;
|
|
206
|
-
const store = await
|
|
204
|
+
const store = await require_kv$3.HybridKv.create(url);
|
|
207
205
|
try {
|
|
208
206
|
return await store.get(arid, timeout, verbose);
|
|
209
207
|
} finally {
|
|
@@ -216,7 +214,7 @@ async function getHybrid(arid, timeout, port, verbose) {
|
|
|
216
214
|
* Port of `get_server()` from bin/hubert.rs lines 346-361.
|
|
217
215
|
*/
|
|
218
216
|
async function getServer(host, port, arid, timeout, verbose) {
|
|
219
|
-
return await new
|
|
217
|
+
return await new require_kv.ServerKvClient(`http://${host}:${port}`).get(arid, timeout, verbose);
|
|
220
218
|
}
|
|
221
219
|
const program = new commander.Command();
|
|
222
220
|
program.name("hubert").description("Distributed substrate for multiparty transactions").version("1.0.0-alpha.1").option("-v, --verbose", "Enable verbose logging", false);
|
|
@@ -364,12 +362,12 @@ program.command("server").description("Start the Hubert HTTP server").option("--
|
|
|
364
362
|
try {
|
|
365
363
|
if (fs.statSync(sqlitePath).isDirectory()) sqlitePath = path.default.join(sqlitePath, "hubert.sqlite");
|
|
366
364
|
} catch {}
|
|
367
|
-
const store = new
|
|
368
|
-
const server =
|
|
365
|
+
const store = new require_kv.SqliteKv(sqlitePath);
|
|
366
|
+
const server = require_kv.Server.newSqlite(config, store);
|
|
369
367
|
console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);
|
|
370
368
|
await server.run();
|
|
371
369
|
} else {
|
|
372
|
-
const server =
|
|
370
|
+
const server = require_kv.Server.newMemory(config);
|
|
373
371
|
console.log(`Starting Hubert server on port ${port} with in-memory storage`);
|
|
374
372
|
await server.run();
|
|
375
373
|
}
|
package/dist/bin/hubert.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hubert.cjs","names":["ARID","Envelope","MainlineDhtKv","IpfsKv","HybridKv","ServerKvClient","Command","SqliteKv","Server"],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAS,UAAU,GAAiB;AAClC,KAAI;AACF,SAAOA,sBAAK,aAAa,EAAE;SACrB;AACN,QAAM,IAAI,MAAM,wCAAwC;;;;;;;;AAS5D,SAAS,cAAc,GAAqB;AAC1C,KAAI;AACF,SAAOC,wBAAS,aAAa,EAAE;SACzB;AACN,QAAM,IAAI,MAAM,gDAAgD;;;;;;;;AASpE,SAAS,uBAAuB,MAAwB;CACtD,MAAM,yCAAyB,KAAK;AAEpC,QAAOA,wBAAS,IAAI,YAAY;;;;;;;AAYlC,eAAe,gBAA+B;AAC5C,KAAI;AAEF,SADY,MAAMC,2BAAc,QAAQ,EAC9B,SAAS;AACnB,UAAQ,IAAI,8BAA8B;UACnC,GAAG;AACV,QAAM,IAAI,MAAM,oCAAoC,aAAa,QAAQ,EAAE,UAAU,IAAI;;;;;;;;AAS7F,eAAe,UAAU,MAA6B;AACpD,KAAI;EACF,MAAM,MAAM,oBAAoB,KAAK;EACrC,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,UAAU,iBAAiB,WAAW,OAAO,EAAE,IAAK;EAE1D,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,QAAQ;GACR,QAAQ,WAAW;GACpB,CAAC;AAEF,eAAa,QAAQ;AAErB,MAAI,SAAS,GACX,SAAQ,IAAI,oCAAoC,OAAO;MAEvD,OAAM,IAAI,MAAM,iCAAiC,SAAS,SAAS;UAE9D,GAAG;AACV,MAAI,aAAa,SAAS,EAAE,SAAS,aACnC,OAAM,IAAI,MAAM,wCAAwC,KAAK,sBAAsB;AAErF,QAAM,IAAI,MACR,wCAAwC,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,IACnF;;;;;;AAOL,eAAe,YAAY,MAAc,MAA6B;AACpE,KAAI;EACF,MAAM,MAAM,UAAU,KAAK,GAAG,KAAK;EACnC,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,UAAU,iBAAiB,WAAW,OAAO,EAAE,IAAK;EAE1D,MAAM,WAAW,MAAM,MAAM,KAAK;GAChC,QAAQ;GACR,QAAQ,WAAW;GACpB,CAAC;AAEF,eAAa,QAAQ;AAErB,MAAI,SAAS,IAAI;GACf,MAAM,OAAQ,MAAM,SAAS,MAAM;AACnC,OAAI,KAAK,WAAW,UAAU;IAC5B,MAAM,UAAU,KAAK,WAAW;AAChC,YAAQ,IAAI,mCAAmC,KAAK,GAAG,KAAK,YAAY,QAAQ,GAAG;SAEnF,OAAM,IAAI,MAAM,eAAe,KAAK,GAAG,KAAK,yBAAyB;QAGvE,OAAM,IAAI,MAAM,eAAe,KAAK,GAAG,KAAK,6BAA6B,SAAS,OAAO,GAAG;UAEvF,GAAG;AACV,MAAI,aAAa,SAAS,EAAE,SAAS,aACnC,OAAM,IAAI,MAAM,gCAAgC,KAAK,GAAG,KAAK,sBAAsB;AAErF,QAAM,IAAI,MACR,gCAAgC,KAAK,GAAG,KAAK,IAAI,aAAa,QAAQ,EAAE,UAAU,IACnF;;;;;;;;AAaL,eAAe,YAAY,MAAY,UAAoB,SAAiC;CAC1F,MAAM,QAAQ,MAAMA,2BAAc,QAAQ;AAC1C,KAAI;AACF,QAAM,MAAM,IAAI,MAAM,UAAU,QAAW,QAAQ;AACnD,MAAI,QACF,gCAAe,4BAA4B;WAErC;AACR,QAAM,MAAM,SAAS;;;;;;;;AASzB,eAAe,QACb,MACA,UACA,MACA,KACA,SACe;CAGf,MAAM,SAAS,MADD,IAAIC,kBADN,oBAAoB,OACH,CAAC,eAAe,IAAI,CACtB,IAAI,MAAM,UAAU,QAAW,QAAQ;AAElE,KAAI,QACF,gCAAe,4BAA4B;AAI7C,KAAI,KAAK;EACP,MAAM,UAAU,OAAO,MAAM,UAAU,CAAC;AACxC,MAAI,QACF,SAAQ,IAAI,QAAQ,UAAU;;;;;;;;AAUpC,eAAe,UACb,MACA,UACA,MACA,KACA,SACe;CACf,MAAM,MAAM,oBAAoB;CAChC,MAAM,SAAS,MAAMC,wBAAS,OAAO,IAAI,EAAE,eAAe,IAAI;AAC9D,KAAI;EACF,MAAM,SAAS,MAAM,MAAM,IAAI,MAAM,UAAU,QAAW,QAAQ;AAElE,MAAI,QACF,gCAAe,4BAA4B;AAI7C,MAAI,OAAO,OAAO,SAAS,UAAU,EAAE;GACrC,MAAM,UAAU,OAAO,MAAM,UAAU,CAAC;AACxC,OAAI,QACF,SAAQ,IAAI,QAAQ,UAAU;;WAG1B;AACR,QAAM,MAAM,SAAS;;;;;;;;AASzB,eAAe,UACb,MACA,MACA,MACA,UACA,KACA,SACe;AAGf,OADc,IAAIC,8BADN,UAAU,KAAK,GAAG,OACO,CACzB,IAAI,MAAM,UAAU,KAAK,QAAQ;AAC7C,KAAI,QACF,gCAAe,4BAA4B;;;;;;;AAa/C,eAAe,YACb,MACA,SACA,SAC0B;CAC1B,MAAM,QAAQ,MAAMH,2BAAc,QAAQ;AAC1C,KAAI;AACF,SAAO,MAAM,MAAM,IAAI,MAAM,SAAS,QAAQ;WACtC;AACR,QAAM,MAAM,SAAS;;;;;;;;AASzB,eAAe,QACb,MACA,SACA,MACA,SAC0B;AAG1B,QAAO,MADO,IAAIC,kBADN,oBAAoB,OACH,CACV,IAAI,MAAM,SAAS,QAAQ;;;;;;;AAQhD,eAAe,UACb,MACA,SACA,MACA,SAC0B;CAC1B,MAAM,MAAM,oBAAoB;CAChC,MAAM,QAAQ,MAAMC,wBAAS,OAAO,IAAI;AACxC,KAAI;AACF,SAAO,MAAM,MAAM,IAAI,MAAM,SAAS,QAAQ;WACtC;AACR,QAAM,MAAM,SAAS;;;;;;;;AASzB,eAAe,UACb,MACA,MACA,MACA,SACA,SAC0B;AAG1B,QAAO,MADO,IAAIC,8BADN,UAAU,KAAK,GAAG,OACO,CAClB,IAAI,MAAM,SAAS,QAAQ;;AAOhD,MAAM,UAAU,IAAIC,mBAAS;AAE7B,QACG,KAAK,SAAS,CACd,YAAY,oDAAoD,CAChE,QAAQ,gBAAgB,CACxB,OAAO,iBAAiB,0BAA0B,MAAM;AAG3D,MAAM,cAAc,QACjB,QAAQ,WAAW,CACnB,YAAY,0CAA0C;AAEzD,YACG,QAAQ,OAAO,CACf,YAAY,sBAAsB,CAClC,aAAa;CACZ,MAAM,OAAON,sBAAK,KAAK;AACvB,SAAQ,IAAI,KAAK,UAAU,CAAC;EAC5B;AAEJ,YACG,QAAQ,kBAAkB,CAC1B,YAAY,4CAA4C,CACxD,QAAQ,YAAoB;CAC3B,MAAM,OAAO,SAAS,SAAS,GAAG;AAClC,KAAI,MAAM,KAAK,IAAI,OAAO,GAAG;AAC3B,UAAQ,MAAM,kCAAkC;AAChD,UAAQ,KAAK,EAAE;;CAEjB,MAAM,WAAW,uBAAuB,KAAK;AAC7C,SAAQ,IAAI,SAAS,UAAU,CAAC;EAChC;AAGJ,QACG,QAAQ,wBAAwB,CAChC,YAAY,+BAA+B,CAC3C,OAAO,2BAA2B,0BAA0B,WAAW,CACvE,OAAO,iBAAiB,qCAAqC,CAC7D,OAAO,iBAAiB,0CAA0C,CAClE,OAAO,mBAAmB,iDAAiD,CAC3E,OAAO,SAAS,qEAAqE,MAAM,CAC3F,OACC,OACE,SACA,aACA,YAOG;CACH,MAAM,UAAU,QAAQ,MAAM,CAAC;CAC/B,MAAM,UAAU,QAAQ;CACxB,MAAM,OAAO,QAAQ,OAAO,SAAS,QAAQ,MAAM,GAAG,GAAG;CACzD,MAAM,MAAM,QAAQ,MAAM,SAAS,QAAQ,KAAK,GAAG,GAAG;AAEtD,KAAI;AAEF,MAAI,YAAY,YAAY;AAC1B,OAAI,SAAS,OACX,OAAM,IAAI,MAAM,wDAAwD;AAE1E,OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MAAM,wDAAwD;AAE1E,OAAI,QAAQ,OACV,OAAM,IAAI,MAAM,sDAAsD;AAExE,OAAI,QAAQ,IACV,OAAM,IAAI,MACR,wEACD;aAEM,YAAY,QAAQ;AAC7B,OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,4EACD;AAEH,OAAI,QAAQ,OACV,OAAM,IAAI,MAAM,sDAAsD;aAE/D,YAAY,UAAU;AAC/B,OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,8EACD;AAEH,OAAI,QAAQ,OACV,OAAM,IAAI,MAAM,sDAAsD;aAE/D,YAAY,UACrB;OAAI,QAAQ,IACV,OAAM,IAAI,MACR,wEACD;;EAIL,MAAM,OAAO,UAAU,QAAQ;EAC/B,MAAM,WAAW,cAAc,YAAY;AAE3C,UAAQ,SAAR;GACE,KAAK;AACH,UAAM,YAAY,MAAM,UAAU,QAAQ;AAC1C,YAAQ,IAAI,yBAAyB;AACrC;GACF,KAAK;AACH,UAAM,QAAQ,MAAM,UAAU,QAAQ,MAAM,QAAQ,KAAK,QAAQ;AACjE,YAAQ,IAAI,iBAAiB;AAC7B;GACF,KAAK;AACH,UAAM,UAAU,MAAM,UAAU,QAAQ,MAAM,QAAQ,KAAK,QAAQ;AACnE,YAAQ,IAAI,2BAA2B;AACvC;GACF,KAAK;AAEH,UAAM,UADO,QAAQ,QAAQ,aACP,QAAQ,OAAO,MAAM,UAAU,KAAK,QAAQ;AAClE,YAAQ,IAAI,mBAAmB;AAC/B;;UAGG,GAAG;AACV,UAAQ,MAAM,aAAa,QAAQ,EAAE,UAAU,EAAE;AACjD,UAAQ,KAAK,EAAE;;EAGpB;AAGH,QACG,QAAQ,aAAa,CACrB,YAAY,+BAA+B,CAC3C,OAAO,2BAA2B,0BAA0B,WAAW,CACvE,OAAO,iBAAiB,qCAAqC,CAC7D,OAAO,iBAAiB,0CAA0C,CAClE,OAAO,2BAA2B,mCAAmC,KAAK,CAC1E,OACC,OACE,SACA,YAMG;CACH,MAAM,UAAU,QAAQ,MAAM,CAAC;CAC/B,MAAM,UAAU,QAAQ;CACxB,MAAM,OAAO,QAAQ,OAAO,SAAS,QAAQ,MAAM,GAAG,GAAG;CACzD,MAAM,UAAU,SAAS,QAAQ,SAAS,GAAG;AAE7C,KAAI;AAEF,MAAI,YAAY,YAAY;AAC1B,OAAI,SAAS,OACX,OAAM,IAAI,MAAM,wDAAwD;AAE1E,OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MAAM,wDAAwD;aAEjE,YAAY,QACrB;OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,4EACD;aAEM,YAAY,UACrB;OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,8EACD;;EAIL,MAAM,OAAO,UAAU,QAAQ;EAE/B,IAAI;AACJ,UAAQ,SAAR;GACE,KAAK;AACH,eAAW,MAAM,YAAY,MAAM,SAAS,QAAQ;AACpD;GACF,KAAK;AACH,eAAW,MAAM,QAAQ,MAAM,SAAS,QAAQ,MAAM,QAAQ;AAC9D;GACF,KAAK;AACH,eAAW,MAAM,UAAU,MAAM,SAAS,QAAQ,MAAM,QAAQ;AAChE;GACF,KAAK;AAEH,eAAW,MAAM,UADJ,QAAQ,QAAQ,aACI,QAAQ,OAAO,MAAM,SAAS,QAAQ;AACvE;;AAIJ,MAAI,SACF,SAAQ,IAAI,SAAS,UAAU,CAAC;MAEhC,OAAM,IAAI,MAAM,0BAA0B,QAAQ,UAAU;UAEvD,GAAG;AACV,UAAQ,MAAM,aAAa,QAAQ,EAAE,UAAU,EAAE;AACjD,UAAQ,KAAK,EAAE;;EAGpB;AAGH,QACG,QAAQ,QAAQ,CAChB,YAAY,wCAAwC,CACpD,OAAO,2BAA2B,0BAA0B,WAAW,CACvE,OAAO,iBAAiB,qCAAqC,CAC7D,OAAO,iBAAiB,0CAA0C,CAClE,OAAO,OAAO,YAAuE;CACpF,MAAM,UAAU,QAAQ;CACxB,MAAM,OAAO,QAAQ,OAAO,SAAS,QAAQ,MAAM,GAAG,GAAG;AAEzD,KAAI;AAEF,MAAI,YAAY,YAAY;AAC1B,OAAI,SAAS,OACX,OAAM,IAAI,MAAM,wDAAwD;AAE1E,OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MAAM,wDAAwD;aAEjE,YAAY,QACrB;OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,4EACD;aAEM,YAAY,UACrB;OAAI,QAAQ,SAAS,OACnB,OAAM,IAAI,MACR,8EACD;;AAIL,UAAQ,SAAR;GACE,KAAK;AACH,UAAM,eAAe;AACrB;GACF,KAAK;AACH,UAAM,UAAU,QAAQ,KAAK;AAC7B;GACF,KAAK;AACH,UAAM,eAAe;AACrB,UAAM,UAAU,QAAQ,KAAK;AAC7B,YAAQ,IAAI,6CAA6C;AACzD;GACF,KAAK;AAEH,UAAM,YADO,QAAQ,QAAQ,aACL,QAAQ,MAAM;AACtC;;UAGG,GAAG;AACV,UAAQ,MAAM,aAAa,QAAQ,EAAE,UAAU,EAAE;AACjD,UAAQ,KAAK,EAAE;;EAEjB;AAGJ,QACG,QAAQ,SAAS,CACjB,YAAY,+BAA+B,CAC3C,OAAO,iBAAiB,oCAAoC,QAAQ,CACpE,OAAO,mBAAmB,mDAAmD,CAC7E,OAAO,OAAO,YAA+C;CAC5D,MAAM,UAAU,QAAQ,MAAM,CAAC;CAC/B,MAAM,OAAO,SAAS,QAAQ,MAAM,GAAG;AAEvC,KAAI;EACF,MAAM,SAAuB;GAC3B;GACA,QAAQ;GACR;GACD;AAED,MAAI,QAAQ,QAAQ;GAElB,IAAI,aAAa,QAAQ;GAEzB,MAAM,KAAK,MAAM,OAAO;AACxB,OAAI;AAEF,QADc,GAAG,SAAS,WAAW,CAC3B,aAAa,CACrB,cAAa,aAAK,KAAK,YAAY,gBAAgB;WAE/C;GAIR,MAAM,QAAQ,IAAIO,wBAAS,WAAW;GACtC,MAAM,SAASC,sBAAO,UAAU,QAAQ,MAAM;AAC9C,WAAQ,IAAI,kCAAkC,KAAK,wBAAwB,aAAa;AACxF,SAAM,OAAO,KAAK;SACb;GAEL,MAAM,SAASA,sBAAO,UAAU,OAAO;AACvC,WAAQ,IAAI,kCAAkC,KAAK,yBAAyB;AAC5E,SAAM,OAAO,KAAK;;UAEb,GAAG;AACV,UAAQ,MAAM,aAAa,QAAQ,EAAE,UAAU,EAAE;AACjD,UAAQ,KAAK,EAAE;;EAEjB;AAGJ,QAAQ,OAAO"}
|
|
1
|
+
{"version":3,"file":"hubert.cjs","names":["ARID","Envelope","MainlineDhtKv","IpfsKv","HybridKv","ServerKvClient","Command","SqliteKv","Server"],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
|
package/dist/bin/hubert.mjs
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { i as verbosePrintln } from "../logging-hmzNzifq.mjs";
|
|
3
3
|
import "../arid-derivation-CbqACjdg.mjs";
|
|
4
|
-
import { n as Server, o as SqliteKv, t as ServerKvClient } from "../
|
|
4
|
+
import { n as Server, o as SqliteKv, t as ServerKvClient } from "../kv-BhFoL8bc.mjs";
|
|
5
5
|
import { t as IpfsKv } from "../kv-DJiKvypY.mjs";
|
|
6
|
-
import "../
|
|
7
|
-
import { t as
|
|
8
|
-
import "../mainline-cFIuXbo-.mjs";
|
|
9
|
-
import { t as HybridKv } from "../hybrid-BZhumygj.mjs";
|
|
6
|
+
import { t as MainlineDhtKv } from "../kv-DVYfnjvh.mjs";
|
|
7
|
+
import { t as HybridKv } from "../kv-CmxPWVB1.mjs";
|
|
10
8
|
import "../index.mjs";
|
|
11
9
|
import path from "path";
|
|
12
10
|
import { ARID } from "@bcts/components";
|
package/dist/bin/hubert.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hubert.mjs","names":[],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hubert.mjs","names":[],"sources":["../../src/bin/hubert.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Hubert: Secure Distributed Substrate for Multiparty Transactions\n *\n * A command-line tool for storing and retrieving Gordian Envelopes using\n * distributed storage backends (BitTorrent Mainline DHT or IPFS).\n *\n * Port of bin/hubert.rs from hubert-rust.\n *\n * @module\n */\n\nimport { Command } from \"commander\";\nimport path from \"path\";\n\nimport { ARID } from \"@bcts/components\";\nimport { Envelope } from \"@bcts/envelope\";\nimport { randomData } from \"@bcts/rand\";\n\nimport {\n verbosePrintln,\n IpfsKv,\n MainlineDhtKv,\n HybridKv,\n Server,\n type ServerConfig,\n ServerKvClient,\n SqliteKv,\n} from \"../index.js\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\ntype StorageBackend = \"mainline\" | \"ipfs\" | \"hybrid\" | \"server\";\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Parse an ARID from ur:arid string format.\n *\n * Port of `parse_arid()` from bin/hubert.rs lines 150-153.\n */\nfunction parseArid(s: string): ARID {\n try {\n return ARID.fromUrString(s);\n } catch {\n throw new Error(\"Invalid ARID format. Expected ur:arid\");\n }\n}\n\n/**\n * Parse an Envelope from ur:envelope string format.\n *\n * Port of `parse_envelope()` from bin/hubert.rs lines 155-161.\n */\nfunction parseEnvelope(s: string): Envelope {\n try {\n return Envelope.fromUrString(s);\n } catch {\n throw new Error(\"Invalid envelope format. Expected ur:envelope\");\n }\n}\n\n/**\n * Generate a random envelope with the specified size.\n *\n * Port of `generate_random_envelope()` from bin/hubert.rs lines 163-167.\n */\nfunction generateRandomEnvelope(size: number): Envelope {\n const randomBytes = randomData(size);\n // Pass raw Uint8Array directly - Envelope.new accepts it as EnvelopeEncodableValue\n return Envelope.new(randomBytes);\n}\n\n// =============================================================================\n// Check Functions\n// =============================================================================\n\n/**\n * Check if Mainline DHT is available.\n *\n * Port of `check_mainline()` from bin/hubert.rs lines 169-182.\n */\nasync function checkMainline(): Promise<void> {\n try {\n const dht = await MainlineDhtKv.create();\n await dht.destroy();\n console.log(\"✓ Mainline DHT is available\");\n } catch (e) {\n throw new Error(`✗ Mainline DHT is not available: ${e instanceof Error ? e.message : e}`);\n }\n}\n\n/**\n * Check if IPFS is available.\n *\n * Port of `check_ipfs()` from bin/hubert.rs lines 184-205.\n */\nasync function checkIpfs(port: number): Promise<void> {\n try {\n const url = `http://127.0.0.1:${port}/api/v0/version`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"POST\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n console.log(`✓ IPFS is available at 127.0.0.1:${port}`);\n } else {\n throw new Error(`✗ IPFS daemon returned error: ${response.status}`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ IPFS is not available at 127.0.0.1:${port}: connection timeout`);\n }\n throw new Error(\n `✗ IPFS is not available at 127.0.0.1:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n/**\n * Check if Hubert server is available.\n */\nasync function checkServer(host: string, port: number): Promise<void> {\n try {\n const url = `http://${host}:${port}/health`;\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 2000);\n\n const response = await fetch(url, {\n method: \"GET\",\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n\n if (response.ok) {\n const json = (await response.json()) as { server?: string; version?: string };\n if (json.server === \"hubert\") {\n const version = json.version ?? \"unknown\";\n console.log(`✓ Hubert server is available at ${host}:${port} (version ${version})`);\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not a Hubert server`);\n }\n } else {\n throw new Error(`✗ Server at ${host}:${port} is not available (status: ${response.status})`);\n }\n } catch (e) {\n if (e instanceof Error && e.name === \"AbortError\") {\n throw new Error(`✗ Server is not available at ${host}:${port}: connection timeout`);\n }\n throw new Error(\n `✗ Server is not available at ${host}:${port}: ${e instanceof Error ? e.message : e}`,\n );\n }\n}\n\n// =============================================================================\n// Put Functions\n// =============================================================================\n\n/**\n * Put envelope to Mainline DHT.\n *\n * Port of `put_mainline()` from bin/hubert.rs lines 207-221.\n */\nasync function putMainline(arid: ARID, envelope: Envelope, verbose: boolean): Promise<void> {\n const store = await MainlineDhtKv.create();\n try {\n await store.put(arid, envelope, undefined, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to IPFS.\n *\n * Port of `put_ipfs()` from bin/hubert.rs lines 223-250.\n */\nasync function putIpfs(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url).withPinContent(pin);\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested\n if (pin) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n}\n\n/**\n * Put envelope to Hybrid storage.\n *\n * Port of `put_hybrid()` from bin/hubert.rs lines 278-308.\n */\nasync function putHybrid(\n arid: ARID,\n envelope: Envelope,\n port: number,\n pin: boolean,\n verbose: boolean,\n): Promise<void> {\n const url = `http://127.0.0.1:${port}`;\n const store = (await HybridKv.create(url)).withPinContent(pin);\n try {\n const result = await store.put(arid, envelope, undefined, verbose);\n\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n\n // Extract and print CID if pinning was requested and IPFS was used\n if (pin && result.includes(\"ipfs://\")) {\n const cidPart = result.split(\"ipfs://\")[1];\n if (cidPart) {\n console.log(`CID: ${cidPart}`);\n }\n }\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Put envelope to Hubert server.\n *\n * Port of `put_server()` from bin/hubert.rs lines 324-344.\n */\nasync function putServer(\n host: string,\n port: number,\n arid: ARID,\n envelope: Envelope,\n ttl: number | undefined,\n verbose: boolean,\n): Promise<void> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n await store.put(arid, envelope, ttl, verbose);\n if (verbose) {\n verbosePrintln(\"✓ Stored envelope at ARID\");\n }\n}\n\n// =============================================================================\n// Get Functions\n// =============================================================================\n\n/**\n * Get envelope from Mainline DHT.\n *\n * Port of `get_mainline()` from bin/hubert.rs lines 252-262.\n */\nasync function getMainline(\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const store = await MainlineDhtKv.create();\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from IPFS.\n *\n * Port of `get_ipfs()` from bin/hubert.rs lines 264-276.\n */\nasync function getIpfs(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = new IpfsKv(url);\n return await store.get(arid, timeout, verbose);\n}\n\n/**\n * Get envelope from Hybrid storage.\n *\n * Port of `get_hybrid()` from bin/hubert.rs lines 310-322.\n */\nasync function getHybrid(\n arid: ARID,\n timeout: number,\n port: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://127.0.0.1:${port}`;\n const store = await HybridKv.create(url);\n try {\n return await store.get(arid, timeout, verbose);\n } finally {\n await store.destroy();\n }\n}\n\n/**\n * Get envelope from Hubert server.\n *\n * Port of `get_server()` from bin/hubert.rs lines 346-361.\n */\nasync function getServer(\n host: string,\n port: number,\n arid: ARID,\n timeout: number,\n verbose: boolean,\n): Promise<Envelope | null> {\n const url = `http://${host}:${port}`;\n const store = new ServerKvClient(url);\n return await store.get(arid, timeout, verbose);\n}\n\n// =============================================================================\n// CLI Setup\n// =============================================================================\n\nconst program = new Command();\n\nprogram\n .name(\"hubert\")\n .description(\"Distributed substrate for multiparty transactions\")\n .version(\"1.0.0-alpha.1\")\n .option(\"-v, --verbose\", \"Enable verbose logging\", false);\n\n// Generate command\nconst generateCmd = program\n .command(\"generate\")\n .description(\"Generate a new ARID or example Envelope\");\n\ngenerateCmd\n .command(\"arid\")\n .description(\"Generate a new ARID\")\n .action(() => {\n const arid = ARID.new();\n console.log(arid.urString());\n });\n\ngenerateCmd\n .command(\"envelope <size>\")\n .description(\"Generate a test envelope with random data\")\n .action((sizeStr: string) => {\n const size = parseInt(sizeStr, 10);\n if (isNaN(size) || size < 0) {\n console.error(\"Size must be a positive integer\");\n process.exit(1);\n }\n const envelope = generateRandomEnvelope(size);\n console.log(envelope.urString());\n });\n\n// Put command\nprogram\n .command(\"put <arid> <envelope>\")\n .description(\"Store an envelope at an ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"--ttl <seconds>\", \"Time-to-live in seconds (for --storage server)\")\n .option(\"--pin\", \"Pin content in IPFS (only for --storage ipfs or --storage hybrid)\", false)\n .action(\n async (\n aridStr: string,\n envelopeStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n ttl?: string;\n pin: boolean;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const ttl = options.ttl ? parseInt(options.ttl, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n if (ttl !== undefined) {\n throw new Error(\"--ttl option is only supported for --storage server\");\n }\n } else if (storage === \"server\") {\n if (options.pin) {\n throw new Error(\n \"--pin option is only supported for --storage ipfs or --storage hybrid\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n const envelope = parseEnvelope(envelopeStr);\n\n switch (storage) {\n case \"mainline\":\n await putMainline(arid, envelope, verbose);\n console.log(\"Stored in Mainline DHT\");\n break;\n case \"ipfs\":\n await putIpfs(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in IPFS\");\n break;\n case \"hybrid\":\n await putHybrid(arid, envelope, port ?? 5001, options.pin, verbose);\n console.log(\"Stored in Hybrid storage\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await putServer(host, port ?? 45678, arid, envelope, ttl, verbose);\n console.log(\"Stored in server\");\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Get command\nprogram\n .command(\"get <arid>\")\n .description(\"Retrieve an envelope by ARID\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .option(\"-t, --timeout <seconds>\", \"Maximum time to wait in seconds\", \"30\")\n .action(\n async (\n aridStr: string,\n options: {\n storage: StorageBackend;\n host?: string;\n port?: string;\n timeout: string;\n },\n ) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n const timeout = parseInt(options.timeout, 10);\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n const arid = parseArid(aridStr);\n\n let envelope: Envelope | null;\n switch (storage) {\n case \"mainline\":\n envelope = await getMainline(arid, timeout, verbose);\n break;\n case \"ipfs\":\n envelope = await getIpfs(arid, timeout, port ?? 5001, verbose);\n break;\n case \"hybrid\":\n envelope = await getHybrid(arid, timeout, port ?? 5001, verbose);\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n envelope = await getServer(host, port ?? 45678, arid, timeout, verbose);\n break;\n }\n }\n\n if (envelope) {\n console.log(envelope.urString());\n } else {\n throw new Error(`Value not found within ${timeout} seconds`);\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n },\n );\n\n// Check command\nprogram\n .command(\"check\")\n .description(\"Check if storage backend is available\")\n .option(\"-s, --storage <backend>\", \"Storage backend to use\", \"mainline\")\n .option(\"--host <host>\", \"Server host (for --storage server)\")\n .option(\"--port <port>\", \"Port (for --storage server/ipfs/hybrid)\")\n .action(async (options: { storage: StorageBackend; host?: string; port?: string }) => {\n const storage = options.storage;\n const port = options.port ? parseInt(options.port, 10) : undefined;\n\n try {\n // Validate options based on storage backend\n if (storage === \"mainline\") {\n if (port !== undefined) {\n throw new Error(\"--port option is not supported for --storage mainline\");\n }\n if (options.host !== undefined) {\n throw new Error(\"--host option is not supported for --storage mainline\");\n }\n } else if (storage === \"ipfs\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage ipfs (always uses 127.0.0.1)\",\n );\n }\n } else if (storage === \"hybrid\") {\n if (options.host !== undefined) {\n throw new Error(\n \"--host option is not supported for --storage hybrid (always uses 127.0.0.1)\",\n );\n }\n }\n\n switch (storage) {\n case \"mainline\":\n await checkMainline();\n break;\n case \"ipfs\":\n await checkIpfs(port ?? 5001);\n break;\n case \"hybrid\":\n await checkMainline();\n await checkIpfs(port ?? 5001);\n console.log(\"✓ Hybrid storage is available (DHT + IPFS)\");\n break;\n case \"server\": {\n const host = options.host ?? \"127.0.0.1\";\n await checkServer(host, port ?? 45678);\n break;\n }\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Server command\nprogram\n .command(\"server\")\n .description(\"Start the Hubert HTTP server\")\n .option(\"--port <port>\", \"Port for the server to listen on\", \"45678\")\n .option(\"--sqlite <path>\", \"SQLite database file path for persistent storage\")\n .action(async (options: { port: string; sqlite?: string }) => {\n const verbose = program.opts()[\"verbose\"] as boolean;\n const port = parseInt(options.port, 10);\n\n try {\n const config: ServerConfig = {\n port,\n maxTtl: 86400, // 24 hours\n verbose,\n };\n\n if (options.sqlite) {\n // Use SQLite storage\n let sqlitePath = options.sqlite;\n // Check if it's a directory\n const fs = await import(\"fs\");\n try {\n const stats = fs.statSync(sqlitePath);\n if (stats.isDirectory()) {\n sqlitePath = path.join(sqlitePath, \"hubert.sqlite\");\n }\n } catch {\n // Path doesn't exist, treat as file path\n }\n\n const store = new SqliteKv(sqlitePath);\n const server = Server.newSqlite(config, store);\n console.log(`Starting Hubert server on port ${port} with SQLite storage: ${sqlitePath}`);\n await server.run();\n } else {\n // Use in-memory storage\n const server = Server.newMemory(config);\n console.log(`Starting Hubert server on port ${port} with in-memory storage`);\n await server.run();\n }\n } catch (e) {\n console.error(e instanceof Error ? e.message : e);\n process.exit(1);\n }\n });\n\n// Parse and run\nprogram.parse();\n"],"mappings":"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"}
|
package/dist/hybrid/index.cjs
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
require('../
|
|
3
|
-
require('../kv-
|
|
4
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
require('../arid-derivation-CNfUKUp-.cjs');
|
|
3
|
+
require('../kv-1qBQRbV5.cjs');
|
|
4
|
+
require('../kv-BmCAYeR7.cjs');
|
|
5
|
+
const require_kv$2 = require('../kv-DfzRmYtR.cjs');
|
|
5
6
|
|
|
6
|
-
exports.ContentNotFoundError =
|
|
7
|
-
exports.HybridError =
|
|
8
|
-
exports.HybridKv =
|
|
9
|
-
exports.InvalidReferenceAridError =
|
|
10
|
-
exports.NoIdAssertionError =
|
|
11
|
-
exports.NotReferenceEnvelopeError =
|
|
12
|
-
exports.createReferenceEnvelope =
|
|
13
|
-
exports.extractReferenceArid =
|
|
14
|
-
exports.isReferenceEnvelope =
|
|
7
|
+
exports.ContentNotFoundError = require_kv$2.ContentNotFoundError;
|
|
8
|
+
exports.HybridError = require_kv$2.HybridError;
|
|
9
|
+
exports.HybridKv = require_kv$2.HybridKv;
|
|
10
|
+
exports.InvalidReferenceAridError = require_kv$2.InvalidReferenceAridError;
|
|
11
|
+
exports.NoIdAssertionError = require_kv$2.NoIdAssertionError;
|
|
12
|
+
exports.NotReferenceEnvelopeError = require_kv$2.NotReferenceEnvelopeError;
|
|
13
|
+
exports.createReferenceEnvelope = require_kv$2.createReferenceEnvelope;
|
|
14
|
+
exports.extractReferenceArid = require_kv$2.extractReferenceArid;
|
|
15
|
+
exports.isReferenceEnvelope = require_kv$2.isReferenceEnvelope;
|
package/dist/hybrid/index.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import "../kv-store-ww-AUyLd.cjs";
|
|
2
|
-
import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../
|
|
2
|
+
import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../kv-Bv__Pl2s.cjs";
|
|
3
3
|
export { ContentNotFoundError, HybridError, HybridKv, InvalidReferenceAridError, NoIdAssertionError, NotReferenceEnvelopeError, createReferenceEnvelope, extractReferenceArid, isReferenceEnvelope };
|
package/dist/hybrid/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import "../kv-store-
|
|
2
|
-
import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../
|
|
1
|
+
import "../kv-store-nL8CboDh.mjs";
|
|
2
|
+
import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../kv-BS5Z28iJ.mjs";
|
|
3
3
|
export { ContentNotFoundError, HybridError, HybridKv, InvalidReferenceAridError, NoIdAssertionError, NotReferenceEnvelopeError, createReferenceEnvelope, extractReferenceArid, isReferenceEnvelope };
|
package/dist/hybrid/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../arid-derivation-CbqACjdg.mjs";
|
|
2
2
|
import "../kv-DJiKvypY.mjs";
|
|
3
|
-
import "../kv-
|
|
4
|
-
import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../
|
|
3
|
+
import "../kv-DVYfnjvh.mjs";
|
|
4
|
+
import { a as ContentNotFoundError, c as NoIdAssertionError, i as isReferenceEnvelope, l as NotReferenceEnvelopeError, n as createReferenceEnvelope, o as HybridError, r as extractReferenceArid, s as InvalidReferenceAridError, t as HybridKv } from "../kv-CmxPWVB1.mjs";
|
|
5
5
|
|
|
6
6
|
export { ContentNotFoundError, HybridError, HybridKv, InvalidReferenceAridError, NoIdAssertionError, NotReferenceEnvelopeError, createReferenceEnvelope, extractReferenceArid, isReferenceEnvelope };
|