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