pinme 2.0.2-beta.2 → 2.0.2-beta.3
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 +27 -22
- package/dist/index.js +1407 -1322
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1033,7 +1033,7 @@ var require_debug = __commonJS({
|
|
|
1033
1033
|
var require_follow_redirects = __commonJS({
|
|
1034
1034
|
"node_modules/.pnpm/follow-redirects@1.15.2/node_modules/follow-redirects/index.js"(exports2, module2) {
|
|
1035
1035
|
var url2 = require("url");
|
|
1036
|
-
var
|
|
1036
|
+
var URL3 = url2.URL;
|
|
1037
1037
|
var http3 = require("http");
|
|
1038
1038
|
var https2 = require("https");
|
|
1039
1039
|
var Writable = require("stream").Writable;
|
|
@@ -1367,7 +1367,7 @@ var require_follow_redirects = __commonJS({
|
|
|
1367
1367
|
if (isString2(input)) {
|
|
1368
1368
|
var parsed;
|
|
1369
1369
|
try {
|
|
1370
|
-
parsed = urlToOptions(new
|
|
1370
|
+
parsed = urlToOptions(new URL3(input));
|
|
1371
1371
|
} catch (err) {
|
|
1372
1372
|
parsed = url2.parse(input);
|
|
1373
1373
|
}
|
|
@@ -1375,7 +1375,7 @@ var require_follow_redirects = __commonJS({
|
|
|
1375
1375
|
throw new InvalidUrlError({ input });
|
|
1376
1376
|
}
|
|
1377
1377
|
input = parsed;
|
|
1378
|
-
} else if (
|
|
1378
|
+
} else if (URL3 && input instanceof URL3) {
|
|
1379
1379
|
input = urlToOptions(input);
|
|
1380
1380
|
} else {
|
|
1381
1381
|
callback = options;
|
|
@@ -1519,17 +1519,21 @@ function checkNodeVersion() {
|
|
|
1519
1519
|
|
|
1520
1520
|
// bin/index.ts
|
|
1521
1521
|
var import_commander = require("commander");
|
|
1522
|
-
var
|
|
1522
|
+
var import_chalk25 = __toESM(require("chalk"));
|
|
1523
1523
|
var import_figlet5 = __toESM(require("figlet"));
|
|
1524
1524
|
|
|
1525
1525
|
// package.json
|
|
1526
|
-
var version = "2.0.2-beta.
|
|
1526
|
+
var version = "2.0.2-beta.3";
|
|
1527
1527
|
|
|
1528
1528
|
// bin/upload.ts
|
|
1529
1529
|
var import_path7 = __toESM(require("path"));
|
|
1530
1530
|
var import_chalk5 = __toESM(require("chalk"));
|
|
1531
1531
|
var import_inquirer = __toESM(require("inquirer"));
|
|
1532
1532
|
var import_figlet = __toESM(require("figlet"));
|
|
1533
|
+
var import_fs2 = __toESM(require("fs"));
|
|
1534
|
+
|
|
1535
|
+
// bin/utils/pinmeApi.ts
|
|
1536
|
+
var import_chalk3 = __toESM(require("chalk"));
|
|
1533
1537
|
|
|
1534
1538
|
// node_modules/.pnpm/axios@1.3.2/node_modules/axios/lib/helpers/bind.js
|
|
1535
1539
|
function bind(fn, thisArg) {
|
|
@@ -4398,201 +4402,60 @@ var {
|
|
|
4398
4402
|
mergeConfig: mergeConfig2
|
|
4399
4403
|
} = axios_default;
|
|
4400
4404
|
|
|
4401
|
-
// bin/utils/
|
|
4402
|
-
var
|
|
4403
|
-
var
|
|
4404
|
-
var
|
|
4405
|
-
var
|
|
4406
|
-
var
|
|
4407
|
-
|
|
4408
|
-
// bin/utils/uploadLimits.ts
|
|
4409
|
-
var import_fs = __toESM(require("fs"));
|
|
4410
|
-
var import_path = __toESM(require("path"));
|
|
4411
|
-
var FILE_SIZE_LIMIT = parseInt("500", 10) * 1024 * 1024;
|
|
4412
|
-
var DIRECTORY_SIZE_LIMIT = parseInt("500", 10) * 1024 * 1024;
|
|
4413
|
-
function checkFileSizeLimit(filePath) {
|
|
4414
|
-
const stats = import_fs.default.statSync(filePath);
|
|
4415
|
-
return {
|
|
4416
|
-
size: stats.size,
|
|
4417
|
-
limit: FILE_SIZE_LIMIT,
|
|
4418
|
-
exceeds: stats.size > FILE_SIZE_LIMIT
|
|
4419
|
-
};
|
|
4420
|
-
}
|
|
4421
|
-
function checkDirectorySizeLimit(directoryPath) {
|
|
4422
|
-
const totalSize = calculateDirectorySize(directoryPath);
|
|
4423
|
-
return {
|
|
4424
|
-
size: totalSize,
|
|
4425
|
-
limit: DIRECTORY_SIZE_LIMIT,
|
|
4426
|
-
exceeds: totalSize > DIRECTORY_SIZE_LIMIT
|
|
4427
|
-
};
|
|
4428
|
-
}
|
|
4429
|
-
function calculateDirectorySize(directoryPath) {
|
|
4430
|
-
let totalSize = 0;
|
|
4431
|
-
const files = import_fs.default.readdirSync(directoryPath);
|
|
4432
|
-
for (const file of files) {
|
|
4433
|
-
const filePath = import_path.default.join(directoryPath, file);
|
|
4434
|
-
const stats = import_fs.default.statSync(filePath);
|
|
4435
|
-
if (stats.isFile()) {
|
|
4436
|
-
totalSize += stats.size;
|
|
4437
|
-
} else if (stats.isDirectory()) {
|
|
4438
|
-
totalSize += calculateDirectorySize(filePath);
|
|
4439
|
-
}
|
|
4440
|
-
}
|
|
4441
|
-
return totalSize;
|
|
4442
|
-
}
|
|
4443
|
-
function formatSize(bytes) {
|
|
4444
|
-
if (bytes < 1024) return bytes + " bytes";
|
|
4445
|
-
else if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + " KB";
|
|
4446
|
-
else if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + " MB";
|
|
4447
|
-
else return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB";
|
|
4448
|
-
}
|
|
4449
|
-
|
|
4450
|
-
// bin/utils/history.ts
|
|
4405
|
+
// bin/utils/webLogin.ts
|
|
4406
|
+
var import_crypto = __toESM(require("crypto"));
|
|
4407
|
+
var import_http3 = __toESM(require("http"));
|
|
4408
|
+
var import_url2 = require("url");
|
|
4409
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
4410
|
+
var import_child_process = require("child_process");
|
|
4451
4411
|
var import_fs_extra = __toESM(require("fs-extra"));
|
|
4452
|
-
var import_path2 = __toESM(require("path"));
|
|
4453
4412
|
var import_os = __toESM(require("os"));
|
|
4454
|
-
var
|
|
4455
|
-
var import_chalk2 = __toESM(require("chalk"));
|
|
4456
|
-
var HISTORY_DIR = import_path2.default.join(import_os.default.homedir(), ".pinme");
|
|
4457
|
-
var HISTORY_FILE = import_path2.default.join(HISTORY_DIR, "upload-history.json");
|
|
4458
|
-
var ensureHistoryDir = () => {
|
|
4459
|
-
if (!import_fs_extra.default.existsSync(HISTORY_DIR)) {
|
|
4460
|
-
import_fs_extra.default.mkdirSync(HISTORY_DIR, { recursive: true });
|
|
4461
|
-
}
|
|
4462
|
-
if (!import_fs_extra.default.existsSync(HISTORY_FILE)) {
|
|
4463
|
-
import_fs_extra.default.writeJsonSync(HISTORY_FILE, { uploads: [] });
|
|
4464
|
-
}
|
|
4465
|
-
};
|
|
4466
|
-
var saveUploadHistory = (uploadData) => {
|
|
4467
|
-
try {
|
|
4468
|
-
ensureHistoryDir();
|
|
4469
|
-
const history = import_fs_extra.default.readJsonSync(HISTORY_FILE);
|
|
4470
|
-
const newRecord = {
|
|
4471
|
-
timestamp: Date.now(),
|
|
4472
|
-
date: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
4473
|
-
path: uploadData.path,
|
|
4474
|
-
filename: uploadData.filename || import_path2.default.basename(uploadData.path),
|
|
4475
|
-
contentHash: uploadData.contentHash,
|
|
4476
|
-
previewHash: uploadData.previewHash,
|
|
4477
|
-
size: uploadData.size,
|
|
4478
|
-
fileCount: uploadData.fileCount || 1,
|
|
4479
|
-
type: uploadData.isDirectory ? "directory" : "file",
|
|
4480
|
-
shortUrl: (uploadData == null ? void 0 : uploadData.shortUrl) || null
|
|
4481
|
-
};
|
|
4482
|
-
history.uploads.unshift(newRecord);
|
|
4483
|
-
import_fs_extra.default.writeJsonSync(HISTORY_FILE, history, { spaces: 2 });
|
|
4484
|
-
return true;
|
|
4485
|
-
} catch (error) {
|
|
4486
|
-
console.error(import_chalk2.default.red(`Error saving upload history: ${error.message}`));
|
|
4487
|
-
return false;
|
|
4488
|
-
}
|
|
4489
|
-
};
|
|
4490
|
-
var getUploadHistory = (limit = 10) => {
|
|
4491
|
-
try {
|
|
4492
|
-
ensureHistoryDir();
|
|
4493
|
-
const history = import_fs_extra.default.readJsonSync(HISTORY_FILE);
|
|
4494
|
-
return history.uploads.slice(0, limit);
|
|
4495
|
-
} catch (error) {
|
|
4496
|
-
console.error(import_chalk2.default.red(`Error reading upload history: ${error.message}`));
|
|
4497
|
-
return [];
|
|
4498
|
-
}
|
|
4499
|
-
};
|
|
4500
|
-
var displayUploadHistory = (limit = 10) => {
|
|
4501
|
-
const history = getUploadHistory(limit);
|
|
4502
|
-
if (history.length === 0) {
|
|
4503
|
-
console.log(import_chalk2.default.yellow("No upload history found."));
|
|
4504
|
-
return;
|
|
4505
|
-
}
|
|
4506
|
-
console.log(import_chalk2.default.cyan("Upload History:"));
|
|
4507
|
-
console.log(import_chalk2.default.cyan("-".repeat(80)));
|
|
4508
|
-
const recentHistory = history.slice(-limit);
|
|
4509
|
-
recentHistory.forEach((item, index) => {
|
|
4510
|
-
console.log(import_chalk2.default.green(`${index + 1}. ${item.filename}`));
|
|
4511
|
-
console.log(import_chalk2.default.white(` Path: ${item.path}`));
|
|
4512
|
-
console.log(import_chalk2.default.white(` IPFS CID: ${item.contentHash}`));
|
|
4513
|
-
if (item.shortUrl) {
|
|
4514
|
-
console.log(import_chalk2.default.white(` ENS URL: https://${item.shortUrl}.pinit.eth.limo`));
|
|
4515
|
-
}
|
|
4516
|
-
console.log(import_chalk2.default.white(` Size: ${formatSize(item.size)}`));
|
|
4517
|
-
console.log(import_chalk2.default.white(` Files: ${item.fileCount}`));
|
|
4518
|
-
console.log(import_chalk2.default.white(` Type: ${item.type === "directory" ? "Directory" : "File"}`));
|
|
4519
|
-
if (item.timestamp) {
|
|
4520
|
-
console.log(import_chalk2.default.white(` Date: ${new Date(item.timestamp).toLocaleString()}`));
|
|
4521
|
-
}
|
|
4522
|
-
console.log(import_chalk2.default.cyan("-".repeat(80)));
|
|
4523
|
-
});
|
|
4524
|
-
const totalSize = history.reduce((sum, record) => sum + record.size, 0);
|
|
4525
|
-
const totalFiles = history.reduce((sum, record) => sum + record.fileCount, 0);
|
|
4526
|
-
console.log(import_chalk2.default.bold(`Total Uploads: ${history.length}`));
|
|
4527
|
-
console.log(import_chalk2.default.bold(`Total Files: ${totalFiles}`));
|
|
4528
|
-
console.log(import_chalk2.default.bold(`Total Size: ${formatSize(totalSize)}`));
|
|
4529
|
-
};
|
|
4530
|
-
var clearUploadHistory = () => {
|
|
4531
|
-
try {
|
|
4532
|
-
ensureHistoryDir();
|
|
4533
|
-
import_fs_extra.default.writeJsonSync(HISTORY_FILE, { uploads: [] });
|
|
4534
|
-
console.log(import_chalk2.default.green("Upload history cleared successfully."));
|
|
4535
|
-
return true;
|
|
4536
|
-
} catch (error) {
|
|
4537
|
-
console.error(import_chalk2.default.red(`Error clearing upload history: ${error.message}`));
|
|
4538
|
-
return false;
|
|
4539
|
-
}
|
|
4540
|
-
};
|
|
4541
|
-
|
|
4542
|
-
// bin/utils/getDeviceId.ts
|
|
4543
|
-
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
4544
|
-
var import_path4 = __toESM(require("path"));
|
|
4545
|
-
var import_os3 = __toESM(require("os"));
|
|
4546
|
-
var import_uuid = require("uuid");
|
|
4547
|
-
|
|
4548
|
-
// bin/utils/auth.ts
|
|
4549
|
-
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
4550
|
-
var import_os2 = __toESM(require("os"));
|
|
4551
|
-
var import_path3 = __toESM(require("path"));
|
|
4552
|
-
var CONFIG_DIR = import_path3.default.join(import_os2.default.homedir(), ".pinme");
|
|
4553
|
-
var AUTH_FILE = import_path3.default.join(CONFIG_DIR, "auth.json");
|
|
4554
|
-
function getAuthConfig() {
|
|
4555
|
-
try {
|
|
4556
|
-
if (!import_fs_extra2.default.existsSync(AUTH_FILE)) return null;
|
|
4557
|
-
const data = import_fs_extra2.default.readJsonSync(AUTH_FILE);
|
|
4558
|
-
if (!(data == null ? void 0 : data.address) || !(data == null ? void 0 : data.token)) return null;
|
|
4559
|
-
return data;
|
|
4560
|
-
} catch {
|
|
4561
|
-
return null;
|
|
4562
|
-
}
|
|
4563
|
-
}
|
|
4413
|
+
var import_path = __toESM(require("path"));
|
|
4564
4414
|
|
|
4565
|
-
// bin/utils/
|
|
4566
|
-
function
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4415
|
+
// bin/utils/config.ts
|
|
4416
|
+
function trimTrailingSlash(value) {
|
|
4417
|
+
return value.replace(/\/+$/, "");
|
|
4418
|
+
}
|
|
4419
|
+
function readNumberEnv(name, fallback) {
|
|
4420
|
+
const rawValue = process.env[name];
|
|
4421
|
+
if (!rawValue) {
|
|
4422
|
+
return fallback;
|
|
4423
|
+
}
|
|
4424
|
+
const parsed = Number.parseInt(rawValue, 10);
|
|
4425
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
4426
|
+
}
|
|
4427
|
+
var DEFAULT_PINME_WEB_URL = "http://localhost:5173";
|
|
4428
|
+
var _a;
|
|
4429
|
+
var APP_CONFIG = {
|
|
4430
|
+
pinmeApiBase: trimTrailingSlash(
|
|
4431
|
+
"https://pinme.benny1996.win/api/v4"
|
|
4432
|
+
),
|
|
4433
|
+
ipfsApiUrl: trimTrailingSlash("https://pinme.benny1996.win/api/v3"),
|
|
4434
|
+
carApiBase: trimTrailingSlash(
|
|
4435
|
+
process.env.CAR_API_BASE || "https://pinme.benny1996.win/api/v3"
|
|
4436
|
+
),
|
|
4437
|
+
pinmeWebUrl: trimTrailingSlash(
|
|
4438
|
+
process.env.PINME_WEB_URL || DEFAULT_PINME_WEB_URL
|
|
4439
|
+
),
|
|
4440
|
+
pinmeCheckDomainPath: process.env.PINME_CHECK_DOMAIN_PATH || "/check_domain",
|
|
4441
|
+
ipfsPreviewUrl: "https://pinme.eth.limo/#/preview/",
|
|
4442
|
+
secretKey: "pinme-secret-key",
|
|
4443
|
+
pinmeProjectName: (_a = process.env.PINME_PROJECT_NAME) == null ? void 0 : _a.trim(),
|
|
4444
|
+
upload: {
|
|
4445
|
+
maxRetries: readNumberEnv("MAX_RETRIES", 2),
|
|
4446
|
+
retryDelayMs: readNumberEnv("RETRY_DELAY_MS", 1e3),
|
|
4447
|
+
timeoutMs: readNumberEnv("TIMEOUT_MS", 6e5),
|
|
4448
|
+
maxPollTimeMs: readNumberEnv("MAX_POLL_TIME_MINUTES", 5) * 60 * 1e3,
|
|
4449
|
+
pollIntervalMs: readNumberEnv("POLL_INTERVAL_SECONDS", 2) * 1e3,
|
|
4450
|
+
pollTimeoutMs: readNumberEnv("POLL_TIMEOUT_SECONDS", 10) * 1e3
|
|
4583
4451
|
}
|
|
4584
|
-
|
|
4452
|
+
};
|
|
4453
|
+
function getPinmeApiUrl(pathname) {
|
|
4454
|
+
const normalizedPath = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
4455
|
+
return `${APP_CONFIG.pinmeApiBase}${normalizedPath}`;
|
|
4585
4456
|
}
|
|
4586
4457
|
|
|
4587
4458
|
// bin/utils/webLogin.ts
|
|
4588
|
-
var import_crypto = __toESM(require("crypto"));
|
|
4589
|
-
var import_http3 = __toESM(require("http"));
|
|
4590
|
-
var import_url2 = require("url");
|
|
4591
|
-
var import_chalk3 = __toESM(require("chalk"));
|
|
4592
|
-
var import_child_process = require("child_process");
|
|
4593
|
-
var import_fs_extra4 = __toESM(require("fs-extra"));
|
|
4594
|
-
var import_os4 = __toESM(require("os"));
|
|
4595
|
-
var import_path5 = __toESM(require("path"));
|
|
4596
4459
|
function openBrowser(url2) {
|
|
4597
4460
|
const platform = process.platform;
|
|
4598
4461
|
let command;
|
|
@@ -4605,15 +4468,15 @@ function openBrowser(url2) {
|
|
|
4605
4468
|
}
|
|
4606
4469
|
(0, import_child_process.exec)(command, (err) => {
|
|
4607
4470
|
if (err) {
|
|
4608
|
-
console.log(
|
|
4471
|
+
console.log(import_chalk2.default.yellow(`Unable to open browser automatically. Please visit manually: ${url2}`));
|
|
4609
4472
|
}
|
|
4610
4473
|
});
|
|
4611
4474
|
}
|
|
4612
|
-
var
|
|
4613
|
-
var
|
|
4475
|
+
var CONFIG_DIR = import_path.default.join(import_os.default.homedir(), ".pinme");
|
|
4476
|
+
var AUTH_FILE = import_path.default.join(CONFIG_DIR, "auth.json");
|
|
4614
4477
|
var DEFAULT_OPTIONS = {
|
|
4615
|
-
apiBaseUrl:
|
|
4616
|
-
webBaseUrl:
|
|
4478
|
+
apiBaseUrl: APP_CONFIG.pinmeApiBase,
|
|
4479
|
+
webBaseUrl: APP_CONFIG.pinmeWebUrl,
|
|
4617
4480
|
callbackPort: 34567,
|
|
4618
4481
|
callbackPath: "/cli/callback"
|
|
4619
4482
|
};
|
|
@@ -4627,30 +4490,30 @@ var WebLoginManager = class {
|
|
|
4627
4490
|
this.config = { ...DEFAULT_OPTIONS, ...options };
|
|
4628
4491
|
}
|
|
4629
4492
|
async login() {
|
|
4630
|
-
console.log(
|
|
4493
|
+
console.log(import_chalk2.default.blue("Starting login flow...\n"));
|
|
4631
4494
|
this.loginToken = this.generateLoginToken();
|
|
4632
|
-
console.log(
|
|
4495
|
+
console.log(import_chalk2.default.blue("Starting local callback server..."));
|
|
4633
4496
|
await this.startCallbackServer();
|
|
4634
4497
|
try {
|
|
4635
4498
|
const loginUrl = this.buildLoginUrl();
|
|
4636
|
-
console.log(
|
|
4637
|
-
console.log(
|
|
4638
|
-
console.log(
|
|
4499
|
+
console.log(import_chalk2.default.blue("Opening browser..."));
|
|
4500
|
+
console.log(import_chalk2.default.white("If browser does not open automatically, please visit manually:"));
|
|
4501
|
+
console.log(import_chalk2.default.cyan(` ${loginUrl}
|
|
4639
4502
|
`));
|
|
4640
4503
|
openBrowser(loginUrl);
|
|
4641
|
-
console.log(
|
|
4642
|
-
console.log(
|
|
4504
|
+
console.log(import_chalk2.default.yellow("Please complete login in browser..."));
|
|
4505
|
+
console.log(import_chalk2.default.gray("Browser will close automatically after successful login.\n"));
|
|
4643
4506
|
const authToken = await this.waitForCallback();
|
|
4644
4507
|
const authConfig = this.parseAuthToken(authToken);
|
|
4645
4508
|
this.saveAuthConfig(authConfig);
|
|
4646
|
-
console.log(
|
|
4509
|
+
console.log(import_chalk2.default.green("\nLogin successful!"));
|
|
4647
4510
|
if (authConfig.email) {
|
|
4648
|
-
console.log(
|
|
4511
|
+
console.log(import_chalk2.default.green(`Welcome, ${authConfig.email}`));
|
|
4649
4512
|
}
|
|
4650
|
-
console.log(
|
|
4513
|
+
console.log(import_chalk2.default.gray(`Address: ${authConfig.address}`));
|
|
4651
4514
|
return authConfig;
|
|
4652
4515
|
} catch (error) {
|
|
4653
|
-
console.error(
|
|
4516
|
+
console.error(import_chalk2.default.red(`
|
|
4654
4517
|
Login failed: ${error.message}`));
|
|
4655
4518
|
throw error;
|
|
4656
4519
|
} finally {
|
|
@@ -4712,7 +4575,7 @@ Login failed: ${error.message}`));
|
|
|
4712
4575
|
reject(err);
|
|
4713
4576
|
});
|
|
4714
4577
|
this.server.listen(this.config.callbackPort, "127.0.0.1", () => {
|
|
4715
|
-
console.log(
|
|
4578
|
+
console.log(import_chalk2.default.gray(`Local server: http://localhost:${this.config.callbackPort}`));
|
|
4716
4579
|
resolve();
|
|
4717
4580
|
});
|
|
4718
4581
|
setTimeout(() => {
|
|
@@ -4747,9 +4610,9 @@ Login failed: ${error.message}`));
|
|
|
4747
4610
|
return { address, token };
|
|
4748
4611
|
}
|
|
4749
4612
|
saveAuthConfig(config) {
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4613
|
+
import_fs_extra.default.ensureDirSync(CONFIG_DIR);
|
|
4614
|
+
import_fs_extra.default.writeJsonSync(AUTH_FILE, config, { spaces: 2 });
|
|
4615
|
+
import_fs_extra.default.chmodSync(AUTH_FILE, 384);
|
|
4753
4616
|
}
|
|
4754
4617
|
closeServer() {
|
|
4755
4618
|
if (this.server) {
|
|
@@ -5046,14 +4909,14 @@ function setAuthToken(combined) {
|
|
|
5046
4909
|
throw new Error("Invalid token content. Address or token is empty.");
|
|
5047
4910
|
}
|
|
5048
4911
|
const config = { address, token };
|
|
5049
|
-
|
|
5050
|
-
|
|
4912
|
+
import_fs_extra.default.ensureDirSync(CONFIG_DIR);
|
|
4913
|
+
import_fs_extra.default.writeJsonSync(AUTH_FILE, config, { spaces: 2 });
|
|
5051
4914
|
return config;
|
|
5052
4915
|
}
|
|
5053
|
-
function
|
|
4916
|
+
function getAuthConfig() {
|
|
5054
4917
|
try {
|
|
5055
|
-
if (!
|
|
5056
|
-
const data =
|
|
4918
|
+
if (!import_fs_extra.default.existsSync(AUTH_FILE)) return null;
|
|
4919
|
+
const data = import_fs_extra.default.readJsonSync(AUTH_FILE);
|
|
5057
4920
|
if (!(data == null ? void 0 : data.address) || !(data == null ? void 0 : data.token)) return null;
|
|
5058
4921
|
return data;
|
|
5059
4922
|
} catch {
|
|
@@ -5062,15 +4925,15 @@ function getAuthConfig2() {
|
|
|
5062
4925
|
}
|
|
5063
4926
|
function clearAuthToken() {
|
|
5064
4927
|
try {
|
|
5065
|
-
if (
|
|
5066
|
-
|
|
4928
|
+
if (import_fs_extra.default.existsSync(AUTH_FILE)) {
|
|
4929
|
+
import_fs_extra.default.removeSync(AUTH_FILE);
|
|
5067
4930
|
}
|
|
5068
4931
|
} catch (error) {
|
|
5069
4932
|
console.error(`Failed to clear auth token: ${error}`);
|
|
5070
4933
|
}
|
|
5071
4934
|
}
|
|
5072
4935
|
function getAuthHeaders() {
|
|
5073
|
-
const conf =
|
|
4936
|
+
const conf = getAuthConfig();
|
|
5074
4937
|
if (!conf) {
|
|
5075
4938
|
throw new Error("Auth not set. Run: pinme login");
|
|
5076
4939
|
}
|
|
@@ -5080,849 +4943,1112 @@ function getAuthHeaders() {
|
|
|
5080
4943
|
};
|
|
5081
4944
|
}
|
|
5082
4945
|
|
|
5083
|
-
// bin/utils/
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
var POLL_INTERVAL = parseInt(process.env.POLL_INTERVAL_SECONDS || "2") * 1e3;
|
|
5090
|
-
var PROGRESS_UPDATE_INTERVAL = 200;
|
|
5091
|
-
var EXPECTED_UPLOAD_TIME = 6e4;
|
|
5092
|
-
var MAX_PROGRESS = 0.9;
|
|
5093
|
-
var StepProgressBar = class {
|
|
5094
|
-
spinner;
|
|
5095
|
-
fileName;
|
|
5096
|
-
startTime;
|
|
5097
|
-
currentStep = 0;
|
|
5098
|
-
stepStartTime = 0;
|
|
5099
|
-
progressInterval = null;
|
|
5100
|
-
isSimulatingProgress = false;
|
|
5101
|
-
simulationStartTime = 0;
|
|
5102
|
-
constructor(fileName, isDirectory = false) {
|
|
5103
|
-
this.fileName = fileName;
|
|
5104
|
-
this.spinner = (0, import_ora.default)(`Preparing to upload ${fileName}...`).start();
|
|
5105
|
-
this.startTime = Date.now();
|
|
5106
|
-
this.stepStartTime = Date.now();
|
|
5107
|
-
this.startProgress();
|
|
5108
|
-
}
|
|
5109
|
-
startStep(stepIndex, stepName) {
|
|
5110
|
-
this.currentStep = stepIndex;
|
|
5111
|
-
this.stepStartTime = Date.now();
|
|
5112
|
-
}
|
|
5113
|
-
updateProgress(progress, total) {
|
|
5114
|
-
}
|
|
5115
|
-
completeStep() {
|
|
5116
|
-
}
|
|
5117
|
-
// Start simulating progress to continue display after 90%
|
|
5118
|
-
startSimulatingProgress() {
|
|
5119
|
-
this.isSimulatingProgress = true;
|
|
5120
|
-
this.simulationStartTime = Date.now();
|
|
4946
|
+
// bin/utils/apiClient.ts
|
|
4947
|
+
function safeGetAuthHeaders() {
|
|
4948
|
+
try {
|
|
4949
|
+
return getAuthHeaders();
|
|
4950
|
+
} catch (error) {
|
|
4951
|
+
return {};
|
|
5121
4952
|
}
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
4953
|
+
}
|
|
4954
|
+
function createApiClient(options = {}) {
|
|
4955
|
+
const {
|
|
4956
|
+
baseURL = APP_CONFIG.pinmeApiBase,
|
|
4957
|
+
includeAuth = true,
|
|
4958
|
+
timeout = 2e4,
|
|
4959
|
+
headers = {}
|
|
4960
|
+
} = options;
|
|
4961
|
+
const client = axios_default.create({
|
|
4962
|
+
baseURL,
|
|
4963
|
+
timeout,
|
|
4964
|
+
headers: {
|
|
4965
|
+
...includeAuth ? safeGetAuthHeaders() : {},
|
|
4966
|
+
Accept: "*/*",
|
|
4967
|
+
"Content-Type": "application/json",
|
|
4968
|
+
"User-Agent": "Pinme-CLI",
|
|
4969
|
+
Connection: "keep-alive",
|
|
4970
|
+
...headers
|
|
4971
|
+
}
|
|
4972
|
+
});
|
|
4973
|
+
client.interceptors.response.use(
|
|
4974
|
+
(response) => response,
|
|
4975
|
+
(error) => Promise.reject(error)
|
|
4976
|
+
);
|
|
4977
|
+
return client;
|
|
4978
|
+
}
|
|
4979
|
+
function createPinmeApiClient(options = {}) {
|
|
4980
|
+
return createApiClient({
|
|
4981
|
+
...options,
|
|
4982
|
+
baseURL: APP_CONFIG.pinmeApiBase
|
|
4983
|
+
});
|
|
4984
|
+
}
|
|
4985
|
+
function createCarApiClient(options = {}) {
|
|
4986
|
+
return createApiClient({
|
|
4987
|
+
...options,
|
|
4988
|
+
baseURL: APP_CONFIG.carApiBase
|
|
4989
|
+
});
|
|
4990
|
+
}
|
|
4991
|
+
|
|
4992
|
+
// bin/utils/pinmeApi.ts
|
|
4993
|
+
var TOKEN_EXPIRED_CODES = [
|
|
4994
|
+
401,
|
|
4995
|
+
403,
|
|
4996
|
+
10001,
|
|
4997
|
+
10002,
|
|
4998
|
+
20001,
|
|
4999
|
+
"TOKEN_EXPIRED",
|
|
5000
|
+
"AUTH_FAILED"
|
|
5001
|
+
];
|
|
5002
|
+
var TOKEN_EXPIRED_MESSAGES = [
|
|
5003
|
+
"token expired",
|
|
5004
|
+
"invalid token",
|
|
5005
|
+
"authentication failed",
|
|
5006
|
+
"auth failed",
|
|
5007
|
+
"unauthorized",
|
|
5008
|
+
"\u767B\u5F55",
|
|
5009
|
+
"\u8FC7\u671F",
|
|
5010
|
+
"token",
|
|
5011
|
+
"\u9274\u6743"
|
|
5012
|
+
];
|
|
5013
|
+
function isTokenExpired(error) {
|
|
5014
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
5015
|
+
const status = (_a2 = error.response) == null ? void 0 : _a2.status;
|
|
5016
|
+
const message = ((_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.msg) || ((_e = (_d = error.response) == null ? void 0 : _d.data) == null ? void 0 : _e.message) || error.message || "";
|
|
5017
|
+
const code = (_g = (_f = error.response) == null ? void 0 : _f.data) == null ? void 0 : _g.code;
|
|
5018
|
+
if (status && TOKEN_EXPIRED_CODES.includes(status)) {
|
|
5019
|
+
return true;
|
|
5125
5020
|
}
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
this.spinner.fail(`Upload failed: ${error}`);
|
|
5021
|
+
if (code && TOKEN_EXPIRED_CODES.includes(code)) {
|
|
5022
|
+
return true;
|
|
5129
5023
|
}
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5024
|
+
const lowerMessage = message.toLowerCase();
|
|
5025
|
+
return TOKEN_EXPIRED_MESSAGES.some(
|
|
5026
|
+
(m) => lowerMessage.includes(m.toLowerCase())
|
|
5027
|
+
);
|
|
5028
|
+
}
|
|
5029
|
+
function showTokenExpiredHint() {
|
|
5030
|
+
console.log(import_chalk3.default.red("\n\u26A0\uFE0F Token has expired or is invalid."));
|
|
5031
|
+
console.log(import_chalk3.default.yellow("Please re-run: pinme set-appkey <AppKey>\n"));
|
|
5032
|
+
}
|
|
5033
|
+
async function bindAnonymousDevice(anonymousUid) {
|
|
5034
|
+
try {
|
|
5035
|
+
const client = createPinmeApiClient();
|
|
5036
|
+
const { data } = await client.post("/bind_anonymous", {
|
|
5037
|
+
anonymous_uid: anonymousUid
|
|
5038
|
+
});
|
|
5039
|
+
return (data == null ? void 0 : data.code) === 200;
|
|
5040
|
+
} catch (e) {
|
|
5041
|
+
if (isTokenExpired(e)) {
|
|
5042
|
+
showTokenExpiredHint();
|
|
5043
|
+
return false;
|
|
5044
|
+
}
|
|
5045
|
+
console.log(
|
|
5046
|
+
import_chalk3.default.yellow(`Failed to trigger anonymous binding: ${(e == null ? void 0 : e.message) || e}`)
|
|
5136
5047
|
);
|
|
5048
|
+
return false;
|
|
5137
5049
|
}
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
if (
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5050
|
+
}
|
|
5051
|
+
async function checkDomainAvailable(domainName) {
|
|
5052
|
+
var _a2;
|
|
5053
|
+
const client = createPinmeApiClient();
|
|
5054
|
+
const configured = APP_CONFIG.pinmeCheckDomainPath;
|
|
5055
|
+
const fallbacks = [configured, "/check_domain_available"];
|
|
5056
|
+
for (const p of fallbacks) {
|
|
5057
|
+
try {
|
|
5058
|
+
const { data } = await client.post(p, { domain_name: domainName });
|
|
5059
|
+
if (typeof (data == null ? void 0 : data.is_valid) === "boolean") {
|
|
5060
|
+
return { is_valid: data.is_valid, error: data == null ? void 0 : data.error };
|
|
5061
|
+
}
|
|
5062
|
+
if ((data == null ? void 0 : data.data) && typeof data.data.is_valid === "boolean") {
|
|
5063
|
+
return { is_valid: data.data.is_valid, error: (_a2 = data.data) == null ? void 0 : _a2.error };
|
|
5064
|
+
}
|
|
5065
|
+
} catch (e) {
|
|
5066
|
+
if (isTokenExpired(e)) {
|
|
5067
|
+
showTokenExpiredHint();
|
|
5068
|
+
throw new Error("Token expired");
|
|
5153
5069
|
}
|
|
5154
|
-
const duration = this.formatDuration(Math.floor(elapsed / 1e3));
|
|
5155
|
-
const progressBar = this.createProgressBar(progress);
|
|
5156
|
-
this.spinner.text = `Uploading ${this.fileName}... ${progressBar} ${Math.round(progress * 100)}% (${duration})`;
|
|
5157
|
-
}, PROGRESS_UPDATE_INTERVAL);
|
|
5158
|
-
}
|
|
5159
|
-
stopProgress() {
|
|
5160
|
-
if (this.progressInterval) {
|
|
5161
|
-
clearInterval(this.progressInterval);
|
|
5162
|
-
this.progressInterval = null;
|
|
5163
5070
|
}
|
|
5164
5071
|
}
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
);
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
return `${seconds}s`;
|
|
5180
|
-
} else if (seconds < 3600) {
|
|
5181
|
-
const minutes = Math.floor(seconds / 60);
|
|
5182
|
-
const remainingSeconds = seconds % 60;
|
|
5183
|
-
return `${minutes}m ${remainingSeconds}s`;
|
|
5184
|
-
} else {
|
|
5185
|
-
const hours = Math.floor(seconds / 3600);
|
|
5186
|
-
const minutes = Math.floor(seconds % 3600 / 60);
|
|
5187
|
-
const remainingSeconds = seconds % 60;
|
|
5188
|
-
return `${hours}h ${minutes}m ${remainingSeconds}s`;
|
|
5072
|
+
return { is_valid: true };
|
|
5073
|
+
}
|
|
5074
|
+
async function bindPinmeDomain(domainName, hash) {
|
|
5075
|
+
try {
|
|
5076
|
+
const client = createPinmeApiClient();
|
|
5077
|
+
const { data } = await client.post("/bind_pinme_domain", {
|
|
5078
|
+
domain_name: domainName,
|
|
5079
|
+
hash
|
|
5080
|
+
});
|
|
5081
|
+
return (data == null ? void 0 : data.code) === 200;
|
|
5082
|
+
} catch (e) {
|
|
5083
|
+
if (isTokenExpired(e)) {
|
|
5084
|
+
showTokenExpiredHint();
|
|
5085
|
+
throw new Error("Token expired");
|
|
5189
5086
|
}
|
|
5087
|
+
throw e;
|
|
5190
5088
|
}
|
|
5191
|
-
};
|
|
5192
|
-
async function calculateMD5(filePath) {
|
|
5193
|
-
return new Promise((resolve, reject) => {
|
|
5194
|
-
const hash = crypto2.createHash("md5");
|
|
5195
|
-
const stream4 = import_fs_extra5.default.createReadStream(filePath);
|
|
5196
|
-
stream4.on("data", hash.update.bind(hash));
|
|
5197
|
-
stream4.on("end", () => resolve(hash.digest("hex")));
|
|
5198
|
-
stream4.on("error", reject);
|
|
5199
|
-
});
|
|
5200
5089
|
}
|
|
5201
|
-
async function
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5090
|
+
async function getMyDomains() {
|
|
5091
|
+
var _a2;
|
|
5092
|
+
try {
|
|
5093
|
+
const client = createPinmeApiClient();
|
|
5094
|
+
const { data } = await client.get("/my_domains");
|
|
5095
|
+
if ((data == null ? void 0 : data.code) === 200) {
|
|
5096
|
+
if (Array.isArray(data == null ? void 0 : data.data)) {
|
|
5097
|
+
return data.data;
|
|
5098
|
+
}
|
|
5099
|
+
if (((_a2 = data == null ? void 0 : data.data) == null ? void 0 : _a2.list) && Array.isArray(data.data.list)) {
|
|
5100
|
+
return data.data.list;
|
|
5101
|
+
}
|
|
5206
5102
|
}
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
);
|
|
5211
|
-
const output = import_fs_extra5.default.createWriteStream(outputPath);
|
|
5212
|
-
const zlib2 = require("zlib");
|
|
5213
|
-
const gzip = zlib2.createGzip({ level: 9 });
|
|
5214
|
-
output.on("close", () => resolve(outputPath));
|
|
5215
|
-
gzip.on("error", reject);
|
|
5216
|
-
gzip.pipe(output);
|
|
5217
|
-
const stats = import_fs_extra5.default.statSync(sourcePath);
|
|
5218
|
-
if (stats.isDirectory()) {
|
|
5219
|
-
const archive = require("archiver");
|
|
5220
|
-
const archiveStream = archive("zip", { zlib: { level: 9 } });
|
|
5221
|
-
archiveStream.on("error", reject);
|
|
5222
|
-
archiveStream.pipe(output);
|
|
5223
|
-
archiveStream.directory(sourcePath, false);
|
|
5224
|
-
archiveStream.finalize();
|
|
5225
|
-
} else {
|
|
5226
|
-
const fileStream = import_fs_extra5.default.createReadStream(sourcePath);
|
|
5227
|
-
fileStream.pipe(gzip);
|
|
5103
|
+
if ((data == null ? void 0 : data.code) === 401 || (data == null ? void 0 : data.code) === 403) {
|
|
5104
|
+
showTokenExpiredHint();
|
|
5105
|
+
throw new Error("Token expired");
|
|
5228
5106
|
}
|
|
5229
|
-
|
|
5107
|
+
return [];
|
|
5108
|
+
} catch (e) {
|
|
5109
|
+
if (isTokenExpired(e)) {
|
|
5110
|
+
showTokenExpiredHint();
|
|
5111
|
+
throw new Error("Token expired");
|
|
5112
|
+
}
|
|
5113
|
+
throw e;
|
|
5114
|
+
}
|
|
5230
5115
|
}
|
|
5231
|
-
async function
|
|
5232
|
-
const stats = import_fs_extra5.default.statSync(filePath);
|
|
5233
|
-
const fileName = import_path6.default.basename(filePath);
|
|
5234
|
-
const fileSize = stats.size;
|
|
5235
|
-
const md5 = await calculateMD5(filePath);
|
|
5116
|
+
async function bindDnsDomainV4(domainName, hash, tokenAddress, authToken) {
|
|
5236
5117
|
try {
|
|
5237
|
-
const
|
|
5238
|
-
|
|
5118
|
+
const client = createPinmeApiClient();
|
|
5119
|
+
const { data } = await client.post(
|
|
5120
|
+
"/bind_dns",
|
|
5239
5121
|
{
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
md5,
|
|
5243
|
-
is_directory: isDirectory,
|
|
5244
|
-
uid: deviceId
|
|
5122
|
+
domain_name: domainName,
|
|
5123
|
+
hash
|
|
5245
5124
|
},
|
|
5246
5125
|
{
|
|
5247
|
-
|
|
5248
|
-
|
|
5126
|
+
headers: {
|
|
5127
|
+
"x-auth-token": authToken,
|
|
5128
|
+
"x-token-address": tokenAddress
|
|
5129
|
+
}
|
|
5249
5130
|
}
|
|
5250
5131
|
);
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
} catch (error) {
|
|
5257
|
-
if (axios_default.isAxiosError(error)) {
|
|
5258
|
-
throw new Error(`Network error: ${error.message}`);
|
|
5132
|
+
return data;
|
|
5133
|
+
} catch (e) {
|
|
5134
|
+
if (isTokenExpired(e)) {
|
|
5135
|
+
showTokenExpiredHint();
|
|
5136
|
+
throw new Error("Token expired");
|
|
5259
5137
|
}
|
|
5260
|
-
throw
|
|
5138
|
+
throw e;
|
|
5261
5139
|
}
|
|
5262
5140
|
}
|
|
5263
|
-
async function
|
|
5141
|
+
async function getWalletBalance(tokenAddress, authToken) {
|
|
5264
5142
|
try {
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
const form = new import_form_data2.default();
|
|
5269
|
-
form.append("session_id", sessionId);
|
|
5270
|
-
form.append("chunk_index", chunkIndex.toString());
|
|
5271
|
-
form.append("uid", deviceId);
|
|
5272
|
-
form.append("chunk", chunkData, {
|
|
5273
|
-
filename: `chunk_${chunkIndex}`,
|
|
5274
|
-
contentType: "application/octet-stream"
|
|
5275
|
-
});
|
|
5276
|
-
const response = await axios_default.post(
|
|
5277
|
-
`${IPFS_API_URL}/chunk/upload`,
|
|
5278
|
-
form,
|
|
5143
|
+
const client = createPinmeApiClient();
|
|
5144
|
+
const { data } = await client.get(
|
|
5145
|
+
"/api/v4/pay/wallet/balance",
|
|
5279
5146
|
{
|
|
5280
|
-
headers: {
|
|
5281
|
-
|
|
5282
|
-
|
|
5147
|
+
headers: {
|
|
5148
|
+
"authentication-tokens": authToken,
|
|
5149
|
+
"token-address": tokenAddress
|
|
5150
|
+
}
|
|
5283
5151
|
}
|
|
5284
5152
|
);
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
} catch (error) {
|
|
5291
|
-
if (error.name === "CanceledError" || signal.aborted) {
|
|
5292
|
-
throw new Error("Request cancelled");
|
|
5293
|
-
}
|
|
5294
|
-
if (retryCount < MAX_RETRIES) {
|
|
5295
|
-
await delayWithAbortCheck(RETRY_DELAY, signal);
|
|
5296
|
-
return uploadChunkWithAbort(
|
|
5297
|
-
sessionId,
|
|
5298
|
-
chunkIndex,
|
|
5299
|
-
chunkData,
|
|
5300
|
-
deviceId,
|
|
5301
|
-
signal,
|
|
5302
|
-
retryCount + 1
|
|
5303
|
-
);
|
|
5153
|
+
return data;
|
|
5154
|
+
} catch (e) {
|
|
5155
|
+
if (isTokenExpired(e)) {
|
|
5156
|
+
showTokenExpiredHint();
|
|
5157
|
+
throw new Error("Token expired");
|
|
5304
5158
|
}
|
|
5305
|
-
throw
|
|
5306
|
-
`Chunk ${chunkIndex + 1} upload failed after ${MAX_RETRIES} retries: ${error.message}`
|
|
5307
|
-
);
|
|
5159
|
+
throw e;
|
|
5308
5160
|
}
|
|
5309
5161
|
}
|
|
5310
|
-
async function
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5162
|
+
async function requestCarExport(cid, uid) {
|
|
5163
|
+
var _a2, _b;
|
|
5164
|
+
try {
|
|
5165
|
+
const client = createCarApiClient();
|
|
5166
|
+
const { data } = await client.post("/car/export", null, {
|
|
5167
|
+
params: {
|
|
5168
|
+
cid,
|
|
5169
|
+
uid
|
|
5317
5170
|
}
|
|
5318
|
-
}
|
|
5319
|
-
if (
|
|
5320
|
-
|
|
5321
|
-
reject(new Error("Request cancelled"));
|
|
5322
|
-
return;
|
|
5171
|
+
});
|
|
5172
|
+
if ((data == null ? void 0 : data.code) === 200 && (data == null ? void 0 : data.data)) {
|
|
5173
|
+
return data.data;
|
|
5323
5174
|
}
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
}
|
|
5330
|
-
}, 50);
|
|
5331
|
-
});
|
|
5332
|
-
}
|
|
5333
|
-
async function uploadFileChunks(filePath, sessionId, totalChunks, chunkSize, deviceId, progressBar) {
|
|
5334
|
-
const fileData = import_fs_extra5.default.readFileSync(filePath);
|
|
5335
|
-
const abortController = new AbortController();
|
|
5336
|
-
let completedCount = 0;
|
|
5337
|
-
let hasFatalError = false;
|
|
5338
|
-
let fatalError = null;
|
|
5339
|
-
const uploadTasks = Array.from({ length: totalChunks }, (_, chunkIndex) => {
|
|
5340
|
-
const start = chunkIndex * chunkSize;
|
|
5341
|
-
const end = Math.min(start + chunkSize, fileData.length);
|
|
5342
|
-
const chunkData = fileData.slice(start, end);
|
|
5343
|
-
return async () => {
|
|
5344
|
-
if (abortController.signal.aborted) return;
|
|
5345
|
-
try {
|
|
5346
|
-
await uploadChunkWithAbort(
|
|
5347
|
-
sessionId,
|
|
5348
|
-
chunkIndex,
|
|
5349
|
-
chunkData,
|
|
5350
|
-
deviceId,
|
|
5351
|
-
abortController.signal
|
|
5352
|
-
);
|
|
5353
|
-
if (abortController.signal.aborted) return;
|
|
5354
|
-
completedCount++;
|
|
5355
|
-
progressBar.updateProgress(completedCount, totalChunks);
|
|
5356
|
-
} catch (error) {
|
|
5357
|
-
if (error.name === "AbortError" || abortController.signal.aborted) {
|
|
5358
|
-
return;
|
|
5359
|
-
}
|
|
5360
|
-
hasFatalError = true;
|
|
5361
|
-
fatalError = `Chunk ${chunkIndex + 1}/${totalChunks} upload failed: ${error.message}`;
|
|
5362
|
-
abortController.abort();
|
|
5363
|
-
throw new Error(fatalError);
|
|
5364
|
-
}
|
|
5365
|
-
};
|
|
5366
|
-
});
|
|
5367
|
-
try {
|
|
5368
|
-
const results = await Promise.allSettled(uploadTasks.map((task) => task()));
|
|
5369
|
-
const failedResults = results.filter(
|
|
5370
|
-
(result) => result.status === "rejected"
|
|
5371
|
-
);
|
|
5372
|
-
if (failedResults.length > 0) {
|
|
5373
|
-
const firstFailure = failedResults[0];
|
|
5374
|
-
throw new Error(
|
|
5375
|
-
firstFailure.reason.message || "Error occurred during upload"
|
|
5376
|
-
);
|
|
5175
|
+
throw new Error((data == null ? void 0 : data.msg) || "Failed to request CAR export");
|
|
5176
|
+
} catch (e) {
|
|
5177
|
+
if (isTokenExpired(e)) {
|
|
5178
|
+
showTokenExpiredHint();
|
|
5179
|
+
throw new Error("Token expired");
|
|
5377
5180
|
}
|
|
5378
|
-
if (
|
|
5379
|
-
throw new Error(
|
|
5181
|
+
if ((_b = (_a2 = e.response) == null ? void 0 : _a2.data) == null ? void 0 : _b.msg) {
|
|
5182
|
+
throw new Error(e.response.data.msg);
|
|
5380
5183
|
}
|
|
5381
|
-
|
|
5382
|
-
throw fatalError ? new Error(fatalError) : error;
|
|
5184
|
+
throw new Error(`Failed to request CAR export: ${(e == null ? void 0 : e.message) || e}`);
|
|
5383
5185
|
}
|
|
5384
5186
|
}
|
|
5385
|
-
async function
|
|
5386
|
-
var
|
|
5187
|
+
async function checkCarExportStatus(taskId) {
|
|
5188
|
+
var _a2, _b;
|
|
5387
5189
|
try {
|
|
5388
|
-
const
|
|
5389
|
-
const
|
|
5390
|
-
|
|
5391
|
-
if (importAsCar) {
|
|
5392
|
-
requestBody.import_as_car = true;
|
|
5393
|
-
}
|
|
5394
|
-
if (projectName) {
|
|
5395
|
-
requestBody.project_name = projectName;
|
|
5396
|
-
authHeaders = getAuthHeaders();
|
|
5397
|
-
}
|
|
5398
|
-
const response = await axios_default.post(
|
|
5399
|
-
`${IPFS_API_URL}/chunk/complete`,
|
|
5400
|
-
requestBody,
|
|
5190
|
+
const client = createCarApiClient();
|
|
5191
|
+
const { data } = await client.get(
|
|
5192
|
+
"/car/export/status",
|
|
5401
5193
|
{
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
"Content-Type": "application/json",
|
|
5405
|
-
...authHeaders
|
|
5194
|
+
params: {
|
|
5195
|
+
task_id: taskId
|
|
5406
5196
|
}
|
|
5407
5197
|
}
|
|
5408
5198
|
);
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
return data.trace_id;
|
|
5199
|
+
if ((data == null ? void 0 : data.code) === 200 && (data == null ? void 0 : data.data)) {
|
|
5200
|
+
return data.data;
|
|
5412
5201
|
}
|
|
5413
|
-
throw new Error(
|
|
5414
|
-
} catch (
|
|
5415
|
-
if (
|
|
5416
|
-
|
|
5202
|
+
throw new Error((data == null ? void 0 : data.msg) || "Failed to check export status");
|
|
5203
|
+
} catch (e) {
|
|
5204
|
+
if (isTokenExpired(e)) {
|
|
5205
|
+
showTokenExpiredHint();
|
|
5206
|
+
throw new Error("Token expired");
|
|
5417
5207
|
}
|
|
5418
|
-
|
|
5208
|
+
if ((_b = (_a2 = e.response) == null ? void 0 : _a2.data) == null ? void 0 : _b.msg) {
|
|
5209
|
+
throw new Error(e.response.data.msg);
|
|
5210
|
+
}
|
|
5211
|
+
throw new Error(`Failed to check export status: ${(e == null ? void 0 : e.message) || e}`);
|
|
5419
5212
|
}
|
|
5420
5213
|
}
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5214
|
+
|
|
5215
|
+
// bin/utils/domainValidator.ts
|
|
5216
|
+
function normalizeDomain(domain) {
|
|
5217
|
+
return domain.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
5218
|
+
}
|
|
5219
|
+
function isDnsDomain(domain) {
|
|
5220
|
+
return normalizeDomain(domain).includes(".");
|
|
5221
|
+
}
|
|
5222
|
+
function validateDnsDomain(domain) {
|
|
5223
|
+
const cleanDomain = normalizeDomain(domain);
|
|
5224
|
+
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]*(\.[a-zA-Z0-9][a-zA-Z0-9-]*)*\.[a-zA-Z]{2,}$/;
|
|
5225
|
+
const parts = cleanDomain.split(".");
|
|
5226
|
+
if (parts.length < 2) {
|
|
5227
|
+
return {
|
|
5228
|
+
valid: false,
|
|
5229
|
+
message: "Invalid domain format. Please enter a complete domain (e.g., example.com)"
|
|
5230
|
+
};
|
|
5231
|
+
}
|
|
5232
|
+
for (const part of parts) {
|
|
5233
|
+
if (part.length === 0) {
|
|
5234
|
+
return {
|
|
5235
|
+
valid: false,
|
|
5236
|
+
message: "Invalid domain format. Consecutive dots are not allowed"
|
|
5237
|
+
};
|
|
5431
5238
|
}
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
}
|
|
5438
|
-
);
|
|
5439
|
-
const { code, msg, data } = response.data;
|
|
5440
|
-
if (code === 200) {
|
|
5441
|
-
return data;
|
|
5239
|
+
if (part.length > 63) {
|
|
5240
|
+
return {
|
|
5241
|
+
valid: false,
|
|
5242
|
+
message: "Invalid domain format. Each label must be 63 characters or less"
|
|
5243
|
+
};
|
|
5442
5244
|
}
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5245
|
+
if (!/^[a-zA-Z0-9-]+$/.test(part)) {
|
|
5246
|
+
return {
|
|
5247
|
+
valid: false,
|
|
5248
|
+
message: "Invalid domain format. Domains can only contain letters, numbers, and hyphens"
|
|
5249
|
+
};
|
|
5250
|
+
}
|
|
5251
|
+
if (/^-|-$/.test(part)) {
|
|
5252
|
+
return {
|
|
5253
|
+
valid: false,
|
|
5254
|
+
message: "Invalid domain format. Labels cannot start or end with hyphens"
|
|
5255
|
+
};
|
|
5447
5256
|
}
|
|
5448
|
-
throw error;
|
|
5449
5257
|
}
|
|
5450
|
-
|
|
5451
|
-
|
|
5452
|
-
let consecutiveErrors = 0;
|
|
5453
|
-
const startTime = Date.now();
|
|
5454
|
-
if (progressBar) {
|
|
5455
|
-
progressBar.startSimulatingProgress();
|
|
5258
|
+
if (!domainRegex.test(cleanDomain)) {
|
|
5259
|
+
return { valid: false, message: "Invalid domain format" };
|
|
5456
5260
|
}
|
|
5261
|
+
return { valid: true };
|
|
5262
|
+
}
|
|
5263
|
+
|
|
5264
|
+
// bin/services/uploadService.ts
|
|
5265
|
+
var import_crypto_js = __toESM(require("crypto-js"));
|
|
5266
|
+
|
|
5267
|
+
// bin/utils/getDeviceId.ts
|
|
5268
|
+
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
5269
|
+
var import_path3 = __toESM(require("path"));
|
|
5270
|
+
var import_os3 = __toESM(require("os"));
|
|
5271
|
+
var import_uuid = require("uuid");
|
|
5272
|
+
|
|
5273
|
+
// bin/utils/auth.ts
|
|
5274
|
+
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
5275
|
+
var import_os2 = __toESM(require("os"));
|
|
5276
|
+
var import_path2 = __toESM(require("path"));
|
|
5277
|
+
var CONFIG_DIR2 = import_path2.default.join(import_os2.default.homedir(), ".pinme");
|
|
5278
|
+
var AUTH_FILE2 = import_path2.default.join(CONFIG_DIR2, "auth.json");
|
|
5279
|
+
function getAuthConfig2() {
|
|
5457
5280
|
try {
|
|
5458
|
-
|
|
5459
|
-
|
|
5460
|
-
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
progressBar.stopSimulatingProgress();
|
|
5465
|
-
}
|
|
5466
|
-
const shortUrl = status.upload_rst.ShortUrl;
|
|
5467
|
-
const domain = status.domain;
|
|
5468
|
-
const fullShortUrl = shortUrl && domain ? `${shortUrl}.${domain}` : shortUrl;
|
|
5469
|
-
return {
|
|
5470
|
-
hash: status.upload_rst.Hash,
|
|
5471
|
-
shortUrl: fullShortUrl
|
|
5472
|
-
};
|
|
5473
|
-
}
|
|
5474
|
-
} catch (error) {
|
|
5475
|
-
consecutiveErrors++;
|
|
5476
|
-
if (consecutiveErrors > 10) {
|
|
5477
|
-
throw new Error(`Polling failed: ${error.message}`);
|
|
5478
|
-
}
|
|
5479
|
-
}
|
|
5480
|
-
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
|
5481
|
-
}
|
|
5482
|
-
const maxPollTimeMinutes = Math.floor(MAX_POLL_TIME / (60 * 1e3));
|
|
5483
|
-
throw new Error(`Polling timeout after ${maxPollTimeMinutes} minutes`);
|
|
5484
|
-
} finally {
|
|
5485
|
-
if (progressBar) {
|
|
5486
|
-
progressBar.stopSimulatingProgress();
|
|
5487
|
-
}
|
|
5281
|
+
if (!import_fs_extra2.default.existsSync(AUTH_FILE2)) return null;
|
|
5282
|
+
const data = import_fs_extra2.default.readJsonSync(AUTH_FILE2);
|
|
5283
|
+
if (!(data == null ? void 0 : data.address) || !(data == null ? void 0 : data.token)) return null;
|
|
5284
|
+
return data;
|
|
5285
|
+
} catch {
|
|
5286
|
+
return null;
|
|
5488
5287
|
}
|
|
5489
5288
|
}
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
);
|
|
5289
|
+
|
|
5290
|
+
// bin/utils/getDeviceId.ts
|
|
5291
|
+
function getDeviceId() {
|
|
5292
|
+
const configDir = import_path3.default.join(import_os3.default.homedir(), ".pinme");
|
|
5293
|
+
const configFile = import_path3.default.join(configDir, "device-id");
|
|
5294
|
+
if (!import_fs_extra3.default.existsSync(configDir)) {
|
|
5295
|
+
import_fs_extra3.default.mkdirSync(configDir, { recursive: true });
|
|
5498
5296
|
}
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5297
|
+
if (import_fs_extra3.default.existsSync(configFile)) {
|
|
5298
|
+
return import_fs_extra3.default.readFileSync(configFile, "utf8").trim();
|
|
5299
|
+
}
|
|
5300
|
+
const deviceId = (0, import_uuid.v4)();
|
|
5301
|
+
import_fs_extra3.default.writeFileSync(configFile, deviceId);
|
|
5302
|
+
return deviceId;
|
|
5303
|
+
}
|
|
5304
|
+
function getUid() {
|
|
5305
|
+
const auth = getAuthConfig2();
|
|
5306
|
+
if (auth == null ? void 0 : auth.address) {
|
|
5307
|
+
return auth.address;
|
|
5308
|
+
}
|
|
5309
|
+
return getDeviceId();
|
|
5310
|
+
}
|
|
5311
|
+
|
|
5312
|
+
// bin/utils/uploadToIpfsSplit.ts
|
|
5313
|
+
var import_fs_extra5 = __toESM(require("fs-extra"));
|
|
5314
|
+
var import_path6 = __toESM(require("path"));
|
|
5315
|
+
var import_form_data2 = __toESM(require("form-data"));
|
|
5316
|
+
var import_ora = __toESM(require("ora"));
|
|
5317
|
+
var crypto2 = __toESM(require("crypto"));
|
|
5318
|
+
|
|
5319
|
+
// bin/utils/uploadLimits.ts
|
|
5320
|
+
var import_fs = __toESM(require("fs"));
|
|
5321
|
+
var import_path4 = __toESM(require("path"));
|
|
5322
|
+
var FILE_SIZE_LIMIT = parseInt("500", 10) * 1024 * 1024;
|
|
5323
|
+
var DIRECTORY_SIZE_LIMIT = parseInt("500", 10) * 1024 * 1024;
|
|
5324
|
+
function checkFileSizeLimit(filePath) {
|
|
5325
|
+
const stats = import_fs.default.statSync(filePath);
|
|
5326
|
+
return {
|
|
5327
|
+
size: stats.size,
|
|
5328
|
+
limit: FILE_SIZE_LIMIT,
|
|
5329
|
+
exceeds: stats.size > FILE_SIZE_LIMIT
|
|
5330
|
+
};
|
|
5331
|
+
}
|
|
5332
|
+
function checkDirectorySizeLimit(directoryPath) {
|
|
5333
|
+
const totalSize = calculateDirectorySize(directoryPath);
|
|
5334
|
+
return {
|
|
5335
|
+
size: totalSize,
|
|
5336
|
+
limit: DIRECTORY_SIZE_LIMIT,
|
|
5337
|
+
exceeds: totalSize > DIRECTORY_SIZE_LIMIT
|
|
5338
|
+
};
|
|
5339
|
+
}
|
|
5340
|
+
function calculateDirectorySize(directoryPath) {
|
|
5341
|
+
let totalSize = 0;
|
|
5342
|
+
const files = import_fs.default.readdirSync(directoryPath);
|
|
5343
|
+
for (const file of files) {
|
|
5344
|
+
const filePath = import_path4.default.join(directoryPath, file);
|
|
5345
|
+
const stats = import_fs.default.statSync(filePath);
|
|
5346
|
+
if (stats.isFile()) {
|
|
5347
|
+
totalSize += stats.size;
|
|
5348
|
+
} else if (stats.isDirectory()) {
|
|
5349
|
+
totalSize += calculateDirectorySize(filePath);
|
|
5539
5350
|
}
|
|
5540
|
-
progressBar.complete();
|
|
5541
|
-
return result;
|
|
5542
|
-
} catch (error) {
|
|
5543
|
-
progressBar.fail(error.message);
|
|
5544
|
-
throw error;
|
|
5545
5351
|
}
|
|
5352
|
+
return totalSize;
|
|
5546
5353
|
}
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
if (
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5354
|
+
function formatSize(bytes) {
|
|
5355
|
+
if (bytes < 1024) return bytes + " bytes";
|
|
5356
|
+
else if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + " KB";
|
|
5357
|
+
else if (bytes < 1024 * 1024 * 1024) return (bytes / (1024 * 1024)).toFixed(2) + " MB";
|
|
5358
|
+
else return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GB";
|
|
5359
|
+
}
|
|
5360
|
+
|
|
5361
|
+
// bin/utils/history.ts
|
|
5362
|
+
var import_fs_extra4 = __toESM(require("fs-extra"));
|
|
5363
|
+
var import_path5 = __toESM(require("path"));
|
|
5364
|
+
var import_os4 = __toESM(require("os"));
|
|
5365
|
+
var import_dayjs = __toESM(require("dayjs"));
|
|
5366
|
+
var import_chalk4 = __toESM(require("chalk"));
|
|
5367
|
+
var HISTORY_DIR = import_path5.default.join(import_os4.default.homedir(), ".pinme");
|
|
5368
|
+
var HISTORY_FILE = import_path5.default.join(HISTORY_DIR, "upload-history.json");
|
|
5369
|
+
var ensureHistoryDir = () => {
|
|
5370
|
+
if (!import_fs_extra4.default.existsSync(HISTORY_DIR)) {
|
|
5371
|
+
import_fs_extra4.default.mkdirSync(HISTORY_DIR, { recursive: true });
|
|
5555
5372
|
}
|
|
5556
|
-
|
|
5557
|
-
|
|
5373
|
+
if (!import_fs_extra4.default.existsSync(HISTORY_FILE)) {
|
|
5374
|
+
import_fs_extra4.default.writeJsonSync(HISTORY_FILE, { uploads: [] });
|
|
5375
|
+
}
|
|
5376
|
+
};
|
|
5377
|
+
var saveUploadHistory = (uploadData) => {
|
|
5558
5378
|
try {
|
|
5559
|
-
|
|
5560
|
-
const
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
progressBar.startStep(2, "Completing upload");
|
|
5573
|
-
const traceId = await completeChunkUpload(sessionInfo.session_id, deviceId, importAsCar);
|
|
5574
|
-
progressBar.completeStep();
|
|
5575
|
-
progressBar.startStep(3, "Waiting for processing");
|
|
5576
|
-
const result = await monitorChunkProgress(traceId, deviceId, progressBar);
|
|
5577
|
-
progressBar.completeStep();
|
|
5578
|
-
const uploadData = {
|
|
5579
|
-
path: filePath,
|
|
5580
|
-
filename: fileName,
|
|
5581
|
-
contentHash: (result == null ? void 0 : result.hash) || "unknown",
|
|
5582
|
-
previewHash: null,
|
|
5583
|
-
size: sizeCheck.size,
|
|
5584
|
-
fileCount: 1,
|
|
5585
|
-
isDirectory: false,
|
|
5586
|
-
shortUrl: (result == null ? void 0 : result.shortUrl) || null
|
|
5379
|
+
ensureHistoryDir();
|
|
5380
|
+
const history = import_fs_extra4.default.readJsonSync(HISTORY_FILE);
|
|
5381
|
+
const newRecord = {
|
|
5382
|
+
timestamp: Date.now(),
|
|
5383
|
+
date: (0, import_dayjs.default)().format("YYYY-MM-DD HH:mm:ss"),
|
|
5384
|
+
path: uploadData.path,
|
|
5385
|
+
filename: uploadData.filename || import_path5.default.basename(uploadData.path),
|
|
5386
|
+
contentHash: uploadData.contentHash,
|
|
5387
|
+
previewHash: uploadData.previewHash,
|
|
5388
|
+
size: uploadData.size,
|
|
5389
|
+
fileCount: uploadData.fileCount || 1,
|
|
5390
|
+
type: uploadData.isDirectory ? "directory" : "file",
|
|
5391
|
+
shortUrl: (uploadData == null ? void 0 : uploadData.shortUrl) || null
|
|
5587
5392
|
};
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
}
|
|
5592
|
-
progressBar.complete();
|
|
5593
|
-
return result;
|
|
5393
|
+
history.uploads.unshift(newRecord);
|
|
5394
|
+
import_fs_extra4.default.writeJsonSync(HISTORY_FILE, history, { spaces: 2 });
|
|
5395
|
+
return true;
|
|
5594
5396
|
} catch (error) {
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
}
|
|
5598
|
-
}
|
|
5599
|
-
async function uploadToIpfsSplit_default(filePath, importAsCar = false) {
|
|
5600
|
-
const deviceId = getUid();
|
|
5601
|
-
if (!deviceId) {
|
|
5602
|
-
throw new Error("Device ID not found");
|
|
5397
|
+
console.error(import_chalk4.default.red(`Error saving upload history: ${error.message}`));
|
|
5398
|
+
return false;
|
|
5603
5399
|
}
|
|
5400
|
+
};
|
|
5401
|
+
var getUploadHistory = (limit = 10) => {
|
|
5604
5402
|
try {
|
|
5605
|
-
|
|
5606
|
-
const
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5403
|
+
ensureHistoryDir();
|
|
5404
|
+
const history = import_fs_extra4.default.readJsonSync(HISTORY_FILE);
|
|
5405
|
+
return history.uploads.slice(0, limit);
|
|
5406
|
+
} catch (error) {
|
|
5407
|
+
console.error(import_chalk4.default.red(`Error reading upload history: ${error.message}`));
|
|
5408
|
+
return [];
|
|
5409
|
+
}
|
|
5410
|
+
};
|
|
5411
|
+
var displayUploadHistory = (limit = 10) => {
|
|
5412
|
+
const history = getUploadHistory(limit);
|
|
5413
|
+
if (history.length === 0) {
|
|
5414
|
+
console.log(import_chalk4.default.yellow("No upload history found."));
|
|
5415
|
+
return;
|
|
5416
|
+
}
|
|
5417
|
+
console.log(import_chalk4.default.cyan("Upload History:"));
|
|
5418
|
+
console.log(import_chalk4.default.cyan("-".repeat(80)));
|
|
5419
|
+
const recentHistory = history.slice(-limit);
|
|
5420
|
+
recentHistory.forEach((item, index) => {
|
|
5421
|
+
console.log(import_chalk4.default.green(`${index + 1}. ${item.filename}`));
|
|
5422
|
+
console.log(import_chalk4.default.white(` Path: ${item.path}`));
|
|
5423
|
+
console.log(import_chalk4.default.white(` IPFS CID: ${item.contentHash}`));
|
|
5424
|
+
if (item.shortUrl) {
|
|
5425
|
+
console.log(import_chalk4.default.white(` ENS URL: https://${item.shortUrl}.pinit.eth.limo`));
|
|
5613
5426
|
}
|
|
5614
|
-
|
|
5427
|
+
console.log(import_chalk4.default.white(` Size: ${formatSize(item.size)}`));
|
|
5428
|
+
console.log(import_chalk4.default.white(` Files: ${item.fileCount}`));
|
|
5429
|
+
console.log(import_chalk4.default.white(` Type: ${item.type === "directory" ? "Directory" : "File"}`));
|
|
5430
|
+
if (item.timestamp) {
|
|
5431
|
+
console.log(import_chalk4.default.white(` Date: ${new Date(item.timestamp).toLocaleString()}`));
|
|
5432
|
+
}
|
|
5433
|
+
console.log(import_chalk4.default.cyan("-".repeat(80)));
|
|
5434
|
+
});
|
|
5435
|
+
const totalSize = history.reduce((sum, record) => sum + record.size, 0);
|
|
5436
|
+
const totalFiles = history.reduce((sum, record) => sum + record.fileCount, 0);
|
|
5437
|
+
console.log(import_chalk4.default.bold(`Total Uploads: ${history.length}`));
|
|
5438
|
+
console.log(import_chalk4.default.bold(`Total Files: ${totalFiles}`));
|
|
5439
|
+
console.log(import_chalk4.default.bold(`Total Size: ${formatSize(totalSize)}`));
|
|
5440
|
+
};
|
|
5441
|
+
var clearUploadHistory = () => {
|
|
5442
|
+
try {
|
|
5443
|
+
ensureHistoryDir();
|
|
5444
|
+
import_fs_extra4.default.writeJsonSync(HISTORY_FILE, { uploads: [] });
|
|
5445
|
+
console.log(import_chalk4.default.green("Upload history cleared successfully."));
|
|
5446
|
+
return true;
|
|
5615
5447
|
} catch (error) {
|
|
5616
|
-
|
|
5448
|
+
console.error(import_chalk4.default.red(`Error clearing upload history: ${error.message}`));
|
|
5449
|
+
return false;
|
|
5617
5450
|
}
|
|
5618
|
-
}
|
|
5619
|
-
|
|
5620
|
-
// bin/upload.ts
|
|
5621
|
-
var import_fs2 = __toESM(require("fs"));
|
|
5622
|
-
var import_crypto_js = __toESM(require("crypto-js"));
|
|
5451
|
+
};
|
|
5623
5452
|
|
|
5624
|
-
// bin/utils/
|
|
5625
|
-
var
|
|
5626
|
-
var
|
|
5627
|
-
var
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
|
|
5647
|
-
|
|
5648
|
-
|
|
5649
|
-
const status = (_a = error.response) == null ? void 0 : _a.status;
|
|
5650
|
-
const message = ((_c = (_b = error.response) == null ? void 0 : _b.data) == null ? void 0 : _c.msg) || ((_e = (_d = error.response) == null ? void 0 : _d.data) == null ? void 0 : _e.message) || error.message || "";
|
|
5651
|
-
const code = (_g = (_f = error.response) == null ? void 0 : _f.data) == null ? void 0 : _g.code;
|
|
5652
|
-
if (status && TOKEN_EXPIRED_CODES.includes(status)) {
|
|
5653
|
-
return true;
|
|
5453
|
+
// bin/utils/uploadToIpfsSplit.ts
|
|
5454
|
+
var IPFS_API_URL = APP_CONFIG.ipfsApiUrl;
|
|
5455
|
+
var MAX_RETRIES = APP_CONFIG.upload.maxRetries;
|
|
5456
|
+
var RETRY_DELAY = APP_CONFIG.upload.retryDelayMs;
|
|
5457
|
+
var TIMEOUT = APP_CONFIG.upload.timeoutMs;
|
|
5458
|
+
var MAX_POLL_TIME = APP_CONFIG.upload.maxPollTimeMs;
|
|
5459
|
+
var POLL_INTERVAL = APP_CONFIG.upload.pollIntervalMs;
|
|
5460
|
+
var PROGRESS_UPDATE_INTERVAL = 200;
|
|
5461
|
+
var EXPECTED_UPLOAD_TIME = 6e4;
|
|
5462
|
+
var MAX_PROGRESS = 0.9;
|
|
5463
|
+
var StepProgressBar = class {
|
|
5464
|
+
spinner;
|
|
5465
|
+
fileName;
|
|
5466
|
+
startTime;
|
|
5467
|
+
currentStep = 0;
|
|
5468
|
+
stepStartTime = 0;
|
|
5469
|
+
progressInterval = null;
|
|
5470
|
+
isSimulatingProgress = false;
|
|
5471
|
+
simulationStartTime = 0;
|
|
5472
|
+
constructor(fileName, isDirectory = false) {
|
|
5473
|
+
this.fileName = fileName;
|
|
5474
|
+
this.spinner = (0, import_ora.default)(`Preparing to upload ${fileName}...`).start();
|
|
5475
|
+
this.startTime = Date.now();
|
|
5476
|
+
this.stepStartTime = Date.now();
|
|
5477
|
+
this.startProgress();
|
|
5654
5478
|
}
|
|
5655
|
-
|
|
5656
|
-
|
|
5479
|
+
startStep(stepIndex, stepName) {
|
|
5480
|
+
this.currentStep = stepIndex;
|
|
5481
|
+
this.stepStartTime = Date.now();
|
|
5657
5482
|
}
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
}
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5483
|
+
updateProgress(progress, total) {
|
|
5484
|
+
}
|
|
5485
|
+
completeStep() {
|
|
5486
|
+
}
|
|
5487
|
+
// Start simulating progress to continue display after 90%
|
|
5488
|
+
startSimulatingProgress() {
|
|
5489
|
+
this.isSimulatingProgress = true;
|
|
5490
|
+
this.simulationStartTime = Date.now();
|
|
5491
|
+
}
|
|
5492
|
+
// Stop simulating progress
|
|
5493
|
+
stopSimulatingProgress() {
|
|
5494
|
+
this.isSimulatingProgress = false;
|
|
5495
|
+
}
|
|
5496
|
+
failStep(error) {
|
|
5497
|
+
this.stopProgress();
|
|
5498
|
+
this.spinner.fail(`Upload failed: ${error}`);
|
|
5499
|
+
}
|
|
5500
|
+
complete() {
|
|
5501
|
+
this.stopProgress();
|
|
5502
|
+
const totalTime = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
5503
|
+
const progressBar = this.createProgressBar(1);
|
|
5504
|
+
this.spinner.succeed(
|
|
5505
|
+
`Upload completed ${progressBar} 100% (${totalTime}s)`
|
|
5506
|
+
);
|
|
5507
|
+
}
|
|
5508
|
+
fail(error) {
|
|
5509
|
+
this.stopProgress();
|
|
5510
|
+
const totalTime = Math.floor((Date.now() - this.startTime) / 1e3);
|
|
5511
|
+
this.spinner.fail(`Upload failed: ${error} (${totalTime}s)`);
|
|
5512
|
+
}
|
|
5513
|
+
startProgress() {
|
|
5514
|
+
this.progressInterval = setInterval(() => {
|
|
5515
|
+
const elapsed = Date.now() - this.startTime;
|
|
5516
|
+
let progress;
|
|
5517
|
+
if (this.isSimulatingProgress) {
|
|
5518
|
+
const simulationElapsed = Date.now() - this.simulationStartTime;
|
|
5519
|
+
const simulationProgress = Math.min(simulationElapsed / 6e4, 1);
|
|
5520
|
+
progress = 0.9 + simulationProgress * 0.09;
|
|
5521
|
+
} else {
|
|
5522
|
+
progress = this.calculateProgress(elapsed);
|
|
5523
|
+
}
|
|
5524
|
+
const duration = this.formatDuration(Math.floor(elapsed / 1e3));
|
|
5525
|
+
const progressBar = this.createProgressBar(progress);
|
|
5526
|
+
this.spinner.text = `Uploading ${this.fileName}... ${progressBar} ${Math.round(progress * 100)}% (${duration})`;
|
|
5527
|
+
}, PROGRESS_UPDATE_INTERVAL);
|
|
5528
|
+
}
|
|
5529
|
+
stopProgress() {
|
|
5530
|
+
if (this.progressInterval) {
|
|
5531
|
+
clearInterval(this.progressInterval);
|
|
5532
|
+
this.progressInterval = null;
|
|
5678
5533
|
}
|
|
5534
|
+
}
|
|
5535
|
+
calculateProgress(elapsed) {
|
|
5536
|
+
return Math.min(
|
|
5537
|
+
elapsed / EXPECTED_UPLOAD_TIME * MAX_PROGRESS,
|
|
5538
|
+
MAX_PROGRESS
|
|
5539
|
+
);
|
|
5540
|
+
}
|
|
5541
|
+
createProgressBar(progress, width = 20) {
|
|
5542
|
+
const percentage = Math.min(progress, 1);
|
|
5543
|
+
const filledWidth = Math.round(width * percentage);
|
|
5544
|
+
const emptyWidth = width - filledWidth;
|
|
5545
|
+
return `[${"\u2588".repeat(filledWidth)}${"\u2591".repeat(emptyWidth)}]`;
|
|
5546
|
+
}
|
|
5547
|
+
formatDuration(seconds) {
|
|
5548
|
+
if (seconds < 60) {
|
|
5549
|
+
return `${seconds}s`;
|
|
5550
|
+
} else if (seconds < 3600) {
|
|
5551
|
+
const minutes = Math.floor(seconds / 60);
|
|
5552
|
+
const remainingSeconds = seconds % 60;
|
|
5553
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
5554
|
+
} else {
|
|
5555
|
+
const hours = Math.floor(seconds / 3600);
|
|
5556
|
+
const minutes = Math.floor(seconds % 3600 / 60);
|
|
5557
|
+
const remainingSeconds = seconds % 60;
|
|
5558
|
+
return `${hours}h ${minutes}m ${remainingSeconds}s`;
|
|
5559
|
+
}
|
|
5560
|
+
}
|
|
5561
|
+
};
|
|
5562
|
+
async function calculateMD5(filePath) {
|
|
5563
|
+
return new Promise((resolve, reject) => {
|
|
5564
|
+
const hash = crypto2.createHash("md5");
|
|
5565
|
+
const stream4 = import_fs_extra5.default.createReadStream(filePath);
|
|
5566
|
+
stream4.on("data", hash.update.bind(hash));
|
|
5567
|
+
stream4.on("end", () => resolve(hash.digest("hex")));
|
|
5568
|
+
stream4.on("error", reject);
|
|
5679
5569
|
});
|
|
5680
5570
|
}
|
|
5681
|
-
async function
|
|
5682
|
-
|
|
5683
|
-
const
|
|
5684
|
-
|
|
5685
|
-
|
|
5686
|
-
});
|
|
5687
|
-
return (data == null ? void 0 : data.code) === 200;
|
|
5688
|
-
} catch (e) {
|
|
5689
|
-
if (isTokenExpired(e)) {
|
|
5690
|
-
showTokenExpiredHint();
|
|
5691
|
-
return false;
|
|
5571
|
+
async function compressDirectory(sourcePath) {
|
|
5572
|
+
return new Promise((resolve, reject) => {
|
|
5573
|
+
const tempDir = require("os").tmpdir();
|
|
5574
|
+
if (!import_fs_extra5.default.existsSync(tempDir)) {
|
|
5575
|
+
import_fs_extra5.default.mkdirSync(tempDir, { recursive: true });
|
|
5692
5576
|
}
|
|
5693
|
-
|
|
5694
|
-
|
|
5577
|
+
const outputPath = import_path6.default.join(
|
|
5578
|
+
tempDir,
|
|
5579
|
+
`pinme_${import_path6.default.basename(sourcePath)}_${Date.now()}.zip`
|
|
5695
5580
|
);
|
|
5696
|
-
|
|
5697
|
-
|
|
5581
|
+
const output = import_fs_extra5.default.createWriteStream(outputPath);
|
|
5582
|
+
const zlib2 = require("zlib");
|
|
5583
|
+
const gzip = zlib2.createGzip({ level: 9 });
|
|
5584
|
+
output.on("close", () => resolve(outputPath));
|
|
5585
|
+
gzip.on("error", reject);
|
|
5586
|
+
gzip.pipe(output);
|
|
5587
|
+
const stats = import_fs_extra5.default.statSync(sourcePath);
|
|
5588
|
+
if (stats.isDirectory()) {
|
|
5589
|
+
const archive = require("archiver");
|
|
5590
|
+
const archiveStream = archive("zip", { zlib: { level: 9 } });
|
|
5591
|
+
archiveStream.on("error", reject);
|
|
5592
|
+
archiveStream.pipe(output);
|
|
5593
|
+
archiveStream.directory(sourcePath, false);
|
|
5594
|
+
archiveStream.finalize();
|
|
5595
|
+
} else {
|
|
5596
|
+
const fileStream = import_fs_extra5.default.createReadStream(sourcePath);
|
|
5597
|
+
fileStream.pipe(gzip);
|
|
5598
|
+
}
|
|
5599
|
+
});
|
|
5698
5600
|
}
|
|
5699
|
-
async function
|
|
5700
|
-
|
|
5701
|
-
const
|
|
5702
|
-
const
|
|
5703
|
-
const
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5601
|
+
async function initChunkSession(filePath, deviceId, isDirectory = false) {
|
|
5602
|
+
const stats = import_fs_extra5.default.statSync(filePath);
|
|
5603
|
+
const fileName = import_path6.default.basename(filePath);
|
|
5604
|
+
const fileSize = stats.size;
|
|
5605
|
+
const md5 = await calculateMD5(filePath);
|
|
5606
|
+
try {
|
|
5607
|
+
const response = await axios_default.post(
|
|
5608
|
+
`${IPFS_API_URL}/chunk/init`,
|
|
5609
|
+
{
|
|
5610
|
+
file_name: fileName,
|
|
5611
|
+
file_size: fileSize,
|
|
5612
|
+
md5,
|
|
5613
|
+
is_directory: isDirectory,
|
|
5614
|
+
uid: deviceId
|
|
5615
|
+
},
|
|
5616
|
+
{
|
|
5617
|
+
timeout: TIMEOUT,
|
|
5618
|
+
headers: { "Content-Type": "application/json" }
|
|
5717
5619
|
}
|
|
5620
|
+
);
|
|
5621
|
+
const { code, msg, data } = response.data;
|
|
5622
|
+
if (code === 200 && data) {
|
|
5623
|
+
return data;
|
|
5718
5624
|
}
|
|
5625
|
+
throw new Error(`Session initialization failed: ${msg} (code: ${code})`);
|
|
5626
|
+
} catch (error) {
|
|
5627
|
+
if (axios_default.isAxiosError(error)) {
|
|
5628
|
+
throw new Error(`Network error: ${error.message}`);
|
|
5629
|
+
}
|
|
5630
|
+
throw error;
|
|
5719
5631
|
}
|
|
5720
|
-
return { is_valid: true };
|
|
5721
5632
|
}
|
|
5722
|
-
async function
|
|
5633
|
+
async function uploadChunkWithAbort(sessionId, chunkIndex, chunkData, deviceId, signal, retryCount = 0) {
|
|
5723
5634
|
try {
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5635
|
+
if (signal.aborted) {
|
|
5636
|
+
throw new Error("Request cancelled");
|
|
5637
|
+
}
|
|
5638
|
+
const form = new import_form_data2.default();
|
|
5639
|
+
form.append("session_id", sessionId);
|
|
5640
|
+
form.append("chunk_index", chunkIndex.toString());
|
|
5641
|
+
form.append("uid", deviceId);
|
|
5642
|
+
form.append("chunk", chunkData, {
|
|
5643
|
+
filename: `chunk_${chunkIndex}`,
|
|
5644
|
+
contentType: "application/octet-stream"
|
|
5728
5645
|
});
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5646
|
+
const response = await axios_default.post(
|
|
5647
|
+
`${IPFS_API_URL}/chunk/upload`,
|
|
5648
|
+
form,
|
|
5649
|
+
{
|
|
5650
|
+
headers: { ...form.getHeaders() },
|
|
5651
|
+
timeout: TIMEOUT,
|
|
5652
|
+
signal
|
|
5653
|
+
}
|
|
5654
|
+
);
|
|
5655
|
+
const { code, msg, data } = response.data;
|
|
5656
|
+
if (code === 200 && data) {
|
|
5657
|
+
return data;
|
|
5658
|
+
}
|
|
5659
|
+
throw new Error(`Chunk upload failed: ${msg} (code: ${code})`);
|
|
5660
|
+
} catch (error) {
|
|
5661
|
+
if (error.name === "CanceledError" || signal.aborted) {
|
|
5662
|
+
throw new Error("Request cancelled");
|
|
5663
|
+
}
|
|
5664
|
+
if (retryCount < MAX_RETRIES) {
|
|
5665
|
+
await delayWithAbortCheck(RETRY_DELAY, signal);
|
|
5666
|
+
return uploadChunkWithAbort(
|
|
5667
|
+
sessionId,
|
|
5668
|
+
chunkIndex,
|
|
5669
|
+
chunkData,
|
|
5670
|
+
deviceId,
|
|
5671
|
+
signal,
|
|
5672
|
+
retryCount + 1
|
|
5673
|
+
);
|
|
5734
5674
|
}
|
|
5735
|
-
throw
|
|
5675
|
+
throw new Error(
|
|
5676
|
+
`Chunk ${chunkIndex + 1} upload failed after ${MAX_RETRIES} retries: ${error.message}`
|
|
5677
|
+
);
|
|
5736
5678
|
}
|
|
5737
5679
|
}
|
|
5738
|
-
async function
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
return data.data;
|
|
5746
|
-
}
|
|
5747
|
-
if (((_a = data == null ? void 0 : data.data) == null ? void 0 : _a.list) && Array.isArray(data.data.list)) {
|
|
5748
|
-
return data.data.list;
|
|
5680
|
+
async function delayWithAbortCheck(delay, signal) {
|
|
5681
|
+
return new Promise((resolve, reject) => {
|
|
5682
|
+
const timeoutId = setTimeout(() => {
|
|
5683
|
+
if (signal.aborted) {
|
|
5684
|
+
reject(new Error("Request cancelled"));
|
|
5685
|
+
} else {
|
|
5686
|
+
resolve();
|
|
5749
5687
|
}
|
|
5688
|
+
}, delay);
|
|
5689
|
+
if (signal.aborted) {
|
|
5690
|
+
clearTimeout(timeoutId);
|
|
5691
|
+
reject(new Error("Request cancelled"));
|
|
5692
|
+
return;
|
|
5750
5693
|
}
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5694
|
+
const checkInterval = setInterval(() => {
|
|
5695
|
+
if (signal.aborted) {
|
|
5696
|
+
clearTimeout(timeoutId);
|
|
5697
|
+
clearInterval(checkInterval);
|
|
5698
|
+
reject(new Error("Request cancelled"));
|
|
5699
|
+
}
|
|
5700
|
+
}, 50);
|
|
5701
|
+
});
|
|
5702
|
+
}
|
|
5703
|
+
async function uploadFileChunks(filePath, sessionId, totalChunks, chunkSize, deviceId, progressBar) {
|
|
5704
|
+
const fileData = import_fs_extra5.default.readFileSync(filePath);
|
|
5705
|
+
const abortController = new AbortController();
|
|
5706
|
+
let completedCount = 0;
|
|
5707
|
+
let hasFatalError = false;
|
|
5708
|
+
let fatalError = null;
|
|
5709
|
+
const uploadTasks = Array.from({ length: totalChunks }, (_, chunkIndex) => {
|
|
5710
|
+
const start = chunkIndex * chunkSize;
|
|
5711
|
+
const end = Math.min(start + chunkSize, fileData.length);
|
|
5712
|
+
const chunkData = fileData.slice(start, end);
|
|
5713
|
+
return async () => {
|
|
5714
|
+
if (abortController.signal.aborted) return;
|
|
5715
|
+
try {
|
|
5716
|
+
await uploadChunkWithAbort(
|
|
5717
|
+
sessionId,
|
|
5718
|
+
chunkIndex,
|
|
5719
|
+
chunkData,
|
|
5720
|
+
deviceId,
|
|
5721
|
+
abortController.signal
|
|
5722
|
+
);
|
|
5723
|
+
if (abortController.signal.aborted) return;
|
|
5724
|
+
completedCount++;
|
|
5725
|
+
progressBar.updateProgress(completedCount, totalChunks);
|
|
5726
|
+
} catch (error) {
|
|
5727
|
+
if (error.name === "AbortError" || abortController.signal.aborted) {
|
|
5728
|
+
return;
|
|
5729
|
+
}
|
|
5730
|
+
hasFatalError = true;
|
|
5731
|
+
fatalError = `Chunk ${chunkIndex + 1}/${totalChunks} upload failed: ${error.message}`;
|
|
5732
|
+
abortController.abort();
|
|
5733
|
+
throw new Error(fatalError);
|
|
5734
|
+
}
|
|
5735
|
+
};
|
|
5736
|
+
});
|
|
5737
|
+
try {
|
|
5738
|
+
const results = await Promise.allSettled(uploadTasks.map((task) => task()));
|
|
5739
|
+
const failedResults = results.filter(
|
|
5740
|
+
(result) => result.status === "rejected"
|
|
5741
|
+
);
|
|
5742
|
+
if (failedResults.length > 0) {
|
|
5743
|
+
const firstFailure = failedResults[0];
|
|
5744
|
+
throw new Error(
|
|
5745
|
+
firstFailure.reason.message || "Error occurred during upload"
|
|
5746
|
+
);
|
|
5754
5747
|
}
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
if (isTokenExpired(e)) {
|
|
5758
|
-
showTokenExpiredHint();
|
|
5759
|
-
throw new Error("Token expired");
|
|
5748
|
+
if (hasFatalError) {
|
|
5749
|
+
throw new Error(fatalError || "Unknown error occurred during upload");
|
|
5760
5750
|
}
|
|
5761
|
-
|
|
5751
|
+
} catch (error) {
|
|
5752
|
+
throw fatalError ? new Error(fatalError) : error;
|
|
5762
5753
|
}
|
|
5763
5754
|
}
|
|
5764
|
-
async function
|
|
5755
|
+
async function completeChunkUpload(sessionId, deviceId, options = {}) {
|
|
5756
|
+
var _a2;
|
|
5765
5757
|
try {
|
|
5766
|
-
const
|
|
5767
|
-
const
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5758
|
+
const requestBody = { session_id: sessionId, uid: deviceId };
|
|
5759
|
+
const projectName = (_a2 = options.projectName) == null ? void 0 : _a2.trim();
|
|
5760
|
+
let authHeaders = {};
|
|
5761
|
+
if (options.importAsCar) {
|
|
5762
|
+
requestBody.import_as_car = true;
|
|
5763
|
+
}
|
|
5764
|
+
if (projectName) {
|
|
5765
|
+
requestBody.project_name = projectName;
|
|
5766
|
+
authHeaders = getAuthHeaders();
|
|
5767
|
+
}
|
|
5768
|
+
const response = await axios_default.post(
|
|
5769
|
+
`${IPFS_API_URL}/chunk/complete`,
|
|
5770
|
+
requestBody,
|
|
5773
5771
|
{
|
|
5772
|
+
timeout: TIMEOUT,
|
|
5774
5773
|
headers: {
|
|
5775
|
-
"
|
|
5776
|
-
|
|
5774
|
+
"Content-Type": "application/json",
|
|
5775
|
+
...authHeaders
|
|
5777
5776
|
}
|
|
5778
5777
|
}
|
|
5779
5778
|
);
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
showTokenExpiredHint();
|
|
5784
|
-
throw new Error("Token expired");
|
|
5779
|
+
const { code, msg, data } = response.data;
|
|
5780
|
+
if (code === 200 && data) {
|
|
5781
|
+
return data.trace_id;
|
|
5785
5782
|
}
|
|
5786
|
-
throw
|
|
5783
|
+
throw new Error(`Complete upload failed: ${msg} (code: ${code})`);
|
|
5784
|
+
} catch (error) {
|
|
5785
|
+
if (axios_default.isAxiosError(error)) {
|
|
5786
|
+
throw new Error(`Network error: ${error.message}`);
|
|
5787
|
+
}
|
|
5788
|
+
throw error;
|
|
5787
5789
|
}
|
|
5788
5790
|
}
|
|
5789
|
-
async function
|
|
5791
|
+
async function getChunkStatus(sessionId, deviceId, options = {}) {
|
|
5792
|
+
var _a2;
|
|
5790
5793
|
try {
|
|
5791
|
-
const
|
|
5792
|
-
const
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
"x-token-address": tokenAddress
|
|
5796
|
-
}
|
|
5794
|
+
const projectName = (_a2 = options.projectName) == null ? void 0 : _a2.trim();
|
|
5795
|
+
const queryParams = new URLSearchParams({
|
|
5796
|
+
trace_id: sessionId,
|
|
5797
|
+
uid: deviceId
|
|
5797
5798
|
});
|
|
5798
|
-
|
|
5799
|
-
|
|
5800
|
-
if (isTokenExpired(e)) {
|
|
5801
|
-
showTokenExpiredHint();
|
|
5802
|
-
throw new Error("Token expired");
|
|
5799
|
+
if (projectName) {
|
|
5800
|
+
queryParams.append("project_name", projectName);
|
|
5803
5801
|
}
|
|
5804
|
-
|
|
5802
|
+
const response = await axios_default.get(
|
|
5803
|
+
`${IPFS_API_URL}/up_status?${queryParams.toString()}`,
|
|
5804
|
+
{
|
|
5805
|
+
timeout: TIMEOUT,
|
|
5806
|
+
headers: { "Content-Type": "application/json" }
|
|
5807
|
+
}
|
|
5808
|
+
);
|
|
5809
|
+
const { code, msg, data } = response.data;
|
|
5810
|
+
if (code === 200) {
|
|
5811
|
+
return data;
|
|
5812
|
+
}
|
|
5813
|
+
throw new Error(`Server returned error: ${msg} (code: ${code})`);
|
|
5814
|
+
} catch (error) {
|
|
5815
|
+
if (axios_default.isAxiosError(error)) {
|
|
5816
|
+
throw new Error(`Network error: ${error.message}`);
|
|
5817
|
+
}
|
|
5818
|
+
throw error;
|
|
5805
5819
|
}
|
|
5806
5820
|
}
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
} catch (e) {
|
|
5821
|
+
async function monitorChunkProgress(traceId, deviceId, options = {}, progressBar) {
|
|
5822
|
+
let consecutiveErrors = 0;
|
|
5823
|
+
const startTime = Date.now();
|
|
5824
|
+
if (progressBar) {
|
|
5825
|
+
progressBar.startSimulatingProgress();
|
|
5813
5826
|
}
|
|
5814
|
-
return axios_default.create({
|
|
5815
|
-
baseURL: CAR_API_BASE,
|
|
5816
|
-
timeout: 2e4,
|
|
5817
|
-
headers: {
|
|
5818
|
-
...headers,
|
|
5819
|
-
Accept: "*/*",
|
|
5820
|
-
"Content-Type": "application/json",
|
|
5821
|
-
"User-Agent": "Pinme-CLI",
|
|
5822
|
-
Connection: "keep-alive"
|
|
5823
|
-
}
|
|
5824
|
-
});
|
|
5825
|
-
}
|
|
5826
|
-
async function requestCarExport(cid, uid) {
|
|
5827
|
-
var _a, _b;
|
|
5828
5827
|
try {
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5828
|
+
while (Date.now() - startTime < MAX_POLL_TIME) {
|
|
5829
|
+
try {
|
|
5830
|
+
const status = await getChunkStatus(traceId, deviceId, options);
|
|
5831
|
+
consecutiveErrors = 0;
|
|
5832
|
+
if (status.is_ready && status.upload_rst.Hash) {
|
|
5833
|
+
if (progressBar) {
|
|
5834
|
+
progressBar.stopSimulatingProgress();
|
|
5835
|
+
}
|
|
5836
|
+
const shortUrl = status.upload_rst.ShortUrl;
|
|
5837
|
+
const domain = status.domain;
|
|
5838
|
+
const fullShortUrl = shortUrl && domain ? `${shortUrl}.${domain}` : shortUrl;
|
|
5839
|
+
return {
|
|
5840
|
+
hash: status.upload_rst.Hash,
|
|
5841
|
+
shortUrl: fullShortUrl
|
|
5842
|
+
};
|
|
5843
|
+
}
|
|
5844
|
+
} catch (error) {
|
|
5845
|
+
consecutiveErrors++;
|
|
5846
|
+
if (consecutiveErrors > 10) {
|
|
5847
|
+
throw new Error(`Polling failed: ${error.message}`);
|
|
5848
|
+
}
|
|
5834
5849
|
}
|
|
5835
|
-
|
|
5836
|
-
if ((data == null ? void 0 : data.code) === 200 && (data == null ? void 0 : data.data)) {
|
|
5837
|
-
return data.data;
|
|
5850
|
+
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL));
|
|
5838
5851
|
}
|
|
5839
|
-
|
|
5840
|
-
|
|
5841
|
-
|
|
5842
|
-
|
|
5843
|
-
|
|
5852
|
+
const maxPollTimeMinutes = Math.floor(MAX_POLL_TIME / (60 * 1e3));
|
|
5853
|
+
throw new Error(`Polling timeout after ${maxPollTimeMinutes} minutes`);
|
|
5854
|
+
} finally {
|
|
5855
|
+
if (progressBar) {
|
|
5856
|
+
progressBar.stopSimulatingProgress();
|
|
5844
5857
|
}
|
|
5845
|
-
|
|
5846
|
-
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5860
|
+
async function uploadDirectoryInChunks(directoryPath, deviceId, options = {}) {
|
|
5861
|
+
const sizeCheck = checkDirectorySizeLimit(directoryPath);
|
|
5862
|
+
if (sizeCheck.exceeds) {
|
|
5863
|
+
throw new Error(
|
|
5864
|
+
`Directory ${directoryPath} exceeds size limit ${formatSize(
|
|
5865
|
+
sizeCheck.limit
|
|
5866
|
+
)} (size: ${formatSize(sizeCheck.size)})`
|
|
5867
|
+
);
|
|
5868
|
+
}
|
|
5869
|
+
const progressBar = new StepProgressBar(import_path6.default.basename(directoryPath), true);
|
|
5870
|
+
try {
|
|
5871
|
+
progressBar.startStep(0, "Preparing compression");
|
|
5872
|
+
const compressedPath = await compressDirectory(directoryPath);
|
|
5873
|
+
progressBar.completeStep();
|
|
5874
|
+
progressBar.startStep(1, "Initializing session");
|
|
5875
|
+
const sessionInfo = await initChunkSession(compressedPath, deviceId, true);
|
|
5876
|
+
progressBar.completeStep();
|
|
5877
|
+
progressBar.startStep(2, "Chunk upload");
|
|
5878
|
+
await uploadFileChunks(
|
|
5879
|
+
compressedPath,
|
|
5880
|
+
sessionInfo.session_id,
|
|
5881
|
+
sessionInfo.total_chunks,
|
|
5882
|
+
sessionInfo.chunk_size,
|
|
5883
|
+
deviceId,
|
|
5884
|
+
progressBar
|
|
5885
|
+
);
|
|
5886
|
+
progressBar.completeStep();
|
|
5887
|
+
progressBar.startStep(3, "Completing upload");
|
|
5888
|
+
const traceId = await completeChunkUpload(
|
|
5889
|
+
sessionInfo.session_id,
|
|
5890
|
+
deviceId,
|
|
5891
|
+
options
|
|
5892
|
+
);
|
|
5893
|
+
progressBar.completeStep();
|
|
5894
|
+
progressBar.startStep(4, "Waiting for processing");
|
|
5895
|
+
const result = await monitorChunkProgress(traceId, deviceId, options, progressBar);
|
|
5896
|
+
progressBar.completeStep();
|
|
5897
|
+
try {
|
|
5898
|
+
import_fs_extra5.default.unlinkSync(compressedPath);
|
|
5899
|
+
} catch (error) {
|
|
5900
|
+
}
|
|
5901
|
+
const uploadData = {
|
|
5902
|
+
path: directoryPath,
|
|
5903
|
+
filename: import_path6.default.basename(directoryPath),
|
|
5904
|
+
contentHash: (result == null ? void 0 : result.hash) || "unknown",
|
|
5905
|
+
size: sizeCheck.size,
|
|
5906
|
+
fileCount: 0,
|
|
5907
|
+
isDirectory: true,
|
|
5908
|
+
shortUrl: (result == null ? void 0 : result.shortUrl) || null
|
|
5909
|
+
};
|
|
5910
|
+
saveUploadHistory(uploadData);
|
|
5911
|
+
if (!(result == null ? void 0 : result.hash)) {
|
|
5912
|
+
throw new Error("Server did not return valid hash value");
|
|
5847
5913
|
}
|
|
5848
|
-
|
|
5914
|
+
progressBar.complete();
|
|
5915
|
+
return result;
|
|
5916
|
+
} catch (error) {
|
|
5917
|
+
progressBar.fail(error.message);
|
|
5918
|
+
throw error;
|
|
5849
5919
|
}
|
|
5850
5920
|
}
|
|
5851
|
-
async function
|
|
5852
|
-
|
|
5921
|
+
async function uploadFileInChunks(filePath, deviceId, options = {}) {
|
|
5922
|
+
const sizeCheck = checkFileSizeLimit(filePath);
|
|
5923
|
+
if (sizeCheck.exceeds) {
|
|
5924
|
+
throw new Error(
|
|
5925
|
+
`File ${filePath} exceeds size limit ${formatSize(
|
|
5926
|
+
sizeCheck.limit
|
|
5927
|
+
)} (size: ${formatSize(sizeCheck.size)})`
|
|
5928
|
+
);
|
|
5929
|
+
}
|
|
5930
|
+
const fileName = import_path6.default.basename(filePath);
|
|
5931
|
+
const progressBar = new StepProgressBar(fileName, false);
|
|
5853
5932
|
try {
|
|
5854
|
-
|
|
5855
|
-
const
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5933
|
+
progressBar.startStep(0, "Initializing session");
|
|
5934
|
+
const sessionInfo = await initChunkSession(filePath, deviceId, false);
|
|
5935
|
+
progressBar.completeStep();
|
|
5936
|
+
progressBar.startStep(1, "Chunk upload");
|
|
5937
|
+
await uploadFileChunks(
|
|
5938
|
+
filePath,
|
|
5939
|
+
sessionInfo.session_id,
|
|
5940
|
+
sessionInfo.total_chunks,
|
|
5941
|
+
sessionInfo.chunk_size,
|
|
5942
|
+
deviceId,
|
|
5943
|
+
progressBar
|
|
5862
5944
|
);
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5945
|
+
progressBar.completeStep();
|
|
5946
|
+
progressBar.startStep(2, "Completing upload");
|
|
5947
|
+
const traceId = await completeChunkUpload(
|
|
5948
|
+
sessionInfo.session_id,
|
|
5949
|
+
deviceId,
|
|
5950
|
+
options
|
|
5951
|
+
);
|
|
5952
|
+
progressBar.completeStep();
|
|
5953
|
+
progressBar.startStep(3, "Waiting for processing");
|
|
5954
|
+
const result = await monitorChunkProgress(traceId, deviceId, options, progressBar);
|
|
5955
|
+
progressBar.completeStep();
|
|
5956
|
+
const uploadData = {
|
|
5957
|
+
path: filePath,
|
|
5958
|
+
filename: fileName,
|
|
5959
|
+
contentHash: (result == null ? void 0 : result.hash) || "unknown",
|
|
5960
|
+
previewHash: null,
|
|
5961
|
+
size: sizeCheck.size,
|
|
5962
|
+
fileCount: 1,
|
|
5963
|
+
isDirectory: false,
|
|
5964
|
+
shortUrl: (result == null ? void 0 : result.shortUrl) || null
|
|
5965
|
+
};
|
|
5966
|
+
saveUploadHistory(uploadData);
|
|
5967
|
+
if (!(result == null ? void 0 : result.hash)) {
|
|
5968
|
+
throw new Error("Server did not return valid hash value");
|
|
5871
5969
|
}
|
|
5872
|
-
|
|
5873
|
-
|
|
5970
|
+
progressBar.complete();
|
|
5971
|
+
return result;
|
|
5972
|
+
} catch (error) {
|
|
5973
|
+
progressBar.fail(error.message);
|
|
5974
|
+
throw error;
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
async function uploadToIpfsSplit_default(filePath, options = {}) {
|
|
5978
|
+
const deviceId = getUid();
|
|
5979
|
+
if (!deviceId) {
|
|
5980
|
+
throw new Error("Device ID not found");
|
|
5981
|
+
}
|
|
5982
|
+
try {
|
|
5983
|
+
const isDirectory = import_fs_extra5.default.statSync(filePath).isDirectory();
|
|
5984
|
+
const result = isDirectory ? await uploadDirectoryInChunks(filePath, deviceId, options) : await uploadFileInChunks(filePath, deviceId, options);
|
|
5985
|
+
if (result == null ? void 0 : result.hash) {
|
|
5986
|
+
return {
|
|
5987
|
+
contentHash: result.hash,
|
|
5988
|
+
previewHash: null,
|
|
5989
|
+
shortUrl: result.shortUrl
|
|
5990
|
+
};
|
|
5874
5991
|
}
|
|
5875
|
-
throw new Error(
|
|
5992
|
+
throw new Error("Upload failed: no hash returned");
|
|
5993
|
+
} catch (error) {
|
|
5994
|
+
throw error;
|
|
5876
5995
|
}
|
|
5877
5996
|
}
|
|
5878
5997
|
|
|
5879
|
-
// bin/
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5998
|
+
// bin/services/uploadService.ts
|
|
5999
|
+
function encryptHash(contentHash, key, uid) {
|
|
6000
|
+
if (!key) {
|
|
6001
|
+
return contentHash;
|
|
6002
|
+
}
|
|
6003
|
+
const combined = uid ? `${contentHash}-${uid}` : contentHash;
|
|
6004
|
+
const encrypted = import_crypto_js.default.RC4.encrypt(combined, key).toString();
|
|
6005
|
+
return encrypted.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
5885
6006
|
}
|
|
5886
|
-
function
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
const parts = cleanDomain.split(".");
|
|
5890
|
-
if (parts.length < 2) {
|
|
5891
|
-
return { valid: false, message: "Invalid domain format. Please enter a complete domain (e.g., example.com)" };
|
|
6007
|
+
function formatShortUrl(shortUrl) {
|
|
6008
|
+
if (!shortUrl) {
|
|
6009
|
+
return void 0;
|
|
5892
6010
|
}
|
|
5893
|
-
|
|
5894
|
-
|
|
5895
|
-
|
|
5896
|
-
}
|
|
5897
|
-
if (part.length > 63) {
|
|
5898
|
-
return { valid: false, message: "Invalid domain format. Each label must be 63 characters or less" };
|
|
5899
|
-
}
|
|
5900
|
-
if (!/^[a-zA-Z0-9-]+$/.test(part)) {
|
|
5901
|
-
return { valid: false, message: "Invalid domain format. Domains can only contain letters, numbers, and hyphens" };
|
|
5902
|
-
}
|
|
5903
|
-
if (/^-|-$/.test(part)) {
|
|
5904
|
-
return { valid: false, message: "Invalid domain format. Labels cannot start or end with hyphens" };
|
|
5905
|
-
}
|
|
6011
|
+
const normalized = shortUrl.trim();
|
|
6012
|
+
if (!normalized) {
|
|
6013
|
+
return void 0;
|
|
5906
6014
|
}
|
|
5907
|
-
if (
|
|
5908
|
-
return
|
|
6015
|
+
if (/^https?:\/\//.test(normalized)) {
|
|
6016
|
+
return normalized;
|
|
5909
6017
|
}
|
|
5910
|
-
|
|
6018
|
+
if (normalized.includes(".")) {
|
|
6019
|
+
return `https://${normalized}`;
|
|
6020
|
+
}
|
|
6021
|
+
return `https://${normalized}.pinit.eth.limo`;
|
|
5911
6022
|
}
|
|
5912
|
-
function
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
6023
|
+
function resolveUploadUrls(contentHash, shortUrl) {
|
|
6024
|
+
const uid = getUid();
|
|
6025
|
+
const encryptedCID = encryptHash(contentHash, APP_CONFIG.secretKey, uid);
|
|
6026
|
+
const managementUrl = `${APP_CONFIG.ipfsPreviewUrl}${encryptedCID}`;
|
|
6027
|
+
const publicUrl = formatShortUrl(shortUrl) || managementUrl;
|
|
6028
|
+
return {
|
|
6029
|
+
publicUrl,
|
|
6030
|
+
managementUrl
|
|
6031
|
+
};
|
|
6032
|
+
}
|
|
6033
|
+
async function uploadPath(targetPath, options = {}) {
|
|
6034
|
+
const result = await uploadToIpfsSplit_default(targetPath, {
|
|
6035
|
+
importAsCar: options.importAsCar,
|
|
6036
|
+
projectName: options.projectName
|
|
6037
|
+
});
|
|
6038
|
+
if (!(result == null ? void 0 : result.contentHash)) {
|
|
6039
|
+
throw new Error("Upload failed: no content hash returned");
|
|
5924
6040
|
}
|
|
6041
|
+
const urls = resolveUploadUrls(result.contentHash, result.shortUrl);
|
|
6042
|
+
return {
|
|
6043
|
+
contentHash: result.contentHash,
|
|
6044
|
+
shortUrl: result.shortUrl,
|
|
6045
|
+
publicUrl: urls.publicUrl,
|
|
6046
|
+
managementUrl: urls.managementUrl
|
|
6047
|
+
};
|
|
5925
6048
|
}
|
|
6049
|
+
|
|
6050
|
+
// bin/upload.ts
|
|
6051
|
+
checkNodeVersion();
|
|
5926
6052
|
function checkPathSync(inputPath) {
|
|
5927
6053
|
try {
|
|
5928
6054
|
const absolutePath = import_path7.default.resolve(inputPath);
|
|
@@ -5935,30 +6061,18 @@ function checkPathSync(inputPath) {
|
|
|
5935
6061
|
return null;
|
|
5936
6062
|
}
|
|
5937
6063
|
}
|
|
5938
|
-
function formatEnsUrl(shortUrl) {
|
|
5939
|
-
if (!shortUrl) return "";
|
|
5940
|
-
const normalized = shortUrl.trim();
|
|
5941
|
-
if (!normalized) return "";
|
|
5942
|
-
if (/^https?:\/\//.test(normalized)) return normalized;
|
|
5943
|
-
if (normalized.includes(".")) return `https://${normalized}`;
|
|
5944
|
-
return `https://${normalized}.pinit.eth.limo`;
|
|
5945
|
-
}
|
|
5946
6064
|
function printUploadUrls(contentHash, shortUrl) {
|
|
5947
|
-
|
|
5948
|
-
const
|
|
5949
|
-
const encryptedCID = encryptHash(contentHash, secretKey, uid);
|
|
5950
|
-
const previewUrl = `${URL3}${encryptedCID}`;
|
|
5951
|
-
const projectName = (_a = process.env.PINME_PROJECT_NAME) == null ? void 0 : _a.trim();
|
|
6065
|
+
const projectName = APP_CONFIG.pinmeProjectName;
|
|
6066
|
+
const { publicUrl, managementUrl } = resolveUploadUrls(contentHash, shortUrl);
|
|
5952
6067
|
if (projectName) {
|
|
5953
|
-
const ensUrl = formatEnsUrl(shortUrl);
|
|
5954
6068
|
console.log(import_chalk5.default.cyan(`URL:`));
|
|
5955
|
-
console.log(import_chalk5.default.cyan(
|
|
6069
|
+
console.log(import_chalk5.default.cyan(publicUrl));
|
|
5956
6070
|
console.log(import_chalk5.default.cyan(`Management page:`));
|
|
5957
|
-
console.log(import_chalk5.default.cyan(
|
|
6071
|
+
console.log(import_chalk5.default.cyan(managementUrl));
|
|
5958
6072
|
return;
|
|
5959
6073
|
}
|
|
5960
6074
|
console.log(import_chalk5.default.cyan(`URL:`));
|
|
5961
|
-
console.log(import_chalk5.default.cyan(
|
|
6075
|
+
console.log(import_chalk5.default.cyan(publicUrl));
|
|
5962
6076
|
}
|
|
5963
6077
|
function getDomainFromArgs() {
|
|
5964
6078
|
const args = process.argv.slice(2);
|
|
@@ -5972,26 +6086,27 @@ function getDnsFromArgs() {
|
|
|
5972
6086
|
const args = process.argv.slice(2);
|
|
5973
6087
|
return args.includes("--dns") || args.includes("-D");
|
|
5974
6088
|
}
|
|
5975
|
-
async function
|
|
5976
|
-
var
|
|
5977
|
-
console.log(import_chalk5.default.blue("Checking
|
|
6089
|
+
async function checkWalletBalanceStatus(authConfig) {
|
|
6090
|
+
var _a2;
|
|
6091
|
+
console.log(import_chalk5.default.blue("Checking wallet balance..."));
|
|
5978
6092
|
try {
|
|
5979
|
-
const
|
|
5980
|
-
|
|
6093
|
+
const balanceResult = await getWalletBalance(authConfig.address, authConfig.token);
|
|
6094
|
+
const balance = Number(((_a2 = balanceResult.data) == null ? void 0 : _a2.wallet_balance_usd) ?? 0);
|
|
6095
|
+
if (!Number.isFinite(balance) || balance <= 0) {
|
|
5981
6096
|
return false;
|
|
5982
6097
|
}
|
|
5983
|
-
console.log(import_chalk5.default.green(
|
|
6098
|
+
console.log(import_chalk5.default.green(`Wallet balance available: $${balance.toFixed(2)}`));
|
|
5984
6099
|
return true;
|
|
5985
6100
|
} catch (e) {
|
|
5986
6101
|
if (e.message === "Token expired") {
|
|
5987
6102
|
throw e;
|
|
5988
6103
|
}
|
|
5989
|
-
console.log(import_chalk5.default.yellow("Failed to check
|
|
6104
|
+
console.log(import_chalk5.default.yellow("Failed to check wallet balance, continuing..."));
|
|
5990
6105
|
return true;
|
|
5991
6106
|
}
|
|
5992
6107
|
}
|
|
5993
6108
|
async function bindDomain(domain, contentHash, isDns, authConfig) {
|
|
5994
|
-
const displayDomain = domain
|
|
6109
|
+
const displayDomain = normalizeDomain(domain);
|
|
5995
6110
|
if (isDns) {
|
|
5996
6111
|
console.log(import_chalk5.default.blue("Binding DNS domain..."));
|
|
5997
6112
|
const dnsResult = await bindDnsDomainV4(displayDomain, contentHash, authConfig.address, authConfig.token);
|
|
@@ -6030,7 +6145,7 @@ var upload_default = async (options) => {
|
|
|
6030
6145
|
const needsAuth = !!domainArg || dnsArg;
|
|
6031
6146
|
let authConfig = null;
|
|
6032
6147
|
if (needsAuth) {
|
|
6033
|
-
authConfig =
|
|
6148
|
+
authConfig = getAuthConfig();
|
|
6034
6149
|
if (!authConfig) {
|
|
6035
6150
|
console.log(import_chalk5.default.red("Please login first. Run: pinme set-appkey <AppKey>"));
|
|
6036
6151
|
return;
|
|
@@ -6054,9 +6169,9 @@ var upload_default = async (options) => {
|
|
|
6054
6169
|
}
|
|
6055
6170
|
if (domainArg) {
|
|
6056
6171
|
try {
|
|
6057
|
-
const
|
|
6058
|
-
if (!
|
|
6059
|
-
console.log(import_chalk5.default.red("
|
|
6172
|
+
const hasWalletBalance = await checkWalletBalanceStatus(authConfig);
|
|
6173
|
+
if (!hasWalletBalance) {
|
|
6174
|
+
console.log(import_chalk5.default.red("Insufficient wallet balance. Please recharge your wallet first."));
|
|
6060
6175
|
return;
|
|
6061
6176
|
}
|
|
6062
6177
|
} catch (e) {
|
|
@@ -6088,7 +6203,9 @@ var upload_default = async (options) => {
|
|
|
6088
6203
|
console.log(import_chalk5.default.blue(`uploading ${absolutePath} to ipfs...`));
|
|
6089
6204
|
let result;
|
|
6090
6205
|
try {
|
|
6091
|
-
result = await
|
|
6206
|
+
result = await uploadPath(absolutePath, {
|
|
6207
|
+
projectName: APP_CONFIG.pinmeProjectName
|
|
6208
|
+
});
|
|
6092
6209
|
} catch (error) {
|
|
6093
6210
|
console.error(import_chalk5.default.red(`Upload error: ${error.message}`));
|
|
6094
6211
|
process.exit(1);
|
|
@@ -6145,9 +6262,9 @@ var upload_default = async (options) => {
|
|
|
6145
6262
|
}
|
|
6146
6263
|
if (domainArg) {
|
|
6147
6264
|
try {
|
|
6148
|
-
const
|
|
6149
|
-
if (!
|
|
6150
|
-
console.log(import_chalk5.default.red("
|
|
6265
|
+
const hasWalletBalance = await checkWalletBalanceStatus(authConfig);
|
|
6266
|
+
if (!hasWalletBalance) {
|
|
6267
|
+
console.log(import_chalk5.default.red("Insufficient wallet balance. Please recharge your wallet first."));
|
|
6151
6268
|
return;
|
|
6152
6269
|
}
|
|
6153
6270
|
} catch (e) {
|
|
@@ -6179,7 +6296,9 @@ var upload_default = async (options) => {
|
|
|
6179
6296
|
console.log(import_chalk5.default.blue(`uploading ${absolutePath} to ipfs...`));
|
|
6180
6297
|
let result;
|
|
6181
6298
|
try {
|
|
6182
|
-
result = await
|
|
6299
|
+
result = await uploadPath(absolutePath, {
|
|
6300
|
+
projectName: APP_CONFIG.pinmeProjectName
|
|
6301
|
+
});
|
|
6183
6302
|
} catch (error) {
|
|
6184
6303
|
console.error(import_chalk5.default.red(`Upload error: ${error.message}`));
|
|
6185
6304
|
process.exit(1);
|
|
@@ -6225,8 +6344,6 @@ var import_inquirer2 = __toESM(require("inquirer"));
|
|
|
6225
6344
|
var import_figlet2 = __toESM(require("figlet"));
|
|
6226
6345
|
var import_fs3 = __toESM(require("fs"));
|
|
6227
6346
|
var import_crypto_js2 = __toESM(require("crypto-js"));
|
|
6228
|
-
var URL4 = "https://pinme.eth.limo/#/preview/";
|
|
6229
|
-
var secretKey2 = "pinme-secret-key";
|
|
6230
6347
|
checkNodeVersion();
|
|
6231
6348
|
function encryptHash2(contentHash, key, uid) {
|
|
6232
6349
|
try {
|
|
@@ -6263,7 +6380,7 @@ function getDomainFromArgs2() {
|
|
|
6263
6380
|
return null;
|
|
6264
6381
|
}
|
|
6265
6382
|
function getUid2() {
|
|
6266
|
-
const auth =
|
|
6383
|
+
const auth = getAuthConfig();
|
|
6267
6384
|
if (auth == null ? void 0 : auth.address) {
|
|
6268
6385
|
return auth.address;
|
|
6269
6386
|
}
|
|
@@ -6298,17 +6415,17 @@ var importCar_default = async (options) => {
|
|
|
6298
6415
|
}
|
|
6299
6416
|
console.log(import_chalk6.default.blue(`importing ${absolutePath} to ipfs as CAR...`));
|
|
6300
6417
|
try {
|
|
6301
|
-
const result = await
|
|
6418
|
+
const result = await uploadPath(absolutePath, { importAsCar: true });
|
|
6302
6419
|
if (result) {
|
|
6303
6420
|
const uid = getUid2();
|
|
6304
|
-
const encryptedCID = encryptHash2(result.contentHash,
|
|
6421
|
+
const encryptedCID = encryptHash2(result.contentHash, APP_CONFIG.secretKey, uid);
|
|
6305
6422
|
console.log(
|
|
6306
6423
|
import_chalk6.default.cyan(
|
|
6307
6424
|
import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
|
|
6308
6425
|
)
|
|
6309
6426
|
);
|
|
6310
6427
|
console.log(import_chalk6.default.cyan(`URL:`));
|
|
6311
|
-
console.log(import_chalk6.default.cyan(`${
|
|
6428
|
+
console.log(import_chalk6.default.cyan(`${APP_CONFIG.ipfsPreviewUrl}${encryptedCID}`));
|
|
6312
6429
|
if (domainArg) {
|
|
6313
6430
|
console.log(import_chalk6.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
|
|
6314
6431
|
const ok = await bindPinmeDomain(domainArg, result.contentHash);
|
|
@@ -6349,17 +6466,17 @@ var importCar_default = async (options) => {
|
|
|
6349
6466
|
}
|
|
6350
6467
|
console.log(import_chalk6.default.blue(`importing ${absolutePath} to ipfs as CAR...`));
|
|
6351
6468
|
try {
|
|
6352
|
-
const result = await
|
|
6469
|
+
const result = await uploadPath(absolutePath, { importAsCar: true });
|
|
6353
6470
|
if (result) {
|
|
6354
6471
|
const uid = getUid2();
|
|
6355
|
-
const encryptedCID = encryptHash2(result.contentHash,
|
|
6472
|
+
const encryptedCID = encryptHash2(result.contentHash, APP_CONFIG.secretKey, uid);
|
|
6356
6473
|
console.log(
|
|
6357
6474
|
import_chalk6.default.cyan(
|
|
6358
6475
|
import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
|
|
6359
6476
|
)
|
|
6360
6477
|
);
|
|
6361
6478
|
console.log(import_chalk6.default.cyan(`URL:`));
|
|
6362
|
-
console.log(import_chalk6.default.cyan(`${
|
|
6479
|
+
console.log(import_chalk6.default.cyan(`${APP_CONFIG.ipfsPreviewUrl}${encryptedCID}`));
|
|
6363
6480
|
if (domainArg) {
|
|
6364
6481
|
console.log(import_chalk6.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
|
|
6365
6482
|
const ok = await bindPinmeDomain(domainArg, result.contentHash);
|
|
@@ -6597,7 +6714,7 @@ var import_figlet4 = __toESM(require("figlet"));
|
|
|
6597
6714
|
|
|
6598
6715
|
// bin/utils/removeFromIpfs.ts
|
|
6599
6716
|
var import_chalk8 = __toESM(require("chalk"));
|
|
6600
|
-
var ipfsApiUrl =
|
|
6717
|
+
var ipfsApiUrl = APP_CONFIG.ipfsApiUrl;
|
|
6601
6718
|
async function removeFromIpfs(value, type = "hash") {
|
|
6602
6719
|
try {
|
|
6603
6720
|
const uid = getUid();
|
|
@@ -6851,7 +6968,7 @@ var import_chalk11 = __toESM(require("chalk"));
|
|
|
6851
6968
|
var import_inquirer6 = __toESM(require("inquirer"));
|
|
6852
6969
|
async function logoutCmd() {
|
|
6853
6970
|
try {
|
|
6854
|
-
const auth =
|
|
6971
|
+
const auth = getAuthConfig();
|
|
6855
6972
|
if (!auth) {
|
|
6856
6973
|
console.log(import_chalk11.default.yellow("No active session found. You are already logged out."));
|
|
6857
6974
|
return;
|
|
@@ -6880,7 +6997,7 @@ async function logoutCmd() {
|
|
|
6880
6997
|
var import_chalk12 = __toESM(require("chalk"));
|
|
6881
6998
|
function showAppKeyCmd() {
|
|
6882
6999
|
try {
|
|
6883
|
-
const auth =
|
|
7000
|
+
const auth = getAuthConfig();
|
|
6884
7001
|
if (!auth) {
|
|
6885
7002
|
console.log(import_chalk12.default.yellow("No AppKey found. Please set your AppKey first."));
|
|
6886
7003
|
console.log(import_chalk12.default.gray("Run: pinme set-appkey <AppKey>"));
|
|
@@ -6936,39 +7053,33 @@ async function myDomainsCmd() {
|
|
|
6936
7053
|
}
|
|
6937
7054
|
}
|
|
6938
7055
|
|
|
6939
|
-
// bin/
|
|
6940
|
-
var import_path10 = __toESM(require("path"));
|
|
7056
|
+
// bin/wallet-balance.ts
|
|
6941
7057
|
var import_chalk14 = __toESM(require("chalk"));
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
const parts = cleanDomain.split(".");
|
|
6950
|
-
if (parts.length < 2) {
|
|
6951
|
-
return { valid: false, message: "Invalid domain format. Please enter a complete domain (e.g., example.com)" };
|
|
6952
|
-
}
|
|
6953
|
-
for (const part of parts) {
|
|
6954
|
-
if (part.length === 0) {
|
|
6955
|
-
return { valid: false, message: "Invalid domain format. Consecutive dots are not allowed" };
|
|
6956
|
-
}
|
|
6957
|
-
if (part.length > 63) {
|
|
6958
|
-
return { valid: false, message: "Invalid domain format. Each label must be 63 characters or less" };
|
|
6959
|
-
}
|
|
6960
|
-
if (!/^[a-zA-Z0-9-]+$/.test(part)) {
|
|
6961
|
-
return { valid: false, message: "Invalid domain format. Domains can only contain letters, numbers, and hyphens" };
|
|
7058
|
+
async function walletBalanceCmd() {
|
|
7059
|
+
var _a2;
|
|
7060
|
+
try {
|
|
7061
|
+
const auth = getAuthConfig();
|
|
7062
|
+
if (!auth) {
|
|
7063
|
+
console.log(import_chalk14.default.yellow("Please login first. Run: pinme set-appkey <AppKey>"));
|
|
7064
|
+
return;
|
|
6962
7065
|
}
|
|
6963
|
-
|
|
6964
|
-
|
|
7066
|
+
const result = await getWalletBalance(auth.address, auth.token);
|
|
7067
|
+
const balance = Number(((_a2 = result.data) == null ? void 0 : _a2.wallet_balance_usd) ?? 0);
|
|
7068
|
+
if (!Number.isFinite(balance)) {
|
|
7069
|
+
console.log(import_chalk14.default.red("Failed to parse wallet balance."));
|
|
7070
|
+
return;
|
|
6965
7071
|
}
|
|
7072
|
+
console.log(import_chalk14.default.cyan("Wallet balance:"));
|
|
7073
|
+
console.log(import_chalk14.default.green(` USD: $${balance.toFixed(2)}`));
|
|
7074
|
+
} catch (e) {
|
|
7075
|
+
console.log(import_chalk14.default.red(`Failed to fetch wallet balance: ${(e == null ? void 0 : e.message) || e}`));
|
|
6966
7076
|
}
|
|
6967
|
-
if (!domainRegex.test(cleanDomain)) {
|
|
6968
|
-
return { valid: false, message: "Invalid domain format" };
|
|
6969
|
-
}
|
|
6970
|
-
return { valid: true };
|
|
6971
7077
|
}
|
|
7078
|
+
|
|
7079
|
+
// bin/bind.ts
|
|
7080
|
+
var import_path10 = __toESM(require("path"));
|
|
7081
|
+
var import_chalk15 = __toESM(require("chalk"));
|
|
7082
|
+
var import_inquirer7 = __toESM(require("inquirer"));
|
|
6972
7083
|
function parseArgs() {
|
|
6973
7084
|
const args = process.argv.slice(2);
|
|
6974
7085
|
const res = {};
|
|
@@ -6987,31 +7098,32 @@ function parseArgs() {
|
|
|
6987
7098
|
}
|
|
6988
7099
|
return res;
|
|
6989
7100
|
}
|
|
6990
|
-
async function
|
|
6991
|
-
var
|
|
6992
|
-
console.log(
|
|
7101
|
+
async function checkWalletBalanceStatus2(authConfig) {
|
|
7102
|
+
var _a2;
|
|
7103
|
+
console.log(import_chalk15.default.blue("Checking wallet balance..."));
|
|
6993
7104
|
try {
|
|
6994
|
-
const
|
|
6995
|
-
|
|
7105
|
+
const balanceResult = await getWalletBalance(authConfig.address, authConfig.token);
|
|
7106
|
+
const balance = Number(((_a2 = balanceResult.data) == null ? void 0 : _a2.wallet_balance_usd) ?? 0);
|
|
7107
|
+
if (!Number.isFinite(balance) || balance <= 0) {
|
|
6996
7108
|
return false;
|
|
6997
7109
|
}
|
|
6998
|
-
console.log(
|
|
7110
|
+
console.log(import_chalk15.default.green(`Wallet balance available: $${balance.toFixed(2)}`));
|
|
6999
7111
|
return true;
|
|
7000
7112
|
} catch (e) {
|
|
7001
7113
|
if (e.message === "Token expired") {
|
|
7002
7114
|
throw e;
|
|
7003
7115
|
}
|
|
7004
|
-
console.log(
|
|
7116
|
+
console.log(import_chalk15.default.yellow("Failed to check wallet balance, continuing..."));
|
|
7005
7117
|
return true;
|
|
7006
7118
|
}
|
|
7007
7119
|
}
|
|
7008
7120
|
async function bindCmd() {
|
|
7009
|
-
var
|
|
7121
|
+
var _a2;
|
|
7010
7122
|
try {
|
|
7011
7123
|
let { domain, targetPath, dns } = parseArgs();
|
|
7012
|
-
const authConfig =
|
|
7124
|
+
const authConfig = getAuthConfig();
|
|
7013
7125
|
if (!authConfig) {
|
|
7014
|
-
console.log(
|
|
7126
|
+
console.log(import_chalk15.default.red("Please login first. Run: pinme set-appkey <AppKey>"));
|
|
7015
7127
|
return;
|
|
7016
7128
|
}
|
|
7017
7129
|
if (!targetPath) {
|
|
@@ -7024,25 +7136,25 @@ async function bindCmd() {
|
|
|
7024
7136
|
const ans = await import_inquirer7.default.prompt([
|
|
7025
7137
|
{ type: "input", name: "domain", message: "Enter the domain to bind (e.g., my-site or example.com): " }
|
|
7026
7138
|
]);
|
|
7027
|
-
domain = (
|
|
7139
|
+
domain = (_a2 = ans.domain) == null ? void 0 : _a2.trim();
|
|
7028
7140
|
}
|
|
7029
7141
|
if (!targetPath || !domain) {
|
|
7030
|
-
console.log(
|
|
7142
|
+
console.log(import_chalk15.default.red("Missing parameters. Path and domain are required."));
|
|
7031
7143
|
return;
|
|
7032
7144
|
}
|
|
7033
|
-
const isDns = dns ||
|
|
7034
|
-
const displayDomain = domain
|
|
7145
|
+
const isDns = dns || isDnsDomain(domain);
|
|
7146
|
+
const displayDomain = normalizeDomain(domain);
|
|
7035
7147
|
if (isDns) {
|
|
7036
|
-
const validation =
|
|
7148
|
+
const validation = validateDnsDomain(domain);
|
|
7037
7149
|
if (!validation.valid) {
|
|
7038
|
-
console.log(
|
|
7150
|
+
console.log(import_chalk15.default.red(validation.message));
|
|
7039
7151
|
return;
|
|
7040
7152
|
}
|
|
7041
7153
|
}
|
|
7042
7154
|
try {
|
|
7043
|
-
const
|
|
7044
|
-
if (!
|
|
7045
|
-
console.log(
|
|
7155
|
+
const hasWalletBalance = await checkWalletBalanceStatus2(authConfig);
|
|
7156
|
+
if (!hasWalletBalance) {
|
|
7157
|
+
console.log(import_chalk15.default.red("Insufficient wallet balance. Please recharge your wallet first."));
|
|
7046
7158
|
return;
|
|
7047
7159
|
}
|
|
7048
7160
|
} catch (e) {
|
|
@@ -7054,10 +7166,10 @@ async function bindCmd() {
|
|
|
7054
7166
|
try {
|
|
7055
7167
|
const check = await checkDomainAvailable(displayDomain);
|
|
7056
7168
|
if (!check.is_valid) {
|
|
7057
|
-
console.log(
|
|
7169
|
+
console.log(import_chalk15.default.red(`Domain not available: ${check.error || "unknown reason"}`));
|
|
7058
7170
|
return;
|
|
7059
7171
|
}
|
|
7060
|
-
console.log(
|
|
7172
|
+
console.log(import_chalk15.default.green(`Domain available: ${displayDomain}`));
|
|
7061
7173
|
} catch (e) {
|
|
7062
7174
|
if (e.message === "Token expired") {
|
|
7063
7175
|
return;
|
|
@@ -7065,33 +7177,33 @@ async function bindCmd() {
|
|
|
7065
7177
|
throw e;
|
|
7066
7178
|
}
|
|
7067
7179
|
const absolutePath = import_path10.default.resolve(targetPath);
|
|
7068
|
-
console.log(
|
|
7069
|
-
const up = await
|
|
7180
|
+
console.log(import_chalk15.default.blue(`Uploading: ${absolutePath}`));
|
|
7181
|
+
const up = await uploadPath(absolutePath);
|
|
7070
7182
|
if (!(up == null ? void 0 : up.contentHash)) {
|
|
7071
|
-
console.log(
|
|
7183
|
+
console.log(import_chalk15.default.red("Upload failed, binding aborted."));
|
|
7072
7184
|
return;
|
|
7073
7185
|
}
|
|
7074
|
-
console.log(
|
|
7186
|
+
console.log(import_chalk15.default.green(`Upload success, CID: ${up.contentHash}`));
|
|
7075
7187
|
try {
|
|
7076
7188
|
if (isDns) {
|
|
7077
|
-
console.log(
|
|
7189
|
+
console.log(import_chalk15.default.blue("Binding DNS domain..."));
|
|
7078
7190
|
const dnsResult = await bindDnsDomainV4(displayDomain, up.contentHash, authConfig.address, authConfig.token);
|
|
7079
7191
|
if (dnsResult.code !== 200) {
|
|
7080
|
-
console.log(
|
|
7192
|
+
console.log(import_chalk15.default.red(`DNS binding failed: ${dnsResult.msg}`));
|
|
7081
7193
|
return;
|
|
7082
7194
|
}
|
|
7083
|
-
console.log(
|
|
7084
|
-
console.log(
|
|
7085
|
-
console.log(
|
|
7195
|
+
console.log(import_chalk15.default.green(`DNS bind success: ${displayDomain}`));
|
|
7196
|
+
console.log(import_chalk15.default.white(`Visit: https://${displayDomain}`));
|
|
7197
|
+
console.log(import_chalk15.default.cyan("\n\u{1F4DA} DNS Setup Guide: https://pinme.eth.limo/#/docs?id=custom-domain"));
|
|
7086
7198
|
} else {
|
|
7087
|
-
console.log(
|
|
7199
|
+
console.log(import_chalk15.default.blue("Binding Pinme subdomain..."));
|
|
7088
7200
|
const ok = await bindPinmeDomain(displayDomain, up.contentHash);
|
|
7089
7201
|
if (!ok) {
|
|
7090
|
-
console.log(
|
|
7202
|
+
console.log(import_chalk15.default.red("Binding failed. Please try again later."));
|
|
7091
7203
|
return;
|
|
7092
7204
|
}
|
|
7093
|
-
console.log(
|
|
7094
|
-
console.log(
|
|
7205
|
+
console.log(import_chalk15.default.green(`Bind success: ${displayDomain}`));
|
|
7206
|
+
console.log(import_chalk15.default.white(`Visit: https://${displayDomain}.pinit.eth.limo`));
|
|
7095
7207
|
}
|
|
7096
7208
|
} catch (e) {
|
|
7097
7209
|
if (e.message === "Token expired") {
|
|
@@ -7100,12 +7212,12 @@ async function bindCmd() {
|
|
|
7100
7212
|
throw e;
|
|
7101
7213
|
}
|
|
7102
7214
|
} catch (e) {
|
|
7103
|
-
console.log(
|
|
7215
|
+
console.log(import_chalk15.default.red(`Execution failed: ${(e == null ? void 0 : e.message) || e}`));
|
|
7104
7216
|
}
|
|
7105
7217
|
}
|
|
7106
7218
|
|
|
7107
7219
|
// bin/login.ts
|
|
7108
|
-
var
|
|
7220
|
+
var import_chalk16 = __toESM(require("chalk"));
|
|
7109
7221
|
var ENV_URLS = {
|
|
7110
7222
|
dev: "http://localhost:5173",
|
|
7111
7223
|
test: "http://test-pinme.pinit.eth.limo",
|
|
@@ -7117,30 +7229,30 @@ async function loginCmd(options = {}) {
|
|
|
7117
7229
|
const env = (options.env || "prod").toLowerCase();
|
|
7118
7230
|
if (ENV_URLS[env]) {
|
|
7119
7231
|
webBaseUrl = ENV_URLS[env];
|
|
7120
|
-
console.log(
|
|
7232
|
+
console.log(import_chalk16.default.blue(`Using ${env} environment: ${webBaseUrl}`));
|
|
7121
7233
|
} else {
|
|
7122
|
-
console.log(
|
|
7234
|
+
console.log(import_chalk16.default.yellow(`Unknown environment: ${options.env}. Using default prod.`));
|
|
7123
7235
|
webBaseUrl = ENV_URLS.prod;
|
|
7124
|
-
console.log(
|
|
7236
|
+
console.log(import_chalk16.default.blue(`Using prod environment: ${webBaseUrl}`));
|
|
7125
7237
|
}
|
|
7126
7238
|
const manager = new WebLoginManager({ webBaseUrl });
|
|
7127
7239
|
await manager.login();
|
|
7128
|
-
console.log(
|
|
7240
|
+
console.log(import_chalk16.default.blue("\nMerging history..."));
|
|
7129
7241
|
const deviceId = getDeviceId();
|
|
7130
7242
|
const ok = await bindAnonymousDevice(deviceId);
|
|
7131
7243
|
if (ok) {
|
|
7132
|
-
console.log(
|
|
7244
|
+
console.log(import_chalk16.default.green("History merged to your account"));
|
|
7133
7245
|
}
|
|
7134
7246
|
process.exit(0);
|
|
7135
7247
|
} catch (e) {
|
|
7136
|
-
console.log(
|
|
7248
|
+
console.log(import_chalk16.default.red(`
|
|
7137
7249
|
Login failed: ${(e == null ? void 0 : e.message) || e}`));
|
|
7138
7250
|
process.exit(1);
|
|
7139
7251
|
}
|
|
7140
7252
|
}
|
|
7141
7253
|
|
|
7142
7254
|
// bin/create.ts
|
|
7143
|
-
var
|
|
7255
|
+
var import_chalk19 = __toESM(require("chalk"));
|
|
7144
7256
|
var import_fs_extra7 = __toESM(require("fs-extra"));
|
|
7145
7257
|
var import_path12 = __toESM(require("path"));
|
|
7146
7258
|
var import_inquirer8 = __toESM(require("inquirer"));
|
|
@@ -7150,7 +7262,7 @@ var import_child_process3 = require("child_process");
|
|
|
7150
7262
|
var import_fs_extra6 = __toESM(require("fs-extra"));
|
|
7151
7263
|
var import_os5 = __toESM(require("os"));
|
|
7152
7264
|
var import_path11 = __toESM(require("path"));
|
|
7153
|
-
var
|
|
7265
|
+
var import_chalk17 = __toESM(require("chalk"));
|
|
7154
7266
|
var import_child_process2 = require("child_process");
|
|
7155
7267
|
function makeTempCacheDir() {
|
|
7156
7268
|
return import_fs_extra6.default.mkdtempSync(import_path11.default.join(import_os5.default.tmpdir(), "pinme-npm-cache-"));
|
|
@@ -7173,7 +7285,7 @@ function installProjectDependencies(cwd) {
|
|
|
7173
7285
|
const cacheDir = makeTempCacheDir();
|
|
7174
7286
|
try {
|
|
7175
7287
|
if (attempt > 1) {
|
|
7176
|
-
console.log(
|
|
7288
|
+
console.log(import_chalk17.default.yellow(" Retrying dependency install with a fresh npm cache..."));
|
|
7177
7289
|
}
|
|
7178
7290
|
runInstall(cwd, cacheDir);
|
|
7179
7291
|
return;
|
|
@@ -7187,7 +7299,7 @@ function installProjectDependencies(cwd) {
|
|
|
7187
7299
|
}
|
|
7188
7300
|
|
|
7189
7301
|
// bin/utils/cliError.ts
|
|
7190
|
-
var
|
|
7302
|
+
var import_chalk18 = __toESM(require("chalk"));
|
|
7191
7303
|
var CliError = class extends Error {
|
|
7192
7304
|
stage;
|
|
7193
7305
|
details;
|
|
@@ -7216,8 +7328,8 @@ function stringifyValue(value) {
|
|
|
7216
7328
|
}
|
|
7217
7329
|
}
|
|
7218
7330
|
function getApiMessage(data) {
|
|
7219
|
-
var
|
|
7220
|
-
return ((
|
|
7331
|
+
var _a2, _b, _c;
|
|
7332
|
+
return ((_a2 = data == null ? void 0 : data.data) == null ? void 0 : _a2.error) || ((_c = (_b = data == null ? void 0 : data.errors) == null ? void 0 : _b[0]) == null ? void 0 : _c.message) || (data == null ? void 0 : data.message) || (data == null ? void 0 : data.msg) || (data == null ? void 0 : data.error);
|
|
7221
7333
|
}
|
|
7222
7334
|
function getBusinessCode(data) {
|
|
7223
7335
|
if ((data == null ? void 0 : data.code) === void 0 || (data == null ? void 0 : data.code) === null) {
|
|
@@ -7263,8 +7375,8 @@ function createCommandError(stage, command, error, suggestions = []) {
|
|
|
7263
7375
|
});
|
|
7264
7376
|
}
|
|
7265
7377
|
function createApiError(stage, error, context = [], suggestions = []) {
|
|
7266
|
-
var
|
|
7267
|
-
const status = (
|
|
7378
|
+
var _a2, _b;
|
|
7379
|
+
const status = (_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.status;
|
|
7268
7380
|
const responseData = (_b = error == null ? void 0 : error.response) == null ? void 0 : _b.data;
|
|
7269
7381
|
const errorCode = error == null ? void 0 : error.code;
|
|
7270
7382
|
const apiMessage = getApiMessage(responseData);
|
|
@@ -7318,25 +7430,24 @@ function normalizeCliError(error, fallbackSummary, suggestions = []) {
|
|
|
7318
7430
|
}
|
|
7319
7431
|
function printCliError(error, fallbackSummary) {
|
|
7320
7432
|
const cliError = normalizeCliError(error, fallbackSummary);
|
|
7321
|
-
console.error(
|
|
7433
|
+
console.error(import_chalk18.default.red(`
|
|
7322
7434
|
Error: ${cliError.message}`));
|
|
7323
7435
|
if (cliError.stage) {
|
|
7324
|
-
console.error(
|
|
7436
|
+
console.error(import_chalk18.default.gray(`Stage: ${cliError.stage}`));
|
|
7325
7437
|
}
|
|
7326
7438
|
for (const detail of cliError.details) {
|
|
7327
|
-
console.error(
|
|
7439
|
+
console.error(import_chalk18.default.gray(detail));
|
|
7328
7440
|
}
|
|
7329
7441
|
if (cliError.suggestions.length > 0) {
|
|
7330
|
-
console.error(
|
|
7442
|
+
console.error(import_chalk18.default.yellow("\nNext steps:"));
|
|
7331
7443
|
for (const suggestion of cliError.suggestions) {
|
|
7332
|
-
console.error(
|
|
7444
|
+
console.error(import_chalk18.default.yellow(`- ${suggestion}`));
|
|
7333
7445
|
}
|
|
7334
7446
|
}
|
|
7335
7447
|
}
|
|
7336
7448
|
|
|
7337
7449
|
// bin/create.ts
|
|
7338
7450
|
var PROJECT_DIR = process.cwd();
|
|
7339
|
-
var API_BASE = "https://pinme.benny1996.win/api/v4";
|
|
7340
7451
|
var TEMPLATE_BRANCH = "feat/auth";
|
|
7341
7452
|
var TEMPLATE_REPO = "glitternetwork/pinme-worker-template";
|
|
7342
7453
|
var TEMPLATE_REPO_NAME = TEMPLATE_REPO.split("/").pop() || "pinme-worker-template";
|
|
@@ -7374,8 +7485,24 @@ function resolveExtractedTemplateDir(extractDir) {
|
|
|
7374
7485
|
}
|
|
7375
7486
|
return import_path12.default.join(extractDir, templateDir.name);
|
|
7376
7487
|
}
|
|
7488
|
+
function updateFrontendUrlInConfig(configPath, frontendUrl) {
|
|
7489
|
+
let config = import_fs_extra7.default.readFileSync(configPath, "utf-8");
|
|
7490
|
+
if (config.includes("frontend_url")) {
|
|
7491
|
+
config = config.replace(
|
|
7492
|
+
/frontend_url\s*=\s*"[^"]*"/,
|
|
7493
|
+
`frontend_url = "${frontendUrl}"`
|
|
7494
|
+
);
|
|
7495
|
+
} else {
|
|
7496
|
+
config = config.replace(
|
|
7497
|
+
/(project_name\s*=\s*"[^"]*"\n)/,
|
|
7498
|
+
`$1frontend_url = "${frontendUrl}"
|
|
7499
|
+
`
|
|
7500
|
+
);
|
|
7501
|
+
}
|
|
7502
|
+
import_fs_extra7.default.writeFileSync(configPath, config);
|
|
7503
|
+
}
|
|
7377
7504
|
async function createCmd(options) {
|
|
7378
|
-
var
|
|
7505
|
+
var _a2, _b;
|
|
7379
7506
|
try {
|
|
7380
7507
|
const headers = getAuthHeaders();
|
|
7381
7508
|
if (!headers["authentication-tokens"] || !headers["token-address"]) {
|
|
@@ -7383,7 +7510,7 @@ async function createCmd(options) {
|
|
|
7383
7510
|
"Run `pinme login` and retry."
|
|
7384
7511
|
]);
|
|
7385
7512
|
}
|
|
7386
|
-
console.log(
|
|
7513
|
+
console.log(import_chalk19.default.blue("Creating new project from template...\n"));
|
|
7387
7514
|
let projectName = options.name;
|
|
7388
7515
|
if (!projectName) {
|
|
7389
7516
|
const answers = await import_inquirer8.default.prompt([
|
|
@@ -7404,7 +7531,7 @@ async function createCmd(options) {
|
|
|
7404
7531
|
}
|
|
7405
7532
|
const targetDir = import_path12.default.join(PROJECT_DIR, projectName);
|
|
7406
7533
|
if (import_fs_extra7.default.existsSync(targetDir) && !options.force) {
|
|
7407
|
-
console.log(
|
|
7534
|
+
console.log(import_chalk19.default.yellow(`
|
|
7408
7535
|
Directory "${projectName}" already exists.`));
|
|
7409
7536
|
const answers = await import_inquirer8.default.prompt([
|
|
7410
7537
|
{
|
|
@@ -7415,16 +7542,16 @@ Directory "${projectName}" already exists.`));
|
|
|
7415
7542
|
}
|
|
7416
7543
|
]);
|
|
7417
7544
|
if (!answers.overwrite) {
|
|
7418
|
-
console.log(
|
|
7545
|
+
console.log(import_chalk19.default.gray("Cancelled."));
|
|
7419
7546
|
process.exit(0);
|
|
7420
7547
|
}
|
|
7421
7548
|
import_fs_extra7.default.removeSync(targetDir);
|
|
7422
7549
|
}
|
|
7423
|
-
console.log(
|
|
7424
|
-
const apiUrl =
|
|
7425
|
-
console.log(
|
|
7550
|
+
console.log(import_chalk19.default.blue("\n1. Creating worker and database..."));
|
|
7551
|
+
const apiUrl = getPinmeApiUrl("/create_worker");
|
|
7552
|
+
console.log(import_chalk19.default.gray(`API URL: ${apiUrl}`));
|
|
7426
7553
|
const normalizedProjectName = projectName.toLowerCase();
|
|
7427
|
-
console.log(
|
|
7554
|
+
console.log(import_chalk19.default.gray(`Project name: ${normalizedProjectName}`));
|
|
7428
7555
|
let workerData;
|
|
7429
7556
|
try {
|
|
7430
7557
|
const response = await axios_default.post(apiUrl, {
|
|
@@ -7443,24 +7570,24 @@ Directory "${projectName}" already exists.`));
|
|
|
7443
7570
|
]);
|
|
7444
7571
|
}
|
|
7445
7572
|
workerData = data.data;
|
|
7446
|
-
console.log(
|
|
7447
|
-
console.log(
|
|
7448
|
-
console.log(
|
|
7573
|
+
console.log(import_chalk19.default.gray(` API Response: ${JSON.stringify(workerData)}`));
|
|
7574
|
+
console.log(import_chalk19.default.green(` API Domain: ${workerData.api_domain}`));
|
|
7575
|
+
console.log(import_chalk19.default.green(` Project Name: ${workerData.project_name}`));
|
|
7449
7576
|
} catch (error) {
|
|
7450
7577
|
throw createApiError("project creation", error, [
|
|
7451
7578
|
`Project name: ${normalizedProjectName}`,
|
|
7452
7579
|
`Endpoint: ${apiUrl}`
|
|
7453
7580
|
]);
|
|
7454
7581
|
}
|
|
7455
|
-
console.log(
|
|
7582
|
+
console.log(import_chalk19.default.blue("\n2. Downloading template from repository..."));
|
|
7456
7583
|
const zipPath = import_path12.default.join(PROJECT_DIR, "template.zip");
|
|
7457
7584
|
const extractDir = import_path12.default.join(PROJECT_DIR, `.pinme-template-${Date.now()}`);
|
|
7458
7585
|
const templateZipUrl = getTemplateZipUrl(TEMPLATE_BRANCH);
|
|
7459
7586
|
let downloadSuccess = false;
|
|
7460
|
-
console.log(
|
|
7587
|
+
console.log(import_chalk19.default.gray(` Template branch: ${TEMPLATE_BRANCH}`));
|
|
7461
7588
|
for (let attempt = 1; attempt <= 3 && !downloadSuccess; attempt++) {
|
|
7462
7589
|
try {
|
|
7463
|
-
console.log(
|
|
7590
|
+
console.log(import_chalk19.default.gray(` Download attempt ${attempt}/3...`));
|
|
7464
7591
|
(0, import_child_process3.execSync)(`curl -L --retry 3 --retry-delay 2 -o "${zipPath}" "${templateZipUrl}"`, {
|
|
7465
7592
|
stdio: "inherit"
|
|
7466
7593
|
});
|
|
@@ -7469,7 +7596,7 @@ Directory "${projectName}" already exists.`));
|
|
|
7469
7596
|
}
|
|
7470
7597
|
downloadSuccess = true;
|
|
7471
7598
|
} catch (downloadError) {
|
|
7472
|
-
console.log(
|
|
7599
|
+
console.log(import_chalk19.default.yellow(` Attempt ${attempt} failed: ${downloadError.message}`));
|
|
7473
7600
|
if (import_fs_extra7.default.existsSync(zipPath)) {
|
|
7474
7601
|
import_fs_extra7.default.removeSync(zipPath);
|
|
7475
7602
|
}
|
|
@@ -7490,11 +7617,11 @@ Directory "${projectName}" already exists.`));
|
|
|
7490
7617
|
const nodeModulesPath = import_path12.default.join(targetDir, "node_modules");
|
|
7491
7618
|
const packageLockPath = import_path12.default.join(targetDir, "package-lock.json");
|
|
7492
7619
|
if (import_fs_extra7.default.existsSync(nodeModulesPath)) {
|
|
7493
|
-
console.log(
|
|
7620
|
+
console.log(import_chalk19.default.gray(" Removing existing node_modules..."));
|
|
7494
7621
|
import_fs_extra7.default.removeSync(nodeModulesPath);
|
|
7495
7622
|
}
|
|
7496
7623
|
if (import_fs_extra7.default.existsSync(packageLockPath)) {
|
|
7497
|
-
console.log(
|
|
7624
|
+
console.log(import_chalk19.default.gray(" Removing existing package-lock.json..."));
|
|
7498
7625
|
import_fs_extra7.default.removeSync(packageLockPath);
|
|
7499
7626
|
}
|
|
7500
7627
|
const frontendNodeModules = import_path12.default.join(targetDir, "frontend", "node_modules");
|
|
@@ -7505,13 +7632,13 @@ Directory "${projectName}" already exists.`));
|
|
|
7505
7632
|
if (import_fs_extra7.default.existsSync(backendNodeModules)) import_fs_extra7.default.removeSync(backendNodeModules);
|
|
7506
7633
|
if (import_fs_extra7.default.existsSync(frontendPackageLock)) import_fs_extra7.default.removeSync(frontendPackageLock);
|
|
7507
7634
|
if (import_fs_extra7.default.existsSync(backendPackageLock)) import_fs_extra7.default.removeSync(backendPackageLock);
|
|
7508
|
-
console.log(
|
|
7635
|
+
console.log(import_chalk19.default.green(` Template downloaded to: ${targetDir}`));
|
|
7509
7636
|
} catch (error) {
|
|
7510
7637
|
throw createCommandError("template extraction", `unzip -o "${zipPath}" -d "${PROJECT_DIR}"`, error, [
|
|
7511
7638
|
"Check whether `unzip` is available and the downloaded template archive is valid."
|
|
7512
7639
|
]);
|
|
7513
7640
|
}
|
|
7514
|
-
console.log(
|
|
7641
|
+
console.log(import_chalk19.default.blue("\n3. Updating configuration..."));
|
|
7515
7642
|
const configPath = import_path12.default.join(targetDir, "pinme.toml");
|
|
7516
7643
|
const config = import_fs_extra7.default.readFileSync(configPath, "utf-8");
|
|
7517
7644
|
let updatedConfig = config.replace(
|
|
@@ -7519,8 +7646,8 @@ Directory "${projectName}" already exists.`));
|
|
|
7519
7646
|
`project_name = "${workerData.project_name}"`
|
|
7520
7647
|
);
|
|
7521
7648
|
import_fs_extra7.default.writeFileSync(configPath, updatedConfig);
|
|
7522
|
-
console.log(
|
|
7523
|
-
console.log(
|
|
7649
|
+
console.log(import_chalk19.default.green(` Updated pinme.toml`));
|
|
7650
|
+
console.log(import_chalk19.default.gray(` metadata: ${workerData.metadata}`));
|
|
7524
7651
|
const backendDir = import_path12.default.join(targetDir, "backend");
|
|
7525
7652
|
if (import_fs_extra7.default.existsSync(backendDir) && workerData.metadata) {
|
|
7526
7653
|
const metadataContent = typeof workerData.metadata === "string" ? workerData.metadata : JSON.stringify(workerData.metadata, null, 2);
|
|
@@ -7528,7 +7655,7 @@ Directory "${projectName}" already exists.`));
|
|
|
7528
7655
|
import_path12.default.join(backendDir, "metadata.json"),
|
|
7529
7656
|
metadataContent
|
|
7530
7657
|
);
|
|
7531
|
-
console.log(
|
|
7658
|
+
console.log(import_chalk19.default.green(` Saved metadata.json`));
|
|
7532
7659
|
}
|
|
7533
7660
|
const wranglerPath = import_path12.default.join(backendDir, "wrangler.toml");
|
|
7534
7661
|
if (import_fs_extra7.default.existsSync(wranglerPath) && workerData.api_key) {
|
|
@@ -7538,7 +7665,7 @@ Directory "${projectName}" already exists.`));
|
|
|
7538
7665
|
`name = "${workerData.project_name}"`
|
|
7539
7666
|
);
|
|
7540
7667
|
import_fs_extra7.default.writeFileSync(wranglerPath, wranglerContent);
|
|
7541
|
-
console.log(
|
|
7668
|
+
console.log(import_chalk19.default.green(` Updated backend/wrangler.toml API_KEY`));
|
|
7542
7669
|
}
|
|
7543
7670
|
const frontendConfigPath = import_path12.default.join(targetDir, "frontend", "src", "utils", "config.ts");
|
|
7544
7671
|
if (workerData.public_client_config) {
|
|
@@ -7548,7 +7675,7 @@ Directory "${projectName}" already exists.`));
|
|
|
7548
7675
|
frontendConfigPath,
|
|
7549
7676
|
injectPublicClientConfigIntoFile(frontendConfigContent, workerData.public_client_config)
|
|
7550
7677
|
);
|
|
7551
|
-
console.log(
|
|
7678
|
+
console.log(import_chalk19.default.green(` Updated frontend/src/utils/config.ts public_client_config`));
|
|
7552
7679
|
}
|
|
7553
7680
|
const envExamplePath = import_path12.default.join(targetDir, "frontend", ".env.example");
|
|
7554
7681
|
const envPath = import_path12.default.join(targetDir, "frontend", ".env");
|
|
@@ -7560,8 +7687,8 @@ Directory "${projectName}" already exists.`));
|
|
|
7560
7687
|
`VITE_API_URL=${workerData.api_domain}`
|
|
7561
7688
|
);
|
|
7562
7689
|
import_fs_extra7.default.writeFileSync(envPath, envContent);
|
|
7563
|
-
console.log(
|
|
7564
|
-
console.log(
|
|
7690
|
+
console.log(import_chalk19.default.green(` Created frontend/.env file`));
|
|
7691
|
+
console.log(import_chalk19.default.gray(` VITE_API_URL: ${workerData.api_domain}`));
|
|
7565
7692
|
}
|
|
7566
7693
|
let pinmeConfig = import_fs_extra7.default.readFileSync(configPath, "utf-8");
|
|
7567
7694
|
if (pinmeConfig.includes("api_url")) {
|
|
@@ -7581,11 +7708,11 @@ Directory "${projectName}" already exists.`));
|
|
|
7581
7708
|
pinmeConfig = newLines.join("\n");
|
|
7582
7709
|
}
|
|
7583
7710
|
import_fs_extra7.default.writeFileSync(configPath, pinmeConfig);
|
|
7584
|
-
console.log(
|
|
7585
|
-
console.log(
|
|
7711
|
+
console.log(import_chalk19.default.green(` Updated pinme.toml with api_url`));
|
|
7712
|
+
console.log(import_chalk19.default.blue("\n4. Installing dependencies..."));
|
|
7586
7713
|
try {
|
|
7587
7714
|
installProjectDependencies(targetDir);
|
|
7588
|
-
console.log(
|
|
7715
|
+
console.log(import_chalk19.default.green(" Project dependencies installed"));
|
|
7589
7716
|
} catch (error) {
|
|
7590
7717
|
const errorMsg = error.message || "";
|
|
7591
7718
|
if (errorMsg.includes("EACCES") || errorMsg.includes("EPERM") || errorMsg.includes("permission denied")) {
|
|
@@ -7624,13 +7751,13 @@ Directory "${projectName}" already exists.`));
|
|
|
7624
7751
|
" sudo chown -R $(whoami) " + targetDir + "/node_modules"
|
|
7625
7752
|
]);
|
|
7626
7753
|
}
|
|
7627
|
-
console.log(
|
|
7754
|
+
console.log(import_chalk19.default.blue("\n5. Building backend worker..."));
|
|
7628
7755
|
try {
|
|
7629
7756
|
(0, import_child_process3.execSync)("npm run build:worker", {
|
|
7630
7757
|
cwd: targetDir,
|
|
7631
7758
|
stdio: "inherit"
|
|
7632
7759
|
});
|
|
7633
|
-
console.log(
|
|
7760
|
+
console.log(import_chalk19.default.green(" Worker built"));
|
|
7634
7761
|
} catch (error) {
|
|
7635
7762
|
throw createCommandError("worker build", "npm run build:worker", error, [
|
|
7636
7763
|
"Fix the build error shown above, then rerun `pinme create`."
|
|
@@ -7656,12 +7783,12 @@ Directory "${projectName}" already exists.`));
|
|
|
7656
7783
|
const sqlFileNames = import_fs_extra7.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
|
|
7657
7784
|
for (const filename of sqlFileNames) {
|
|
7658
7785
|
sqlFiles.push(import_path12.default.join(sqlDir, filename));
|
|
7659
|
-
console.log(
|
|
7786
|
+
console.log(import_chalk19.default.gray(` Including SQL: ${filename}`));
|
|
7660
7787
|
}
|
|
7661
7788
|
}
|
|
7662
|
-
console.log(
|
|
7663
|
-
const saveApiUrl = `${
|
|
7664
|
-
console.log(
|
|
7789
|
+
console.log(import_chalk19.default.blue("\n6. Deploying backend worker..."));
|
|
7790
|
+
const saveApiUrl = `${getPinmeApiUrl("/save_worker")}?project_name=${encodeURIComponent(workerData.project_name)}`;
|
|
7791
|
+
console.log(import_chalk19.default.gray(` API URL: ${saveApiUrl}`));
|
|
7665
7792
|
try {
|
|
7666
7793
|
const FormData4 = (await import("formdata-node")).FormData;
|
|
7667
7794
|
const Blob2 = (await import("formdata-node")).Blob;
|
|
@@ -7693,10 +7820,10 @@ Directory "${projectName}" already exists.`));
|
|
|
7693
7820
|
timeout: 12e4
|
|
7694
7821
|
});
|
|
7695
7822
|
if (response.data) {
|
|
7696
|
-
console.log(
|
|
7697
|
-
if ((_b = (
|
|
7823
|
+
console.log(import_chalk19.default.green(" Worker deployed"));
|
|
7824
|
+
if ((_b = (_a2 = response.data) == null ? void 0 : _a2.data) == null ? void 0 : _b.sql_results) {
|
|
7698
7825
|
for (const result of response.data.data.sql_results) {
|
|
7699
|
-
console.log(
|
|
7826
|
+
console.log(import_chalk19.default.gray(` SQL ${result.filename}: ${result.status}`));
|
|
7700
7827
|
}
|
|
7701
7828
|
}
|
|
7702
7829
|
} else {
|
|
@@ -7715,7 +7842,7 @@ Directory "${projectName}" already exists.`));
|
|
|
7715
7842
|
"Check whether backend metadata, SQL files, or worker bundle contains invalid content."
|
|
7716
7843
|
]);
|
|
7717
7844
|
}
|
|
7718
|
-
console.log(
|
|
7845
|
+
console.log(import_chalk19.default.blue("\n7. Building frontend..."));
|
|
7719
7846
|
const frontendDir = import_path12.default.join(targetDir, "frontend");
|
|
7720
7847
|
if (import_fs_extra7.default.existsSync(frontendDir)) {
|
|
7721
7848
|
try {
|
|
@@ -7723,60 +7850,36 @@ Directory "${projectName}" already exists.`));
|
|
|
7723
7850
|
cwd: targetDir,
|
|
7724
7851
|
stdio: "inherit"
|
|
7725
7852
|
});
|
|
7726
|
-
console.log(
|
|
7853
|
+
console.log(import_chalk19.default.green(" Frontend built"));
|
|
7727
7854
|
} catch (error) {
|
|
7728
7855
|
throw createCommandError("frontend build", "npm run build:frontend", error, [
|
|
7729
7856
|
"Fix the frontend build error shown above, then rerun `pinme create`."
|
|
7730
7857
|
]);
|
|
7731
7858
|
}
|
|
7732
|
-
console.log(
|
|
7733
|
-
let frontendUrl = "";
|
|
7859
|
+
console.log(import_chalk19.default.blue(" Uploading to IPFS..."));
|
|
7734
7860
|
try {
|
|
7735
|
-
const
|
|
7736
|
-
|
|
7737
|
-
encoding: "utf-8",
|
|
7738
|
-
env: {
|
|
7739
|
-
...process.env,
|
|
7740
|
-
PINME_PROJECT_NAME: workerData.project_name
|
|
7741
|
-
}
|
|
7861
|
+
const uploadResult = await uploadPath(import_path12.default.join(frontendDir, "dist"), {
|
|
7862
|
+
projectName: workerData.project_name
|
|
7742
7863
|
});
|
|
7743
|
-
console.log(
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
let config2 = import_fs_extra7.default.readFileSync(configPath2, "utf-8");
|
|
7750
|
-
if (config2.includes("frontend_url")) {
|
|
7751
|
-
config2 = config2.replace(
|
|
7752
|
-
/frontend_url\s*=\s*"[^"]*"/,
|
|
7753
|
-
`frontend_url = "${frontendUrl}"`
|
|
7754
|
-
);
|
|
7755
|
-
} else {
|
|
7756
|
-
config2 = config2.replace(
|
|
7757
|
-
/(project_name\s*=\s*"[^"]*"\n)/,
|
|
7758
|
-
`$1frontend_url = "${frontendUrl}"
|
|
7759
|
-
`
|
|
7760
|
-
);
|
|
7761
|
-
}
|
|
7762
|
-
import_fs_extra7.default.writeFileSync(configPath2, config2);
|
|
7763
|
-
console.log(import_chalk18.default.green(" Updated pinme.toml with frontend URL"));
|
|
7764
|
-
} else {
|
|
7765
|
-
console.log(import_chalk18.default.green(" Frontend uploaded to IPFS"));
|
|
7766
|
-
}
|
|
7864
|
+
console.log(import_chalk19.default.green(` Frontend uploaded to IPFS: ${uploadResult.publicUrl}`));
|
|
7865
|
+
updateFrontendUrlInConfig(
|
|
7866
|
+
import_path12.default.join(targetDir, "pinme.toml"),
|
|
7867
|
+
uploadResult.publicUrl
|
|
7868
|
+
);
|
|
7869
|
+
console.log(import_chalk19.default.green(" Updated pinme.toml with frontend URL"));
|
|
7767
7870
|
} catch (error) {
|
|
7768
|
-
console.log(
|
|
7871
|
+
console.log(import_chalk19.default.yellow(" Warning: IPFS upload failed, you can upload manually later"));
|
|
7769
7872
|
}
|
|
7770
7873
|
}
|
|
7771
|
-
console.log(
|
|
7772
|
-
console.log(
|
|
7874
|
+
console.log(import_chalk19.default.green("\nProject created successfully."));
|
|
7875
|
+
console.log(import_chalk19.default.gray(`
|
|
7773
7876
|
Project Details:`));
|
|
7774
|
-
console.log(
|
|
7775
|
-
console.log(
|
|
7776
|
-
console.log(
|
|
7877
|
+
console.log(import_chalk19.default.gray(` API Domain: ${workerData.api_domain}`));
|
|
7878
|
+
console.log(import_chalk19.default.gray(` Project Name: ${workerData.project_name}`));
|
|
7879
|
+
console.log(import_chalk19.default.gray(`
|
|
7777
7880
|
Next steps:`));
|
|
7778
|
-
console.log(
|
|
7779
|
-
console.log(
|
|
7881
|
+
console.log(import_chalk19.default.gray(` cd ${projectName}`));
|
|
7882
|
+
console.log(import_chalk19.default.gray(` pinme save`));
|
|
7780
7883
|
process.exit(0);
|
|
7781
7884
|
} catch (error) {
|
|
7782
7885
|
printCliError(error, "Project creation failed.");
|
|
@@ -7785,12 +7888,11 @@ Next steps:`));
|
|
|
7785
7888
|
}
|
|
7786
7889
|
|
|
7787
7890
|
// bin/save.ts
|
|
7788
|
-
var
|
|
7891
|
+
var import_chalk20 = __toESM(require("chalk"));
|
|
7789
7892
|
var import_fs_extra8 = __toESM(require("fs-extra"));
|
|
7790
7893
|
var import_path13 = __toESM(require("path"));
|
|
7791
7894
|
var import_child_process4 = require("child_process");
|
|
7792
7895
|
var PROJECT_DIR2 = process.cwd();
|
|
7793
|
-
var API_BASE2 = "https://pinme.benny1996.win/api/v4";
|
|
7794
7896
|
function loadConfig() {
|
|
7795
7897
|
const configPath = import_path13.default.join(PROJECT_DIR2, "pinme.toml");
|
|
7796
7898
|
if (!import_fs_extra8.default.existsSync(configPath)) {
|
|
@@ -7808,19 +7910,19 @@ function loadConfig() {
|
|
|
7808
7910
|
function getMetadata() {
|
|
7809
7911
|
const metadataPath = import_path13.default.join(PROJECT_DIR2, "backend", "metadata.json");
|
|
7810
7912
|
if (!import_fs_extra8.default.existsSync(metadataPath)) {
|
|
7811
|
-
console.log(
|
|
7913
|
+
console.log(import_chalk20.default.yellow(" Warning: metadata.json not found, using empty metadata"));
|
|
7812
7914
|
return {};
|
|
7813
7915
|
}
|
|
7814
7916
|
return import_fs_extra8.default.readJsonSync(metadataPath);
|
|
7815
7917
|
}
|
|
7816
7918
|
function buildWorker() {
|
|
7817
|
-
console.log(
|
|
7919
|
+
console.log(import_chalk20.default.blue("Building worker..."));
|
|
7818
7920
|
try {
|
|
7819
7921
|
(0, import_child_process4.execSync)("npm run build:worker", {
|
|
7820
7922
|
cwd: PROJECT_DIR2,
|
|
7821
7923
|
stdio: "inherit"
|
|
7822
7924
|
});
|
|
7823
|
-
console.log(
|
|
7925
|
+
console.log(import_chalk20.default.green("Worker built"));
|
|
7824
7926
|
} catch (error) {
|
|
7825
7927
|
throw createCommandError("worker build", "npm run build:worker", error, [
|
|
7826
7928
|
"Fix the build error shown above, then rerun `pinme save`."
|
|
@@ -7828,10 +7930,10 @@ function buildWorker() {
|
|
|
7828
7930
|
}
|
|
7829
7931
|
}
|
|
7830
7932
|
function installDependencies() {
|
|
7831
|
-
console.log(
|
|
7933
|
+
console.log(import_chalk20.default.blue("Installing dependencies..."));
|
|
7832
7934
|
try {
|
|
7833
7935
|
installProjectDependencies(PROJECT_DIR2);
|
|
7834
|
-
console.log(
|
|
7936
|
+
console.log(import_chalk20.default.green("Project dependencies installed"));
|
|
7835
7937
|
} catch (error) {
|
|
7836
7938
|
const errorMsg = error.message || "";
|
|
7837
7939
|
if (errorMsg.includes("EACCES") || errorMsg.includes("EPERM") || errorMsg.includes("permission denied")) {
|
|
@@ -7902,16 +8004,16 @@ function getSqlFiles() {
|
|
|
7902
8004
|
return files.map((f) => import_path13.default.join(sqlDir, f));
|
|
7903
8005
|
}
|
|
7904
8006
|
async function saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, projectName) {
|
|
7905
|
-
var
|
|
7906
|
-
console.log(
|
|
7907
|
-
console.log(
|
|
7908
|
-
console.log(
|
|
7909
|
-
console.log(
|
|
7910
|
-
console.log(
|
|
7911
|
-
console.log(
|
|
7912
|
-
const apiUrl = `${
|
|
8007
|
+
var _a2, _b;
|
|
8008
|
+
console.log(import_chalk20.default.blue("Saving worker to platform..."));
|
|
8009
|
+
console.log(import_chalk20.default.gray(`Project: ${projectName}`));
|
|
8010
|
+
console.log(import_chalk20.default.gray(`workerJsPath: ${workerJsPath}`));
|
|
8011
|
+
console.log(import_chalk20.default.gray(`modulePaths: ${modulePaths}`));
|
|
8012
|
+
console.log(import_chalk20.default.gray(`sqlFiles: ${sqlFiles}`));
|
|
8013
|
+
console.log(import_chalk20.default.gray(`metadata: ${metadata}`));
|
|
8014
|
+
const apiUrl = `${getPinmeApiUrl("/save_worker")}?project_name=${encodeURIComponent(projectName)}`;
|
|
7913
8015
|
const headers = getAuthHeaders();
|
|
7914
|
-
console.log(
|
|
8016
|
+
console.log(import_chalk20.default.gray(`API URL: ${apiUrl}`));
|
|
7915
8017
|
try {
|
|
7916
8018
|
const FormData4 = (await import("formdata-node")).FormData;
|
|
7917
8019
|
const Blob2 = (await import("formdata-node")).Blob;
|
|
@@ -7936,18 +8038,18 @@ async function saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, project
|
|
|
7936
8038
|
formData.append("sql_file", new Blob2([content], {
|
|
7937
8039
|
type: "application/sql"
|
|
7938
8040
|
}), filename);
|
|
7939
|
-
console.log(
|
|
8041
|
+
console.log(import_chalk20.default.gray(` Including SQL: ${filename}`));
|
|
7940
8042
|
}
|
|
7941
8043
|
const response = await axios_default.put(apiUrl, formData, {
|
|
7942
8044
|
headers: { ...headers },
|
|
7943
8045
|
timeout: 12e4
|
|
7944
8046
|
});
|
|
7945
|
-
console.log(
|
|
8047
|
+
console.log(import_chalk20.default.gray(` Response: ${JSON.stringify(response.data)}`));
|
|
7946
8048
|
if (response.data) {
|
|
7947
|
-
console.log(
|
|
7948
|
-
if ((_b = (
|
|
8049
|
+
console.log(import_chalk20.default.green("Worker saved"));
|
|
8050
|
+
if ((_b = (_a2 = response.data) == null ? void 0 : _a2.data) == null ? void 0 : _b.sql_results) {
|
|
7949
8051
|
for (const result of response.data.data.sql_results) {
|
|
7950
|
-
console.log(
|
|
8052
|
+
console.log(import_chalk20.default.gray(` SQL ${result.filename}: ${result.status}`));
|
|
7951
8053
|
}
|
|
7952
8054
|
}
|
|
7953
8055
|
} else {
|
|
@@ -7968,57 +8070,47 @@ async function saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, project
|
|
|
7968
8070
|
}
|
|
7969
8071
|
}
|
|
7970
8072
|
function buildFrontend() {
|
|
7971
|
-
console.log(
|
|
8073
|
+
console.log(import_chalk20.default.blue("Building frontend..."));
|
|
7972
8074
|
try {
|
|
7973
8075
|
(0, import_child_process4.execSync)("npm run build:frontend", {
|
|
7974
8076
|
cwd: PROJECT_DIR2,
|
|
7975
8077
|
stdio: "inherit"
|
|
7976
8078
|
});
|
|
7977
|
-
console.log(
|
|
8079
|
+
console.log(import_chalk20.default.green("Frontend built"));
|
|
7978
8080
|
} catch (error) {
|
|
7979
8081
|
throw createCommandError("frontend build", "npm run build:frontend", error, [
|
|
7980
8082
|
"Fix the frontend build error shown above, then rerun `pinme save`."
|
|
7981
8083
|
]);
|
|
7982
8084
|
}
|
|
7983
8085
|
}
|
|
7984
|
-
function
|
|
7985
|
-
|
|
8086
|
+
function updateFrontendUrlInConfig2(configPath, frontendUrl) {
|
|
8087
|
+
let config = import_fs_extra8.default.readFileSync(configPath, "utf-8");
|
|
8088
|
+
if (config.includes("frontend_url")) {
|
|
8089
|
+
config = config.replace(
|
|
8090
|
+
/frontend_url\s*=\s*"[^"]*"/,
|
|
8091
|
+
`frontend_url = "${frontendUrl}"`
|
|
8092
|
+
);
|
|
8093
|
+
} else {
|
|
8094
|
+
config = config.replace(
|
|
8095
|
+
/(project_name\s*=\s*"[^"]*"\n)/,
|
|
8096
|
+
`$1frontend_url = "${frontendUrl}"
|
|
8097
|
+
`
|
|
8098
|
+
);
|
|
8099
|
+
}
|
|
8100
|
+
import_fs_extra8.default.writeFileSync(configPath, config);
|
|
8101
|
+
}
|
|
8102
|
+
async function deployFrontend(projectName) {
|
|
8103
|
+
console.log(import_chalk20.default.blue("Deploying frontend to IPFS..."));
|
|
7986
8104
|
try {
|
|
7987
|
-
const
|
|
7988
|
-
|
|
7989
|
-
encoding: "utf-8",
|
|
7990
|
-
env: {
|
|
7991
|
-
...process.env,
|
|
7992
|
-
PINME_PROJECT_NAME: projectName
|
|
7993
|
-
}
|
|
8105
|
+
const uploadResult = await uploadPath(import_path13.default.join(PROJECT_DIR2, "frontend", "dist"), {
|
|
8106
|
+
projectName
|
|
7994
8107
|
});
|
|
7995
|
-
console.log(
|
|
7996
|
-
|
|
7997
|
-
|
|
7998
|
-
const frontendUrl = urlMatch[0];
|
|
7999
|
-
console.log(import_chalk19.default.green(`Frontend deployed to IPFS: ${frontendUrl}`));
|
|
8000
|
-
const configPath = import_path13.default.join(PROJECT_DIR2, "pinme.toml");
|
|
8001
|
-
let config = import_fs_extra8.default.readFileSync(configPath, "utf-8");
|
|
8002
|
-
if (config.includes("frontend_url")) {
|
|
8003
|
-
config = config.replace(
|
|
8004
|
-
/frontend_url\s*=\s*"[^"]*"/,
|
|
8005
|
-
`frontend_url = "${frontendUrl}"`
|
|
8006
|
-
);
|
|
8007
|
-
} else {
|
|
8008
|
-
config = config.replace(
|
|
8009
|
-
/(project_name\s*=\s*"[^"]*"\n)/,
|
|
8010
|
-
`$1frontend_url = "${frontendUrl}"
|
|
8011
|
-
`
|
|
8012
|
-
);
|
|
8013
|
-
}
|
|
8014
|
-
import_fs_extra8.default.writeFileSync(configPath, config);
|
|
8015
|
-
console.log(import_chalk19.default.green("Updated pinme.toml with frontend URL"));
|
|
8016
|
-
} else {
|
|
8017
|
-
console.log(import_chalk19.default.green("Frontend deployed to IPFS"));
|
|
8018
|
-
}
|
|
8108
|
+
console.log(import_chalk20.default.green(`Frontend deployed to IPFS: ${uploadResult.publicUrl}`));
|
|
8109
|
+
updateFrontendUrlInConfig2(import_path13.default.join(PROJECT_DIR2, "pinme.toml"), uploadResult.publicUrl);
|
|
8110
|
+
console.log(import_chalk20.default.green("Updated pinme.toml with frontend URL"));
|
|
8019
8111
|
} catch (error) {
|
|
8020
|
-
throw createCommandError("frontend deploy", "
|
|
8021
|
-
"Make sure `frontend/dist` exists and
|
|
8112
|
+
throw createCommandError("frontend deploy", "upload frontend/dist", error, [
|
|
8113
|
+
"Make sure `frontend/dist` exists and the upload API is reachable."
|
|
8022
8114
|
]);
|
|
8023
8115
|
}
|
|
8024
8116
|
}
|
|
@@ -8036,8 +8128,8 @@ async function saveCmd(options) {
|
|
|
8036
8128
|
if (import_fs_extra8.default.existsSync(tokenFileSrc) && !import_fs_extra8.default.existsSync(tokenFileDst)) {
|
|
8037
8129
|
import_fs_extra8.default.copySync(tokenFileSrc, tokenFileDst);
|
|
8038
8130
|
}
|
|
8039
|
-
console.log(
|
|
8040
|
-
console.log(
|
|
8131
|
+
console.log(import_chalk20.default.blue("Deploying to platform...\n"));
|
|
8132
|
+
console.log(import_chalk20.default.gray(`Project dir: ${PROJECT_DIR2}`));
|
|
8041
8133
|
const config = loadConfig();
|
|
8042
8134
|
const projectName = config.project_name;
|
|
8043
8135
|
if (!projectName) {
|
|
@@ -8045,23 +8137,23 @@ async function saveCmd(options) {
|
|
|
8045
8137
|
'Set `project_name = "your-project-name"` in `pinme.toml`.'
|
|
8046
8138
|
]);
|
|
8047
8139
|
}
|
|
8048
|
-
console.log(
|
|
8049
|
-
const apiUrl = `${
|
|
8050
|
-
console.log(
|
|
8051
|
-
console.log(
|
|
8140
|
+
console.log(import_chalk20.default.gray(`Project: ${projectName}`));
|
|
8141
|
+
const apiUrl = `${getPinmeApiUrl("/save_worker")}?project_name=${encodeURIComponent(projectName)}`;
|
|
8142
|
+
console.log(import_chalk20.default.gray(`API URL: ${apiUrl}`));
|
|
8143
|
+
console.log(import_chalk20.default.blue("\n--- Backend ---"));
|
|
8052
8144
|
installDependencies();
|
|
8053
8145
|
buildWorker();
|
|
8054
8146
|
const metadata = getMetadata();
|
|
8055
8147
|
const { workerJsPath, modulePaths } = getBuiltWorker();
|
|
8056
|
-
console.log(
|
|
8057
|
-
console.log(
|
|
8148
|
+
console.log(import_chalk20.default.gray(`Worker JS: ${workerJsPath}`));
|
|
8149
|
+
console.log(import_chalk20.default.gray(`Module paths: ${JSON.stringify(modulePaths)}`));
|
|
8058
8150
|
const sqlFiles = getSqlFiles();
|
|
8059
|
-
console.log(
|
|
8151
|
+
console.log(import_chalk20.default.gray(`SQL files: ${JSON.stringify(sqlFiles)}`));
|
|
8060
8152
|
await saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, projectName);
|
|
8061
|
-
console.log(
|
|
8153
|
+
console.log(import_chalk20.default.blue("\n--- Frontend ---"));
|
|
8062
8154
|
buildFrontend();
|
|
8063
|
-
deployFrontend(projectName);
|
|
8064
|
-
console.log(
|
|
8155
|
+
await deployFrontend(projectName);
|
|
8156
|
+
console.log(import_chalk20.default.green("\nDeployment complete."));
|
|
8065
8157
|
process.exit(0);
|
|
8066
8158
|
} catch (error) {
|
|
8067
8159
|
printCliError(error, "Save failed.");
|
|
@@ -8070,11 +8162,10 @@ async function saveCmd(options) {
|
|
|
8070
8162
|
}
|
|
8071
8163
|
|
|
8072
8164
|
// bin/updateDb.ts
|
|
8073
|
-
var
|
|
8165
|
+
var import_chalk21 = __toESM(require("chalk"));
|
|
8074
8166
|
var import_fs_extra9 = __toESM(require("fs-extra"));
|
|
8075
8167
|
var import_path14 = __toESM(require("path"));
|
|
8076
8168
|
var PROJECT_DIR3 = process.cwd();
|
|
8077
|
-
var API_BASE3 = "https://pinme.benny1996.win/api/v4";
|
|
8078
8169
|
function loadConfig2() {
|
|
8079
8170
|
const configPath = import_path14.default.join(PROJECT_DIR3, "pinme.toml");
|
|
8080
8171
|
if (!import_fs_extra9.default.existsSync(configPath)) {
|
|
@@ -8104,12 +8195,12 @@ function getSqlFiles2() {
|
|
|
8104
8195
|
return files.map((f) => import_path14.default.join(sqlDir, f));
|
|
8105
8196
|
}
|
|
8106
8197
|
async function updateDb(sqlFiles, projectName) {
|
|
8107
|
-
console.log(
|
|
8108
|
-
console.log(
|
|
8109
|
-
console.log(
|
|
8110
|
-
const apiUrl = `${
|
|
8198
|
+
console.log(import_chalk21.default.blue("Importing SQL files to database..."));
|
|
8199
|
+
console.log(import_chalk21.default.gray(`Project: ${projectName}`));
|
|
8200
|
+
console.log(import_chalk21.default.gray(`SQL files: ${sqlFiles.length}`));
|
|
8201
|
+
const apiUrl = `${getPinmeApiUrl("/update_db")}?project_name=${encodeURIComponent(projectName)}`;
|
|
8111
8202
|
const headers = getAuthHeaders();
|
|
8112
|
-
console.log(
|
|
8203
|
+
console.log(import_chalk21.default.gray(`API URL: ${apiUrl}`));
|
|
8113
8204
|
try {
|
|
8114
8205
|
const FormData4 = (await import("formdata-node")).FormData;
|
|
8115
8206
|
const Blob2 = (await import("formdata-node")).Blob;
|
|
@@ -8127,24 +8218,24 @@ async function updateDb(sqlFiles, projectName) {
|
|
|
8127
8218
|
formData.append("file", new Blob2([content], {
|
|
8128
8219
|
type: "application/sql"
|
|
8129
8220
|
}), filename);
|
|
8130
|
-
console.log(
|
|
8221
|
+
console.log(import_chalk21.default.gray(` Including: ${filename} (${content.length} bytes)`));
|
|
8131
8222
|
}
|
|
8132
8223
|
const response = await axios_default.post(apiUrl, formData, {
|
|
8133
8224
|
headers: { ...headers },
|
|
8134
8225
|
timeout: 12e4
|
|
8135
8226
|
});
|
|
8136
|
-
console.log(
|
|
8227
|
+
console.log(import_chalk21.default.gray(` Response: ${JSON.stringify(response.data)}`));
|
|
8137
8228
|
if (response.data.code === 200) {
|
|
8138
|
-
console.log(
|
|
8229
|
+
console.log(import_chalk21.default.green("SQL files imported successfully!"));
|
|
8139
8230
|
const results = response.data.data.results;
|
|
8140
8231
|
for (const result of results) {
|
|
8141
8232
|
if (result.status === "complete") {
|
|
8142
|
-
console.log(
|
|
8233
|
+
console.log(import_chalk21.default.green(` COMPLETE ${result.filename}: ${result.num_queries} queries, ${result.duration}ms`));
|
|
8143
8234
|
if (result.changes !== void 0) {
|
|
8144
|
-
console.log(
|
|
8235
|
+
console.log(import_chalk21.default.gray(` Changes: ${result.changes}, Read: ${result.rows_read}, Written: ${result.rows_written}`));
|
|
8145
8236
|
}
|
|
8146
8237
|
} else if (result.status === "error") {
|
|
8147
|
-
console.log(
|
|
8238
|
+
console.log(import_chalk21.default.red(` ERROR ${result.filename}: ${result.error}`));
|
|
8148
8239
|
}
|
|
8149
8240
|
}
|
|
8150
8241
|
} else {
|
|
@@ -8178,8 +8269,8 @@ async function updateDbCmd(options) {
|
|
|
8178
8269
|
if (import_fs_extra9.default.existsSync(tokenFileSrc) && !import_fs_extra9.default.existsSync(tokenFileDst)) {
|
|
8179
8270
|
import_fs_extra9.default.copySync(tokenFileSrc, tokenFileDst);
|
|
8180
8271
|
}
|
|
8181
|
-
console.log(
|
|
8182
|
-
console.log(
|
|
8272
|
+
console.log(import_chalk21.default.blue("Importing SQL to database...\n"));
|
|
8273
|
+
console.log(import_chalk21.default.gray(`Project dir: ${PROJECT_DIR3}`));
|
|
8183
8274
|
const config = loadConfig2();
|
|
8184
8275
|
const projectName = config.project_name;
|
|
8185
8276
|
if (!projectName) {
|
|
@@ -8187,11 +8278,11 @@ async function updateDbCmd(options) {
|
|
|
8187
8278
|
'Set `project_name = "your-project-name"` in `pinme.toml`.'
|
|
8188
8279
|
]);
|
|
8189
8280
|
}
|
|
8190
|
-
console.log(
|
|
8281
|
+
console.log(import_chalk21.default.gray(`Project: ${projectName}`));
|
|
8191
8282
|
const sqlFiles = getSqlFiles2();
|
|
8192
|
-
console.log(
|
|
8283
|
+
console.log(import_chalk21.default.gray(`Found ${sqlFiles.length} SQL file(s) in db`));
|
|
8193
8284
|
await updateDb(sqlFiles, projectName);
|
|
8194
|
-
console.log(
|
|
8285
|
+
console.log(import_chalk21.default.green("\nDatabase update complete."));
|
|
8195
8286
|
process.exit(0);
|
|
8196
8287
|
} catch (error) {
|
|
8197
8288
|
printCliError(error, "Database update failed.");
|
|
@@ -8200,12 +8291,11 @@ async function updateDbCmd(options) {
|
|
|
8200
8291
|
}
|
|
8201
8292
|
|
|
8202
8293
|
// bin/updateWorker.ts
|
|
8203
|
-
var
|
|
8294
|
+
var import_chalk22 = __toESM(require("chalk"));
|
|
8204
8295
|
var import_fs_extra10 = __toESM(require("fs-extra"));
|
|
8205
8296
|
var import_path15 = __toESM(require("path"));
|
|
8206
8297
|
var import_child_process5 = require("child_process");
|
|
8207
8298
|
var PROJECT_DIR4 = process.cwd();
|
|
8208
|
-
var API_BASE4 = "https://pinme.benny1996.win/api/v4";
|
|
8209
8299
|
function loadConfig3() {
|
|
8210
8300
|
const configPath = import_path15.default.join(PROJECT_DIR4, "pinme.toml");
|
|
8211
8301
|
if (!import_fs_extra10.default.existsSync(configPath)) {
|
|
@@ -8229,13 +8319,13 @@ function getMetadata2() {
|
|
|
8229
8319
|
return import_fs_extra10.default.readJsonSync(metadataPath);
|
|
8230
8320
|
}
|
|
8231
8321
|
function buildWorker2() {
|
|
8232
|
-
console.log(
|
|
8322
|
+
console.log(import_chalk22.default.blue("Building worker..."));
|
|
8233
8323
|
try {
|
|
8234
8324
|
(0, import_child_process5.execSync)("npm run build:worker", {
|
|
8235
8325
|
cwd: PROJECT_DIR4,
|
|
8236
8326
|
stdio: "inherit"
|
|
8237
8327
|
});
|
|
8238
|
-
console.log(
|
|
8328
|
+
console.log(import_chalk22.default.green("Worker built"));
|
|
8239
8329
|
} catch (error) {
|
|
8240
8330
|
throw createCommandError("worker build", "npm run build:worker", error, [
|
|
8241
8331
|
"Fix the build error shown above, then rerun `pinme update-worker`."
|
|
@@ -8265,14 +8355,14 @@ function getBuiltWorker2() {
|
|
|
8265
8355
|
return { workerJsPath, modulePaths };
|
|
8266
8356
|
}
|
|
8267
8357
|
async function updateWorker(workerJsPath, modulePaths, metadata, projectName) {
|
|
8268
|
-
console.log(
|
|
8269
|
-
console.log(
|
|
8270
|
-
console.log(
|
|
8271
|
-
console.log(
|
|
8272
|
-
console.log(
|
|
8273
|
-
const apiUrl = `${
|
|
8358
|
+
console.log(import_chalk22.default.blue("Updating worker on platform..."));
|
|
8359
|
+
console.log(import_chalk22.default.gray(`Project: ${projectName}`));
|
|
8360
|
+
console.log(import_chalk22.default.gray(`workerJsPath: ${workerJsPath}`));
|
|
8361
|
+
console.log(import_chalk22.default.gray(`modulePaths: ${modulePaths}`));
|
|
8362
|
+
console.log(import_chalk22.default.gray(`metadata: ${metadata}`));
|
|
8363
|
+
const apiUrl = `${getPinmeApiUrl("/update_worker")}?project_name=${encodeURIComponent(projectName)}`;
|
|
8274
8364
|
const headers = getAuthHeaders();
|
|
8275
|
-
console.log(
|
|
8365
|
+
console.log(import_chalk22.default.gray(`API URL: ${apiUrl}`));
|
|
8276
8366
|
try {
|
|
8277
8367
|
const FormData4 = (await import("formdata-node")).FormData;
|
|
8278
8368
|
const Blob2 = (await import("formdata-node")).Blob;
|
|
@@ -8295,33 +8385,33 @@ async function updateWorker(workerJsPath, modulePaths, metadata, projectName) {
|
|
|
8295
8385
|
headers: { ...headers },
|
|
8296
8386
|
timeout: 12e4
|
|
8297
8387
|
});
|
|
8298
|
-
console.log(
|
|
8388
|
+
console.log(import_chalk22.default.gray(` Response: ${JSON.stringify(response.data)}`));
|
|
8299
8389
|
if (response.data) {
|
|
8300
|
-
console.log(
|
|
8390
|
+
console.log(import_chalk22.default.green("Worker updated"));
|
|
8301
8391
|
const data = response.data.data;
|
|
8302
8392
|
if (data.worker_id) {
|
|
8303
|
-
console.log(
|
|
8393
|
+
console.log(import_chalk22.default.gray(` Worker ID: ${data.worker_id}`));
|
|
8304
8394
|
}
|
|
8305
8395
|
if (data.deployment_id) {
|
|
8306
|
-
console.log(
|
|
8396
|
+
console.log(import_chalk22.default.gray(` Deployment ID: ${data.deployment_id}`));
|
|
8307
8397
|
}
|
|
8308
8398
|
if (data.entry_point) {
|
|
8309
|
-
console.log(
|
|
8399
|
+
console.log(import_chalk22.default.gray(` Entry Point: ${data.entry_point}`));
|
|
8310
8400
|
}
|
|
8311
8401
|
if (data.created_on) {
|
|
8312
|
-
console.log(
|
|
8402
|
+
console.log(import_chalk22.default.gray(` Created: ${data.created_on}`));
|
|
8313
8403
|
}
|
|
8314
8404
|
if (data.modified_on) {
|
|
8315
|
-
console.log(
|
|
8405
|
+
console.log(import_chalk22.default.gray(` Modified: ${data.modified_on}`));
|
|
8316
8406
|
}
|
|
8317
8407
|
if (data.startup_time_ms !== void 0) {
|
|
8318
|
-
console.log(
|
|
8408
|
+
console.log(import_chalk22.default.gray(` Startup Time: ${data.startup_time_ms}ms`));
|
|
8319
8409
|
}
|
|
8320
8410
|
if (data.has_modules !== void 0) {
|
|
8321
|
-
console.log(
|
|
8411
|
+
console.log(import_chalk22.default.gray(` Has Modules: ${data.has_modules}`));
|
|
8322
8412
|
}
|
|
8323
8413
|
if (data.domain) {
|
|
8324
|
-
console.log(
|
|
8414
|
+
console.log(import_chalk22.default.gray(` Domain: ${data.domain}`));
|
|
8325
8415
|
}
|
|
8326
8416
|
} else {
|
|
8327
8417
|
throw createApiError("worker update", { response: { data: response.data } }, [
|
|
@@ -8354,8 +8444,8 @@ async function updateWorkerCmd(options) {
|
|
|
8354
8444
|
if (import_fs_extra10.default.existsSync(tokenFileSrc) && !import_fs_extra10.default.existsSync(tokenFileDst)) {
|
|
8355
8445
|
import_fs_extra10.default.copySync(tokenFileSrc, tokenFileDst);
|
|
8356
8446
|
}
|
|
8357
|
-
console.log(
|
|
8358
|
-
console.log(
|
|
8447
|
+
console.log(import_chalk22.default.blue("Updating worker...\n"));
|
|
8448
|
+
console.log(import_chalk22.default.gray(`Project dir: ${PROJECT_DIR4}`));
|
|
8359
8449
|
const config = loadConfig3();
|
|
8360
8450
|
const projectName = config.project_name;
|
|
8361
8451
|
if (!projectName) {
|
|
@@ -8363,16 +8453,16 @@ async function updateWorkerCmd(options) {
|
|
|
8363
8453
|
'Set `project_name = "your-project-name"` in `pinme.toml`.'
|
|
8364
8454
|
]);
|
|
8365
8455
|
}
|
|
8366
|
-
console.log(
|
|
8367
|
-
console.log(
|
|
8456
|
+
console.log(import_chalk22.default.gray(`Project: ${projectName}`));
|
|
8457
|
+
console.log(import_chalk22.default.blue("\n--- Worker Update ---"));
|
|
8368
8458
|
buildWorker2();
|
|
8369
8459
|
const metadata = getMetadata2();
|
|
8370
8460
|
const { workerJsPath, modulePaths } = getBuiltWorker2();
|
|
8371
|
-
console.log(
|
|
8372
|
-
console.log(
|
|
8373
|
-
console.log(
|
|
8461
|
+
console.log(import_chalk22.default.gray(`Worker JS: ${workerJsPath}`));
|
|
8462
|
+
console.log(import_chalk22.default.gray(`Module paths: ${JSON.stringify(modulePaths)}`));
|
|
8463
|
+
console.log(import_chalk22.default.gray(`SQL files: ignored (not processed for update_worker)`));
|
|
8374
8464
|
await updateWorker(workerJsPath, modulePaths, metadata, projectName);
|
|
8375
|
-
console.log(
|
|
8465
|
+
console.log(import_chalk22.default.green("\nWorker update complete."));
|
|
8376
8466
|
process.exit(0);
|
|
8377
8467
|
} catch (error) {
|
|
8378
8468
|
printCliError(error, "Worker update failed.");
|
|
@@ -8381,7 +8471,7 @@ async function updateWorkerCmd(options) {
|
|
|
8381
8471
|
}
|
|
8382
8472
|
|
|
8383
8473
|
// bin/updateWeb.ts
|
|
8384
|
-
var
|
|
8474
|
+
var import_chalk23 = __toESM(require("chalk"));
|
|
8385
8475
|
var import_fs_extra11 = __toESM(require("fs-extra"));
|
|
8386
8476
|
var import_path16 = __toESM(require("path"));
|
|
8387
8477
|
var import_child_process6 = require("child_process");
|
|
@@ -8400,34 +8490,29 @@ function loadConfig4() {
|
|
|
8400
8490
|
};
|
|
8401
8491
|
}
|
|
8402
8492
|
function buildFrontend2() {
|
|
8403
|
-
console.log(
|
|
8493
|
+
console.log(import_chalk23.default.blue("Building frontend..."));
|
|
8404
8494
|
try {
|
|
8405
8495
|
(0, import_child_process6.execSync)("npm run build:frontend", {
|
|
8406
8496
|
cwd: PROJECT_DIR5,
|
|
8407
8497
|
stdio: "inherit"
|
|
8408
8498
|
});
|
|
8409
|
-
console.log(
|
|
8499
|
+
console.log(import_chalk23.default.green("Frontend built"));
|
|
8410
8500
|
} catch (error) {
|
|
8411
8501
|
throw createCommandError("frontend build", "npm run build:frontend", error, [
|
|
8412
8502
|
"Fix the frontend build error shown above, then rerun `pinme update-web`."
|
|
8413
8503
|
]);
|
|
8414
8504
|
}
|
|
8415
8505
|
}
|
|
8416
|
-
function deployFrontend2(projectName) {
|
|
8417
|
-
console.log(
|
|
8506
|
+
async function deployFrontend2(projectName) {
|
|
8507
|
+
console.log(import_chalk23.default.blue("Deploying frontend to IPFS..."));
|
|
8418
8508
|
try {
|
|
8419
|
-
(
|
|
8420
|
-
|
|
8421
|
-
stdio: "inherit",
|
|
8422
|
-
env: {
|
|
8423
|
-
...process.env,
|
|
8424
|
-
PINME_PROJECT_NAME: projectName
|
|
8425
|
-
}
|
|
8509
|
+
const uploadResult = await uploadPath(import_path16.default.join(PROJECT_DIR5, "frontend", "dist"), {
|
|
8510
|
+
projectName
|
|
8426
8511
|
});
|
|
8427
|
-
console.log(
|
|
8512
|
+
console.log(import_chalk23.default.green(`Frontend deployed to IPFS: ${uploadResult.publicUrl}`));
|
|
8428
8513
|
} catch (error) {
|
|
8429
|
-
throw createCommandError("frontend deploy", "
|
|
8430
|
-
"Make sure `frontend/dist` exists and
|
|
8514
|
+
throw createCommandError("frontend deploy", "upload frontend/dist", error, [
|
|
8515
|
+
"Make sure `frontend/dist` exists and the upload API is reachable."
|
|
8431
8516
|
]);
|
|
8432
8517
|
}
|
|
8433
8518
|
}
|
|
@@ -8445,8 +8530,8 @@ async function updateWebCmd(options) {
|
|
|
8445
8530
|
if (import_fs_extra11.default.existsSync(tokenFileSrc) && !import_fs_extra11.default.existsSync(tokenFileDst)) {
|
|
8446
8531
|
import_fs_extra11.default.copySync(tokenFileSrc, tokenFileDst);
|
|
8447
8532
|
}
|
|
8448
|
-
console.log(
|
|
8449
|
-
console.log(
|
|
8533
|
+
console.log(import_chalk23.default.blue("Updating web (frontend)...\n"));
|
|
8534
|
+
console.log(import_chalk23.default.gray(`Project dir: ${PROJECT_DIR5}`));
|
|
8450
8535
|
const config = loadConfig4();
|
|
8451
8536
|
const projectName = config.project_name;
|
|
8452
8537
|
if (!projectName) {
|
|
@@ -8454,11 +8539,11 @@ async function updateWebCmd(options) {
|
|
|
8454
8539
|
'Set `project_name = "your-project-name"` in `pinme.toml`.'
|
|
8455
8540
|
]);
|
|
8456
8541
|
}
|
|
8457
|
-
console.log(
|
|
8458
|
-
console.log(
|
|
8542
|
+
console.log(import_chalk23.default.gray(`Project: ${projectName}`));
|
|
8543
|
+
console.log(import_chalk23.default.blue("\n--- Frontend Update ---"));
|
|
8459
8544
|
buildFrontend2();
|
|
8460
|
-
deployFrontend2(projectName);
|
|
8461
|
-
console.log(
|
|
8545
|
+
await deployFrontend2(projectName);
|
|
8546
|
+
console.log(import_chalk23.default.green("\nWeb update complete."));
|
|
8462
8547
|
process.exit(0);
|
|
8463
8548
|
} catch (error) {
|
|
8464
8549
|
printCliError(error, "Web update failed.");
|
|
@@ -8467,11 +8552,10 @@ async function updateWebCmd(options) {
|
|
|
8467
8552
|
}
|
|
8468
8553
|
|
|
8469
8554
|
// bin/delete.ts
|
|
8470
|
-
var
|
|
8555
|
+
var import_chalk24 = __toESM(require("chalk"));
|
|
8471
8556
|
var import_inquirer9 = __toESM(require("inquirer"));
|
|
8472
8557
|
var import_fs_extra12 = __toESM(require("fs-extra"));
|
|
8473
8558
|
var import_path17 = __toESM(require("path"));
|
|
8474
|
-
var API_BASE5 = "https://pinme.benny1996.win/api/v4";
|
|
8475
8559
|
function getProjectName() {
|
|
8476
8560
|
const configPath = import_path17.default.join(process.cwd(), "pinme.toml");
|
|
8477
8561
|
if (!import_fs_extra12.default.existsSync(configPath)) {
|
|
@@ -8482,27 +8566,27 @@ function getProjectName() {
|
|
|
8482
8566
|
return (match == null ? void 0 : match[1]) || null;
|
|
8483
8567
|
}
|
|
8484
8568
|
async function deleteCmd(options) {
|
|
8485
|
-
var
|
|
8569
|
+
var _a2, _b;
|
|
8486
8570
|
try {
|
|
8487
8571
|
const headers = getAuthHeaders();
|
|
8488
8572
|
if (!headers["authentication-tokens"] || !headers["token-address"]) {
|
|
8489
|
-
console.log(
|
|
8490
|
-
console.log(
|
|
8573
|
+
console.log(import_chalk24.default.yellow("\n\u26A0\uFE0F You are not logged in."));
|
|
8574
|
+
console.log(import_chalk24.default.gray("Please run: pinme login"));
|
|
8491
8575
|
process.exit(1);
|
|
8492
8576
|
}
|
|
8493
|
-
console.log(
|
|
8577
|
+
console.log(import_chalk24.default.blue("Deleting project...\n"));
|
|
8494
8578
|
let projectName = options.name || getProjectName();
|
|
8495
8579
|
if (!projectName) {
|
|
8496
|
-
console.log(
|
|
8497
|
-
console.log(
|
|
8498
|
-
console.log(
|
|
8499
|
-
console.log(
|
|
8500
|
-
console.log(
|
|
8501
|
-
console.log(
|
|
8580
|
+
console.log(import_chalk24.default.red("\n\u274C Error: Cannot find project name."));
|
|
8581
|
+
console.log(import_chalk24.default.yellow(" Please make sure you are in the project directory."));
|
|
8582
|
+
console.log(import_chalk24.default.gray(" The project directory should contain a pinme.toml file."));
|
|
8583
|
+
console.log(import_chalk24.default.gray("\n Or specify the project name:"));
|
|
8584
|
+
console.log(import_chalk24.default.gray(" cd /path/to/your-project"));
|
|
8585
|
+
console.log(import_chalk24.default.gray(" pinme delete"));
|
|
8502
8586
|
process.exit(1);
|
|
8503
8587
|
}
|
|
8504
|
-
console.log(
|
|
8505
|
-
console.log(
|
|
8588
|
+
console.log(import_chalk24.default.gray(`Project: ${projectName}`));
|
|
8589
|
+
console.log(import_chalk24.default.gray(`Directory: ${process.cwd()}`));
|
|
8506
8590
|
if (!options.force) {
|
|
8507
8591
|
const answers = await import_inquirer9.default.prompt([
|
|
8508
8592
|
{
|
|
@@ -8513,14 +8597,14 @@ async function deleteCmd(options) {
|
|
|
8513
8597
|
}
|
|
8514
8598
|
]);
|
|
8515
8599
|
if (!answers.confirm) {
|
|
8516
|
-
console.log(
|
|
8600
|
+
console.log(import_chalk24.default.gray("Cancelled."));
|
|
8517
8601
|
process.exit(0);
|
|
8518
8602
|
}
|
|
8519
8603
|
}
|
|
8520
|
-
console.log(
|
|
8521
|
-
const apiUrl =
|
|
8522
|
-
console.log(
|
|
8523
|
-
console.log(
|
|
8604
|
+
console.log(import_chalk24.default.blue("Deleting project on platform..."));
|
|
8605
|
+
const apiUrl = getPinmeApiUrl("/delete_project");
|
|
8606
|
+
console.log(import_chalk24.default.gray(`API URL: ${apiUrl}`));
|
|
8607
|
+
console.log(import_chalk24.default.gray(`Project name: ${projectName}`));
|
|
8524
8608
|
const response = await axios_default.post(apiUrl, {
|
|
8525
8609
|
project_name: projectName
|
|
8526
8610
|
}, {
|
|
@@ -8529,33 +8613,33 @@ async function deleteCmd(options) {
|
|
|
8529
8613
|
"Content-Type": "application/json"
|
|
8530
8614
|
}
|
|
8531
8615
|
}).catch((error) => {
|
|
8532
|
-
var
|
|
8616
|
+
var _a3, _b2;
|
|
8533
8617
|
if (error.response) {
|
|
8534
|
-
console.log(
|
|
8535
|
-
console.log(
|
|
8618
|
+
console.log(import_chalk24.default.red(` Response status: ${(_a3 = error.response) == null ? void 0 : _a3.status}`));
|
|
8619
|
+
console.log(import_chalk24.default.red(` Response data: ${JSON.stringify((_b2 = error.response) == null ? void 0 : _b2.data)}`));
|
|
8536
8620
|
} else {
|
|
8537
|
-
console.log(
|
|
8621
|
+
console.log(import_chalk24.default.red("No Response"));
|
|
8538
8622
|
}
|
|
8539
8623
|
throw error;
|
|
8540
8624
|
});
|
|
8541
8625
|
const data = response.data;
|
|
8542
8626
|
if (data.code === 200) {
|
|
8543
|
-
console.log(
|
|
8544
|
-
console.log(
|
|
8627
|
+
console.log(import_chalk24.default.green("\n\u2705 Project deleted successfully!"));
|
|
8628
|
+
console.log(import_chalk24.default.gray(`
|
|
8545
8629
|
Project: ${data.data.project_name}`));
|
|
8546
|
-
console.log(
|
|
8547
|
-
console.log(
|
|
8548
|
-
console.log(
|
|
8549
|
-
console.log(
|
|
8630
|
+
console.log(import_chalk24.default.gray(` Domain deleted: ${data.data.domain_deleted ? "\u2705" : "\u274C"}`));
|
|
8631
|
+
console.log(import_chalk24.default.gray(` Worker deleted: ${data.data.worker_deleted ? "\u2705" : "\u274C"}`));
|
|
8632
|
+
console.log(import_chalk24.default.gray(` Database deleted: ${data.data.database_deleted ? "\u2705" : "\u274C"}`));
|
|
8633
|
+
console.log(import_chalk24.default.gray("\nLocal files are kept unchanged."));
|
|
8550
8634
|
} else {
|
|
8551
8635
|
const errorMsg = (data == null ? void 0 : data.msg) || "Failed to delete project";
|
|
8552
8636
|
throw new Error(errorMsg);
|
|
8553
8637
|
}
|
|
8554
8638
|
process.exit(0);
|
|
8555
8639
|
} catch (error) {
|
|
8556
|
-
console.log(
|
|
8557
|
-
const errorMsg = ((_b = (
|
|
8558
|
-
console.error(
|
|
8640
|
+
console.log(import_chalk24.default.red(error));
|
|
8641
|
+
const errorMsg = ((_b = (_a2 = error.response) == null ? void 0 : _a2.data) == null ? void 0 : _b.msg) || error.message || "Failed to delete project";
|
|
8642
|
+
console.error(import_chalk24.default.red(`
|
|
8559
8643
|
\u274C Error: ${errorMsg}`));
|
|
8560
8644
|
process.exit(1);
|
|
8561
8645
|
}
|
|
@@ -8566,9 +8650,9 @@ import_dotenv.default.config();
|
|
|
8566
8650
|
checkNodeVersion();
|
|
8567
8651
|
function showBanner() {
|
|
8568
8652
|
console.log(
|
|
8569
|
-
|
|
8653
|
+
import_chalk25.default.cyan(import_figlet5.default.textSync("Pinme", { horizontalLayout: "full" }))
|
|
8570
8654
|
);
|
|
8571
|
-
console.log(
|
|
8655
|
+
console.log(import_chalk25.default.cyan("A command-line tool for uploading files to IPFS\n"));
|
|
8572
8656
|
}
|
|
8573
8657
|
var program = new import_commander.Command();
|
|
8574
8658
|
program.name("pinme").version(version).option("-v, --version", "output the current version");
|
|
@@ -8585,7 +8669,8 @@ program.command("set-appkey").description(
|
|
|
8585
8669
|
program.command("logout").description("log out and clear authentication").action(() => logoutCmd());
|
|
8586
8670
|
program.command("show-appkey").alias("appkey").description("show current AppKey information (masked)").action(() => showAppKeyCmd());
|
|
8587
8671
|
program.command("my-domains").alias("domain").description("List domains owned by current account").action(() => myDomainsCmd());
|
|
8588
|
-
program.command("
|
|
8672
|
+
program.command("wallet").alias("wallet-balance").alias("balance").description("Show current wallet balance").action(() => walletBalanceCmd());
|
|
8673
|
+
program.command("bind").description("Upload and bind to a domain (requires wallet balance)").option("-d, --domain <name>", "Domain name to bind").option("--dns", "Force DNS domain mode").action(() => bindCmd());
|
|
8589
8674
|
program.command("create").description("Create a new project from template").argument("[name]", "Project name").option("-f, --force", "Overwrite if exists").action((name, options) => createCmd({ name, force: options == null ? void 0 : options.force }));
|
|
8590
8675
|
program.command("save").description("Deploy the project (frontend + backend)").action((options) => saveCmd(options));
|
|
8591
8676
|
program.command("update-db").description("Execute database migration").action(() => updateDbCmd());
|