withub-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -26
- package/dist/commands/account.js +262 -63
- package/dist/commands/chain.js +35 -0
- package/dist/commands/checkout.js +137 -16
- package/dist/commands/clone.js +64 -7
- package/dist/commands/commit.js +4 -16
- package/dist/commands/fetch.js +76 -4
- package/dist/commands/init.js +75 -13
- package/dist/commands/invite.js +68 -53
- package/dist/commands/ipfsCar.js +98 -0
- package/dist/commands/lighthouse.js +97 -0
- package/dist/commands/lighthouseDownload.js +58 -0
- package/dist/commands/lighthousePin.js +62 -0
- package/dist/commands/pull.js +2 -1
- package/dist/commands/push.js +224 -8
- package/dist/commands/registerCommands.js +108 -2
- package/dist/commands/remove-user.js +46 -0
- package/dist/commands/removeUser.js +30 -1
- package/dist/index.js +15 -0
- package/dist/lib/chain.js +72 -0
- package/dist/lib/crypto.js +62 -0
- package/dist/lib/evmClone.js +255 -0
- package/dist/lib/evmKeys.js +218 -0
- package/dist/lib/evmProvider.js +88 -0
- package/dist/lib/evmRepo.js +192 -0
- package/dist/lib/ipfsCar.js +132 -0
- package/dist/lib/keccak.js +125 -0
- package/dist/lib/keys.js +102 -37
- package/dist/lib/lighthouse.js +661 -0
- package/dist/lib/lit.js +165 -0
- package/dist/lib/manifest.js +22 -4
- package/dist/lib/repo.js +94 -0
- package/dist/lib/schema.js +26 -6
- package/dist/lib/walrus.js +11 -1
- package/package.json +17 -2
package/dist/commands/invite.js
CHANGED
|
@@ -2,71 +2,86 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.inviteAction = inviteAction;
|
|
4
4
|
const client_1 = require("@mysten/sui/client");
|
|
5
|
-
const ui_1 = require("../lib/ui");
|
|
6
|
-
const repo_1 = require("../lib/repo");
|
|
7
|
-
const walrus_1 = require("../lib/walrus");
|
|
8
5
|
const keys_1 = require("../lib/keys");
|
|
6
|
+
const walrus_1 = require("../lib/walrus");
|
|
9
7
|
const suiRepo_1 = require("../lib/suiRepo");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
console.log(ui_1.colors.header('Adding collaborator...'));
|
|
16
|
-
let witPath;
|
|
8
|
+
const evmRepo_1 = require("../lib/evmRepo");
|
|
9
|
+
const evmProvider_1 = require("../lib/evmProvider");
|
|
10
|
+
const repo_1 = require("../lib/repo");
|
|
11
|
+
const ui_1 = require("../lib/ui");
|
|
12
|
+
async function inviteAction(address, options) {
|
|
17
13
|
try {
|
|
18
|
-
witPath = await (0, repo_1.requireWitDir)();
|
|
14
|
+
const witPath = await (0, repo_1.requireWitDir)();
|
|
15
|
+
const repoCfg = await (0, repo_1.readRepoConfig)(witPath);
|
|
16
|
+
if (repoCfg.chain !== 'mantle') {
|
|
17
|
+
// SUI Logic (Default)
|
|
18
|
+
return inviteActionSui(address, options, repoCfg);
|
|
19
|
+
}
|
|
20
|
+
// Mantle Logic
|
|
21
|
+
let repoIdStr = options.repo || repoCfg.repo_id;
|
|
22
|
+
if (!repoIdStr) {
|
|
23
|
+
// eslint-disable-next-line no-console
|
|
24
|
+
console.error(ui_1.colors.red('Error: Repository ID is required. Run inside a wit repo or use --repo <id>.'));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
if (repoCfg.isPrivate === false) {
|
|
28
|
+
console.log(ui_1.colors.yellow('Warning: This repository is public. Collaborators are not needed for read access (but may be needed for write access).'));
|
|
29
|
+
}
|
|
30
|
+
if (repoIdStr.startsWith('mantle:')) {
|
|
31
|
+
repoIdStr = repoIdStr.split(':').pop();
|
|
32
|
+
}
|
|
33
|
+
const repoId = BigInt(repoIdStr);
|
|
34
|
+
// 2. Connect to Mantle
|
|
35
|
+
const signerCtx = await (0, evmProvider_1.loadMantleSigner)();
|
|
36
|
+
const repoService = new evmRepo_1.EvmRepoService(signerCtx);
|
|
37
|
+
// 3. Add Collaborator
|
|
38
|
+
await repoService.addCollaborator(repoId, address);
|
|
19
39
|
}
|
|
20
40
|
catch (err) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return;
|
|
41
|
+
console.error(ui_1.colors.red(`Command failed: ${err.message}`));
|
|
42
|
+
process.exit(1);
|
|
24
43
|
}
|
|
25
|
-
|
|
44
|
+
}
|
|
45
|
+
async function inviteActionSui(address, options, repoCfg) {
|
|
26
46
|
if (!repoCfg.repo_id) {
|
|
27
|
-
throw new Error('
|
|
47
|
+
throw new Error('Repository not initialized on chain. Run `wit push` first.');
|
|
28
48
|
}
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
49
|
+
const signer = await (0, keys_1.loadSigner)();
|
|
50
|
+
const signerAddr = signer.address;
|
|
51
|
+
console.log(ui_1.colors.header(`Adding collaborator ${address} to ${repoCfg.repo_id}...`));
|
|
52
|
+
const res = await (0, keys_1.checkResources)(signerAddr);
|
|
53
|
+
if (res.hasMinSui === false) {
|
|
54
|
+
throw new Error(`Insufficient SUI balance. Need at least ${res.minSui} MIST.`);
|
|
55
|
+
}
|
|
56
|
+
const config = await (0, walrus_1.resolveWalrusConfig)();
|
|
57
|
+
const client = new client_1.SuiClient({ url: config.suiRpcUrl });
|
|
34
58
|
let whitelistId;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
59
|
+
// Attempt to auto-detect if private
|
|
60
|
+
if (repoCfg.seal_policy_id) {
|
|
61
|
+
whitelistId = repoCfg.seal_policy_id;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
try {
|
|
65
|
+
const state = await (0, suiRepo_1.fetchRepositoryState)(client, repoCfg.repo_id);
|
|
66
|
+
if (state.sealPolicyId) {
|
|
67
|
+
whitelistId = state.sealPolicyId;
|
|
43
68
|
}
|
|
44
69
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// ignore fetch error, assume public or will fail later
|
|
48
|
-
}
|
|
49
|
-
try {
|
|
50
|
-
await (0, suiRepo_1.addCollaborator)(suiClient, signerInfo.signer, {
|
|
51
|
-
repoId: repoCfg.repo_id,
|
|
52
|
-
collaborator: address,
|
|
53
|
-
whitelistId
|
|
54
|
-
});
|
|
55
|
-
// eslint-disable-next-line no-console
|
|
56
|
-
console.log(ui_1.colors.green(`Added ${ui_1.colors.hash(address)} as collaborator.`));
|
|
57
|
-
if (whitelistId) {
|
|
58
|
-
// eslint-disable-next-line no-console
|
|
59
|
-
console.log(ui_1.colors.cyan(`User added to Whitelist (${whitelistId}). They can now decrypt the repository.`));
|
|
70
|
+
catch (err) {
|
|
71
|
+
// ignore
|
|
60
72
|
}
|
|
61
73
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
// Allow override
|
|
75
|
+
if (options.sealPolicy) {
|
|
76
|
+
whitelistId = options.sealPolicy;
|
|
77
|
+
}
|
|
78
|
+
await (0, suiRepo_1.addCollaborator)(client, signer.signer, {
|
|
79
|
+
repoId: repoCfg.repo_id,
|
|
80
|
+
collaborator: address,
|
|
81
|
+
whitelistId
|
|
82
|
+
});
|
|
83
|
+
console.log(ui_1.colors.green(`Collaborator ${address} added successfully.`));
|
|
84
|
+
if (whitelistId) {
|
|
85
|
+
console.log(ui_1.colors.gray(`(Added to private whitelist ${whitelistId})`));
|
|
71
86
|
}
|
|
72
87
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.carPackAction = carPackAction;
|
|
7
|
+
exports.carUnpackAction = carUnpackAction;
|
|
8
|
+
exports.carMapAction = carMapAction;
|
|
9
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const ui_1 = require("../lib/ui");
|
|
12
|
+
const ipfsCar_1 = require("../lib/ipfsCar");
|
|
13
|
+
async function carPackAction(input, opts) {
|
|
14
|
+
try {
|
|
15
|
+
if (!input) {
|
|
16
|
+
printError('Input path is required. Usage: wit car-pack <input> --out <file.car>');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const absInput = path_1.default.resolve(input);
|
|
20
|
+
const output = resolveOutputPath(absInput, opts.out);
|
|
21
|
+
const result = await (0, ipfsCar_1.packCar)(absInput, output, { wrap: opts.wrap !== false });
|
|
22
|
+
if (opts.rootOut) {
|
|
23
|
+
await promises_1.default.writeFile(path_1.default.resolve(opts.rootOut), `${result.root}\n`, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line no-console
|
|
26
|
+
console.log(ui_1.colors.green('CAR snapshot created.'));
|
|
27
|
+
// eslint-disable-next-line no-console
|
|
28
|
+
console.log(` root: ${ui_1.colors.hash(result.root)}`);
|
|
29
|
+
// eslint-disable-next-line no-console
|
|
30
|
+
console.log(` output: ${result.output}`);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
printError(errorMessage(err));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function carUnpackAction(carFile, outDir) {
|
|
37
|
+
try {
|
|
38
|
+
if (!carFile || !outDir) {
|
|
39
|
+
printError('CAR file and output directory are required. Usage: wit car-unpack <file.car> <out_dir>');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
await (0, ipfsCar_1.unpackCar)(carFile, outDir);
|
|
43
|
+
// eslint-disable-next-line no-console
|
|
44
|
+
console.log(ui_1.colors.green('CAR snapshot unpacked.'));
|
|
45
|
+
// eslint-disable-next-line no-console
|
|
46
|
+
console.log(` input: ${path_1.default.resolve(carFile)}`);
|
|
47
|
+
// eslint-disable-next-line no-console
|
|
48
|
+
console.log(` output: ${path_1.default.resolve(outDir)}`);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
printError(errorMessage(err));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async function carMapAction(carFile, opts) {
|
|
55
|
+
try {
|
|
56
|
+
if (!carFile) {
|
|
57
|
+
printError('CAR file is required. Usage: wit car-map <file.car> --out <path>');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const result = await (0, ipfsCar_1.mapCarPaths)(carFile, { stripRoot: opts.stripRoot !== false });
|
|
61
|
+
const payload = JSON.stringify(result.map, null, 2) + '\n';
|
|
62
|
+
if (opts.out) {
|
|
63
|
+
const outPath = path_1.default.resolve(opts.out);
|
|
64
|
+
await promises_1.default.writeFile(outPath, payload, 'utf8');
|
|
65
|
+
// eslint-disable-next-line no-console
|
|
66
|
+
console.log(ui_1.colors.green('CAR path map written.'));
|
|
67
|
+
// eslint-disable-next-line no-console
|
|
68
|
+
console.log(` root: ${ui_1.colors.hash(result.root)}`);
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.log(` output: ${outPath}`);
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.log(` entries: ${Object.keys(result.map).length}`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// eslint-disable-next-line no-console
|
|
76
|
+
console.log(payload.trimEnd());
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
printError(errorMessage(err));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function resolveOutputPath(input, out) {
|
|
84
|
+
if (out)
|
|
85
|
+
return path_1.default.resolve(out);
|
|
86
|
+
const base = path_1.default.basename(input === '.' ? process.cwd() : input);
|
|
87
|
+
return path_1.default.resolve(`${base}.car`);
|
|
88
|
+
}
|
|
89
|
+
function printError(message) {
|
|
90
|
+
// eslint-disable-next-line no-console
|
|
91
|
+
console.error(ui_1.colors.red(message));
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
}
|
|
94
|
+
function errorMessage(err) {
|
|
95
|
+
if (err instanceof Error && err.message)
|
|
96
|
+
return err.message;
|
|
97
|
+
return String(err);
|
|
98
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.lighthouseUploadAction = lighthouseUploadAction;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const ui_1 = require("../lib/ui");
|
|
9
|
+
const lighthouse_1 = require("../lib/lighthouse");
|
|
10
|
+
async function lighthouseUploadAction(filePath, opts) {
|
|
11
|
+
try {
|
|
12
|
+
if (!filePath) {
|
|
13
|
+
printError('File path is required. Usage: wit lighthouse-upload <file>');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const apiKey = (0, lighthouse_1.resolveLighthouseApiKey)();
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
printError('Missing LIGHTHOUSE_API_KEY. Set it in .env, ~/.witconfig, or export it before running this command.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const cidVersion = parseCidVersion(opts.cidVersion);
|
|
22
|
+
const retries = parseOptionalNumber(opts.retries, 3);
|
|
23
|
+
const retryDelay = parseOptionalNumber(opts.retryDelay, 1000);
|
|
24
|
+
const absPath = path_1.default.resolve(filePath);
|
|
25
|
+
const progress = opts.progress ? createProgressReporter() : undefined;
|
|
26
|
+
const totalAttempts = retries + 1;
|
|
27
|
+
const result = await (0, lighthouse_1.uploadFileToLighthouse)(absPath, {
|
|
28
|
+
apiKey,
|
|
29
|
+
cidVersion,
|
|
30
|
+
onProgress: progress,
|
|
31
|
+
useCache: opts.cache !== false,
|
|
32
|
+
retries,
|
|
33
|
+
retryDelayMs: retryDelay,
|
|
34
|
+
onRetry: (attempt, err, delayMs) => {
|
|
35
|
+
const message = err?.message || String(err);
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.warn(ui_1.colors.yellow(`Upload attempt ${attempt}/${totalAttempts} failed: ${message}. Retrying in ${delayMs}ms...`));
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
if (progress && !result.fromCache)
|
|
41
|
+
progress(100);
|
|
42
|
+
// eslint-disable-next-line no-console
|
|
43
|
+
console.log(ui_1.colors.green(result.fromCache ? 'Cache hit. Using existing Lighthouse CID.' : 'Uploaded to Lighthouse.'));
|
|
44
|
+
// eslint-disable-next-line no-console
|
|
45
|
+
console.log(` cid: ${ui_1.colors.hash(result.cid)}`);
|
|
46
|
+
// eslint-disable-next-line no-console
|
|
47
|
+
console.log(` name: ${result.name ?? path_1.default.basename(absPath)}`);
|
|
48
|
+
if (result.size) {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.log(` size: ${result.size}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
printError(errorMessage(err));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function parseCidVersion(value) {
|
|
58
|
+
if (value === undefined || value === null)
|
|
59
|
+
return 1;
|
|
60
|
+
if (typeof value === 'number')
|
|
61
|
+
return Number.isNaN(value) ? 1 : value;
|
|
62
|
+
const parsed = Number.parseInt(value, 10);
|
|
63
|
+
return Number.isNaN(parsed) ? 1 : parsed;
|
|
64
|
+
}
|
|
65
|
+
function parseOptionalNumber(value, fallback) {
|
|
66
|
+
if (value === undefined || value === null)
|
|
67
|
+
return fallback;
|
|
68
|
+
if (typeof value === 'number')
|
|
69
|
+
return Number.isNaN(value) ? fallback : value;
|
|
70
|
+
const parsed = Number.parseInt(value, 10);
|
|
71
|
+
return Number.isNaN(parsed) ? fallback : parsed;
|
|
72
|
+
}
|
|
73
|
+
function createProgressReporter() {
|
|
74
|
+
let last = -1;
|
|
75
|
+
return (progress) => {
|
|
76
|
+
const value = Math.max(0, Math.min(100, Math.round(progress)));
|
|
77
|
+
if (value === last)
|
|
78
|
+
return;
|
|
79
|
+
last = value;
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
process.stdout.write(`\rUploading... ${value}%`);
|
|
82
|
+
if (value === 100) {
|
|
83
|
+
// eslint-disable-next-line no-console
|
|
84
|
+
process.stdout.write('\n');
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function printError(message) {
|
|
89
|
+
// eslint-disable-next-line no-console
|
|
90
|
+
console.error(ui_1.colors.red(message));
|
|
91
|
+
process.exitCode = 1;
|
|
92
|
+
}
|
|
93
|
+
function errorMessage(err) {
|
|
94
|
+
if (err instanceof Error && err.message)
|
|
95
|
+
return err.message;
|
|
96
|
+
return String(err);
|
|
97
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.lighthouseDownloadAction = lighthouseDownloadAction;
|
|
7
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const ui_1 = require("../lib/ui");
|
|
10
|
+
const lighthouse_1 = require("../lib/lighthouse");
|
|
11
|
+
async function lighthouseDownloadAction(cid, opts) {
|
|
12
|
+
try {
|
|
13
|
+
if (!cid) {
|
|
14
|
+
printError('CID is required. Usage: wit lighthouse-download <cid> --out <path>');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const format = opts.car ? 'car' : 'raw';
|
|
18
|
+
const output = resolveOutputPath(cid, format, opts.out);
|
|
19
|
+
const gateway = opts.gateway || (0, lighthouse_1.resolveLighthouseGatewayUrl)();
|
|
20
|
+
const result = await (0, lighthouse_1.downloadFromLighthouseGateway)(cid, {
|
|
21
|
+
format,
|
|
22
|
+
verify: opts.verify !== false,
|
|
23
|
+
retries: opts.retries,
|
|
24
|
+
retryDelayMs: opts.retryDelay,
|
|
25
|
+
timeoutMs: opts.timeout,
|
|
26
|
+
gatewayUrl: gateway,
|
|
27
|
+
});
|
|
28
|
+
await promises_1.default.mkdir(path_1.default.dirname(output), { recursive: true });
|
|
29
|
+
await promises_1.default.writeFile(output, result.bytes);
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.log(ui_1.colors.green('Downloaded from Lighthouse.'));
|
|
32
|
+
// eslint-disable-next-line no-console
|
|
33
|
+
console.log(` cid: ${ui_1.colors.hash(cid)}`);
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log(` gateway: ${result.gateway}`);
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.log(` output: ${output}`);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
printError(errorMessage(err));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function resolveOutputPath(cid, format, out) {
|
|
44
|
+
if (out)
|
|
45
|
+
return path_1.default.resolve(out);
|
|
46
|
+
const suffix = format === 'car' ? '.car' : '';
|
|
47
|
+
return path_1.default.resolve(`${cid}${suffix}`);
|
|
48
|
+
}
|
|
49
|
+
function printError(message) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.error(ui_1.colors.red(message));
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
}
|
|
54
|
+
function errorMessage(err) {
|
|
55
|
+
if (err instanceof Error && err.message)
|
|
56
|
+
return err.message;
|
|
57
|
+
return String(err);
|
|
58
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.lighthousePinAction = lighthousePinAction;
|
|
4
|
+
const ui_1 = require("../lib/ui");
|
|
5
|
+
const lighthouse_1 = require("../lib/lighthouse");
|
|
6
|
+
async function lighthousePinAction(cid, opts) {
|
|
7
|
+
try {
|
|
8
|
+
if (!cid) {
|
|
9
|
+
printError('CID is required. Usage: wit lighthouse-pin <cid>');
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const apiKey = (0, lighthouse_1.resolveLighthouseApiKey)();
|
|
13
|
+
if (!apiKey) {
|
|
14
|
+
printError('Missing LIGHTHOUSE_API_KEY. Set it in .env, ~/.witconfig, or export it before running this command.');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const pinUrl = opts.pinUrl || (0, lighthouse_1.resolveLighthousePinUrl)() || undefined;
|
|
18
|
+
const retries = parseOptionalNumber(opts.retries, 3);
|
|
19
|
+
const retryDelay = parseOptionalNumber(opts.retryDelay, 1000);
|
|
20
|
+
const timeout = parseOptionalNumber(opts.timeout, 30000);
|
|
21
|
+
const totalAttempts = retries + 1;
|
|
22
|
+
const result = await (0, lighthouse_1.pinCidWithLighthouse)(cid, {
|
|
23
|
+
apiKey,
|
|
24
|
+
pinUrl,
|
|
25
|
+
retries,
|
|
26
|
+
retryDelayMs: retryDelay,
|
|
27
|
+
timeoutMs: timeout,
|
|
28
|
+
onRetry: (attempt, err, delayMs) => {
|
|
29
|
+
const message = err?.message || String(err);
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.warn(ui_1.colors.yellow(`Pin attempt ${attempt}/${totalAttempts} failed: ${message}. Retrying in ${delayMs}ms...`));
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
// eslint-disable-next-line no-console
|
|
35
|
+
console.log(ui_1.colors.green('Pinned on Lighthouse.'));
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.log(` cid: ${ui_1.colors.hash(result.cid)}`);
|
|
38
|
+
// eslint-disable-next-line no-console
|
|
39
|
+
console.log(` pin url: ${result.pinUrl}`);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
printError(errorMessage(err));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function parseOptionalNumber(value, fallback) {
|
|
46
|
+
if (value === undefined || value === null)
|
|
47
|
+
return fallback;
|
|
48
|
+
if (typeof value === 'number')
|
|
49
|
+
return Number.isNaN(value) ? fallback : value;
|
|
50
|
+
const parsed = Number.parseInt(value, 10);
|
|
51
|
+
return Number.isNaN(parsed) ? fallback : parsed;
|
|
52
|
+
}
|
|
53
|
+
function printError(message) {
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
console.error(ui_1.colors.red(message));
|
|
56
|
+
process.exitCode = 1;
|
|
57
|
+
}
|
|
58
|
+
function errorMessage(err) {
|
|
59
|
+
if (err instanceof Error && err.message)
|
|
60
|
+
return err.message;
|
|
61
|
+
return String(err);
|
|
62
|
+
}
|
package/dist/commands/pull.js
CHANGED
|
@@ -14,6 +14,7 @@ const state_1 = require("../lib/state");
|
|
|
14
14
|
const fs_1 = require("../lib/fs");
|
|
15
15
|
const schema_1 = require("../lib/schema");
|
|
16
16
|
const manifest_1 = require("../lib/manifest");
|
|
17
|
+
const serialize_1 = require("../lib/serialize");
|
|
17
18
|
const walrus_1 = require("../lib/walrus");
|
|
18
19
|
async function pullAction() {
|
|
19
20
|
// eslint-disable-next-line no-console
|
|
@@ -156,5 +157,5 @@ function manifestIdToFile(id) {
|
|
|
156
157
|
return id.replace(/\//g, '_').replace(/\+/g, '-');
|
|
157
158
|
}
|
|
158
159
|
function canonicalManifest(m) {
|
|
159
|
-
return
|
|
160
|
+
return (0, serialize_1.canonicalStringify)(m);
|
|
160
161
|
}
|