pinme 1.2.6 → 2.0.0-alpha.1

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.
Files changed (2) hide show
  1. package/dist/index.js +1997 -352
  2. package/package.json +31 -29
package/dist/index.js CHANGED
@@ -96,10 +96,10 @@ var require_package = __commonJS({
96
96
  // node_modules/.pnpm/dotenv@16.5.0/node_modules/dotenv/lib/main.js
97
97
  var require_main = __commonJS({
98
98
  "node_modules/.pnpm/dotenv@16.5.0/node_modules/dotenv/lib/main.js"(exports2, module2) {
99
- var fs9 = require("fs");
100
- var path10 = require("path");
101
- var os4 = require("os");
102
- var crypto2 = require("crypto");
99
+ var fs16 = require("fs");
100
+ var path17 = require("path");
101
+ var os5 = require("os");
102
+ var crypto3 = require("crypto");
103
103
  var packageJson = require_package();
104
104
  var version2 = packageJson.version;
105
105
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
@@ -200,7 +200,7 @@ var require_main = __commonJS({
200
200
  if (options && options.path && options.path.length > 0) {
201
201
  if (Array.isArray(options.path)) {
202
202
  for (const filepath of options.path) {
203
- if (fs9.existsSync(filepath)) {
203
+ if (fs16.existsSync(filepath)) {
204
204
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
205
205
  }
206
206
  }
@@ -208,15 +208,15 @@ var require_main = __commonJS({
208
208
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
209
209
  }
210
210
  } else {
211
- possibleVaultPath = path10.resolve(process.cwd(), ".env.vault");
211
+ possibleVaultPath = path17.resolve(process.cwd(), ".env.vault");
212
212
  }
213
- if (fs9.existsSync(possibleVaultPath)) {
213
+ if (fs16.existsSync(possibleVaultPath)) {
214
214
  return possibleVaultPath;
215
215
  }
216
216
  return null;
217
217
  }
218
218
  function _resolveHome(envPath) {
219
- return envPath[0] === "~" ? path10.join(os4.homedir(), envPath.slice(1)) : envPath;
219
+ return envPath[0] === "~" ? path17.join(os5.homedir(), envPath.slice(1)) : envPath;
220
220
  }
221
221
  function _configVault(options) {
222
222
  const debug = Boolean(options && options.debug);
@@ -232,7 +232,7 @@ var require_main = __commonJS({
232
232
  return { parsed };
233
233
  }
234
234
  function configDotenv(options) {
235
- const dotenvPath = path10.resolve(process.cwd(), ".env");
235
+ const dotenvPath = path17.resolve(process.cwd(), ".env");
236
236
  let encoding = "utf8";
237
237
  const debug = Boolean(options && options.debug);
238
238
  if (options && options.encoding) {
@@ -255,13 +255,13 @@ var require_main = __commonJS({
255
255
  }
256
256
  let lastError;
257
257
  const parsedAll = {};
258
- for (const path11 of optionPaths) {
258
+ for (const path18 of optionPaths) {
259
259
  try {
260
- const parsed = DotenvModule.parse(fs9.readFileSync(path11, { encoding }));
260
+ const parsed = DotenvModule.parse(fs16.readFileSync(path18, { encoding }));
261
261
  DotenvModule.populate(parsedAll, parsed, options);
262
262
  } catch (e) {
263
263
  if (debug) {
264
- _debug(`Failed to load ${path11} ${e.message}`);
264
+ _debug(`Failed to load ${path18} ${e.message}`);
265
265
  }
266
266
  lastError = e;
267
267
  }
@@ -295,7 +295,7 @@ var require_main = __commonJS({
295
295
  const authTag = ciphertext.subarray(-16);
296
296
  ciphertext = ciphertext.subarray(12, -16);
297
297
  try {
298
- const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
298
+ const aesgcm = crypto3.createDecipheriv("aes-256-gcm", key, nonce);
299
299
  aesgcm.setAuthTag(authTag);
300
300
  return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
301
301
  } catch (error) {
@@ -810,7 +810,7 @@ var require_has_flag = __commonJS({
810
810
  var require_supports_color = __commonJS({
811
811
  "node_modules/.pnpm/supports-color@5.5.0/node_modules/supports-color/index.js"(exports2, module2) {
812
812
  "use strict";
813
- var os4 = require("os");
813
+ var os5 = require("os");
814
814
  var hasFlag = require_has_flag();
815
815
  var env = process.env;
816
816
  var forceColor;
@@ -848,7 +848,7 @@ var require_supports_color = __commonJS({
848
848
  }
849
849
  const min = forceColor ? 1 : 0;
850
850
  if (process.platform === "win32") {
851
- const osRelease = os4.release().split(".");
851
+ const osRelease = os5.release().split(".");
852
852
  if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
853
853
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
854
854
  }
@@ -1033,8 +1033,8 @@ 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 URL4 = url2.URL;
1037
- var http2 = require("http");
1036
+ var URL5 = url2.URL;
1037
+ var http3 = require("http");
1038
1038
  var https2 = require("https");
1039
1039
  var Writable = require("stream").Writable;
1040
1040
  var assert = require("assert");
@@ -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 URL4(input));
1370
+ parsed = urlToOptions(new URL5(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 (URL4 && input instanceof URL4) {
1378
+ } else if (URL5 && input instanceof URL5) {
1379
1379
  input = urlToOptions(input);
1380
1380
  } else {
1381
1381
  callback = options;
@@ -1473,7 +1473,7 @@ var require_follow_redirects = __commonJS({
1473
1473
  function isBuffer2(value) {
1474
1474
  return typeof value === "object" && "length" in value;
1475
1475
  }
1476
- module2.exports = wrap({ http: http2, https: https2 });
1476
+ module2.exports = wrap({ http: http3, https: https2 });
1477
1477
  module2.exports.wrap = wrap;
1478
1478
  }
1479
1479
  });
@@ -1519,15 +1519,15 @@ function checkNodeVersion() {
1519
1519
 
1520
1520
  // bin/index.ts
1521
1521
  var import_commander = require("commander");
1522
- var import_chalk14 = __toESM(require("chalk"));
1522
+ var import_chalk23 = __toESM(require("chalk"));
1523
1523
  var import_figlet5 = __toESM(require("figlet"));
1524
1524
 
1525
1525
  // package.json
1526
- var version = "1.2.6";
1526
+ var version = "2.0.0-alpha.1";
1527
1527
 
1528
1528
  // bin/upload.ts
1529
- var import_path6 = __toESM(require("path"));
1530
- var import_chalk4 = __toESM(require("chalk"));
1529
+ var import_path7 = __toESM(require("path"));
1530
+ var import_chalk5 = __toESM(require("chalk"));
1531
1531
  var import_inquirer = __toESM(require("inquirer"));
1532
1532
  var import_figlet = __toESM(require("figlet"));
1533
1533
 
@@ -1968,9 +1968,9 @@ function isVisitable(thing) {
1968
1968
  function removeBrackets(key) {
1969
1969
  return utils_default.endsWith(key, "[]") ? key.slice(0, -2) : key;
1970
1970
  }
1971
- function renderKey(path10, key, dots) {
1972
- if (!path10) return key;
1973
- return path10.concat(key).map(function each(token, i) {
1971
+ function renderKey(path17, key, dots) {
1972
+ if (!path17) return key;
1973
+ return path17.concat(key).map(function each(token, i) {
1974
1974
  token = removeBrackets(token);
1975
1975
  return !dots && i ? "[" + token + "]" : token;
1976
1976
  }).join(dots ? "." : "");
@@ -2015,9 +2015,9 @@ function toFormData(obj, formData, options) {
2015
2015
  }
2016
2016
  return value;
2017
2017
  }
2018
- function defaultVisitor(value, key, path10) {
2018
+ function defaultVisitor(value, key, path17) {
2019
2019
  let arr = value;
2020
- if (value && !path10 && typeof value === "object") {
2020
+ if (value && !path17 && typeof value === "object") {
2021
2021
  if (utils_default.endsWith(key, "{}")) {
2022
2022
  key = metaTokens ? key : key.slice(0, -2);
2023
2023
  value = JSON.stringify(value);
@@ -2036,7 +2036,7 @@ function toFormData(obj, formData, options) {
2036
2036
  if (isVisitable(value)) {
2037
2037
  return true;
2038
2038
  }
2039
- formData.append(renderKey(path10, key, dots), convertValue(value));
2039
+ formData.append(renderKey(path17, key, dots), convertValue(value));
2040
2040
  return false;
2041
2041
  }
2042
2042
  const stack = [];
@@ -2045,10 +2045,10 @@ function toFormData(obj, formData, options) {
2045
2045
  convertValue,
2046
2046
  isVisitable
2047
2047
  });
2048
- function build(value, path10) {
2048
+ function build(value, path17) {
2049
2049
  if (utils_default.isUndefined(value)) return;
2050
2050
  if (stack.indexOf(value) !== -1) {
2051
- throw Error("Circular reference detected in " + path10.join("."));
2051
+ throw Error("Circular reference detected in " + path17.join("."));
2052
2052
  }
2053
2053
  stack.push(value);
2054
2054
  utils_default.forEach(value, function each(el, key) {
@@ -2056,11 +2056,11 @@ function toFormData(obj, formData, options) {
2056
2056
  formData,
2057
2057
  el,
2058
2058
  utils_default.isString(key) ? key.trim() : key,
2059
- path10,
2059
+ path17,
2060
2060
  exposedHelpers
2061
2061
  );
2062
2062
  if (result === true) {
2063
- build(el, path10 ? path10.concat(key) : [key]);
2063
+ build(el, path17 ? path17.concat(key) : [key]);
2064
2064
  }
2065
2065
  });
2066
2066
  stack.pop();
@@ -2221,7 +2221,7 @@ var node_default = {
2221
2221
  // node_modules/.pnpm/axios@1.3.2/node_modules/axios/lib/helpers/toURLEncodedForm.js
2222
2222
  function toURLEncodedForm(data, options) {
2223
2223
  return toFormData_default(data, new node_default.classes.URLSearchParams(), Object.assign({
2224
- visitor: function(value, key, path10, helpers) {
2224
+ visitor: function(value, key, path17, helpers) {
2225
2225
  if (node_default.isNode && utils_default.isBuffer(value)) {
2226
2226
  this.append(key, value.toString("base64"));
2227
2227
  return false;
@@ -2250,10 +2250,10 @@ function arrayToObject(arr) {
2250
2250
  return obj;
2251
2251
  }
2252
2252
  function formDataToJSON(formData) {
2253
- function buildPath(path10, value, target, index) {
2254
- let name = path10[index++];
2253
+ function buildPath(path17, value, target, index) {
2254
+ let name = path17[index++];
2255
2255
  const isNumericKey = Number.isFinite(+name);
2256
- const isLast = index >= path10.length;
2256
+ const isLast = index >= path17.length;
2257
2257
  name = !name && utils_default.isArray(target) ? target.length : name;
2258
2258
  if (isLast) {
2259
2259
  if (utils_default.hasOwnProp(target, name)) {
@@ -2266,7 +2266,7 @@ function formDataToJSON(formData) {
2266
2266
  if (!target[name] || !utils_default.isObject(target[name])) {
2267
2267
  target[name] = [];
2268
2268
  }
2269
- const result = buildPath(path10, value, target[name], index);
2269
+ const result = buildPath(path17, value, target[name], index);
2270
2270
  if (result && utils_default.isArray(target[name])) {
2271
2271
  target[name] = arrayToObject(target[name]);
2272
2272
  }
@@ -3328,9 +3328,9 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
3328
3328
  auth = urlUsername + ":" + urlPassword;
3329
3329
  }
3330
3330
  auth && headers.delete("authorization");
3331
- let path10;
3331
+ let path17;
3332
3332
  try {
3333
- path10 = buildURL(
3333
+ path17 = buildURL(
3334
3334
  parsed.pathname + parsed.search,
3335
3335
  config.params,
3336
3336
  config.paramsSerializer
@@ -3348,7 +3348,7 @@ var http_default = isHttpAdapterSupported && function httpAdapter(config) {
3348
3348
  false
3349
3349
  );
3350
3350
  const options = {
3351
- path: path10,
3351
+ path: path17,
3352
3352
  method,
3353
3353
  headers: headers.toJSON(),
3354
3354
  agents: { http: config.httpAgent, https: config.httpsAgent },
@@ -3567,14 +3567,14 @@ var cookies_default = node_default.isStandardBrowserEnv ? (
3567
3567
  // Standard browser envs support document.cookie
3568
3568
  /* @__PURE__ */ function standardBrowserEnv() {
3569
3569
  return {
3570
- write: function write(name, value, expires, path10, domain, secure) {
3570
+ write: function write(name, value, expires, path17, domain, secure) {
3571
3571
  const cookie = [];
3572
3572
  cookie.push(name + "=" + encodeURIComponent(value));
3573
3573
  if (utils_default.isNumber(expires)) {
3574
3574
  cookie.push("expires=" + new Date(expires).toGMTString());
3575
3575
  }
3576
- if (utils_default.isString(path10)) {
3577
- cookie.push("path=" + path10);
3576
+ if (utils_default.isString(path17)) {
3577
+ cookie.push("path=" + path17);
3578
3578
  }
3579
3579
  if (utils_default.isString(domain)) {
3580
3580
  cookie.push("domain=" + domain);
@@ -4399,11 +4399,11 @@ var {
4399
4399
  } = axios_default;
4400
4400
 
4401
4401
  // bin/utils/uploadToIpfsSplit.ts
4402
- var import_fs_extra4 = __toESM(require("fs-extra"));
4403
- var import_path5 = __toESM(require("path"));
4402
+ var import_fs_extra5 = __toESM(require("fs-extra"));
4403
+ var import_path6 = __toESM(require("path"));
4404
4404
  var import_form_data2 = __toESM(require("form-data"));
4405
4405
  var import_ora = __toESM(require("ora"));
4406
- var crypto = __toESM(require("crypto"));
4406
+ var crypto2 = __toESM(require("crypto"));
4407
4407
 
4408
4408
  // bin/utils/uploadLimits.ts
4409
4409
  var import_fs = __toESM(require("fs"));
@@ -4551,38 +4551,6 @@ var import_os2 = __toESM(require("os"));
4551
4551
  var import_path3 = __toESM(require("path"));
4552
4552
  var CONFIG_DIR = import_path3.default.join(import_os2.default.homedir(), ".pinme");
4553
4553
  var AUTH_FILE = import_path3.default.join(CONFIG_DIR, "auth.json");
4554
- function ensureConfigDir() {
4555
- if (!import_fs_extra2.default.existsSync(CONFIG_DIR)) {
4556
- import_fs_extra2.default.mkdirSync(CONFIG_DIR, { recursive: true });
4557
- }
4558
- }
4559
- function parseCombinedToken(combined) {
4560
- const firstDash = combined.indexOf("-");
4561
- if (firstDash <= 0 || firstDash === combined.length - 1) {
4562
- throw new Error('Invalid token format. Expected "<address>-<jwt>".');
4563
- }
4564
- const address = combined.slice(0, firstDash).trim();
4565
- const token = combined.slice(firstDash + 1).trim();
4566
- if (!address || !token) {
4567
- throw new Error("Invalid token content. Address or token is empty.");
4568
- }
4569
- return { address, token };
4570
- }
4571
- function setAuthToken(combined) {
4572
- ensureConfigDir();
4573
- const auth = parseCombinedToken(combined);
4574
- import_fs_extra2.default.writeJsonSync(AUTH_FILE, auth, { spaces: 2 });
4575
- return auth;
4576
- }
4577
- function clearAuthToken() {
4578
- try {
4579
- if (import_fs_extra2.default.existsSync(AUTH_FILE)) {
4580
- import_fs_extra2.default.removeSync(AUTH_FILE);
4581
- }
4582
- } catch (error) {
4583
- console.error(`Failed to clear auth token: ${error}`);
4584
- }
4585
- }
4586
4554
  function getAuthConfig() {
4587
4555
  try {
4588
4556
  if (!import_fs_extra2.default.existsSync(AUTH_FILE)) return null;
@@ -4593,16 +4561,6 @@ function getAuthConfig() {
4593
4561
  return null;
4594
4562
  }
4595
4563
  }
4596
- function getAuthHeaders() {
4597
- const conf = getAuthConfig();
4598
- if (!conf) {
4599
- throw new Error("Auth not set. Run: pinme set-appkey <AppKey>");
4600
- }
4601
- return {
4602
- "token-address": conf.address,
4603
- "authentication-tokens": conf.token
4604
- };
4605
- }
4606
4564
 
4607
4565
  // bin/utils/getDeviceId.ts
4608
4566
  function getDeviceId() {
@@ -4626,8 +4584,504 @@ function getUid() {
4626
4584
  return getDeviceId();
4627
4585
  }
4628
4586
 
4587
+ // 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
+ function openBrowser(url2) {
4597
+ const platform = process.platform;
4598
+ let command;
4599
+ if (platform === "darwin") {
4600
+ command = `open "${url2}"`;
4601
+ } else if (platform === "win32") {
4602
+ command = `start "" "${url2}"`;
4603
+ } else {
4604
+ command = `xdg-open "${url2}"`;
4605
+ }
4606
+ (0, import_child_process.exec)(command, (err) => {
4607
+ if (err) {
4608
+ console.log(import_chalk3.default.yellow(`Unable to open browser automatically. Please visit manually: ${url2}`));
4609
+ }
4610
+ });
4611
+ }
4612
+ var CONFIG_DIR2 = import_path5.default.join(import_os4.default.homedir(), ".pinme");
4613
+ var AUTH_FILE2 = import_path5.default.join(CONFIG_DIR2, "auth.json");
4614
+ var DEFAULT_OPTIONS = {
4615
+ apiBaseUrl: "https://pinme.benny1996.win/api/v4",
4616
+ webBaseUrl: process.env.PINME_WEB_URL || "http://localhost:5173",
4617
+ callbackPort: 34567,
4618
+ callbackPath: "/cli/callback"
4619
+ };
4620
+ var WebLoginManager = class {
4621
+ config;
4622
+ server = null;
4623
+ resolvePromise = null;
4624
+ rejectPromise = null;
4625
+ loginToken = "";
4626
+ constructor(options = {}) {
4627
+ this.config = { ...DEFAULT_OPTIONS, ...options };
4628
+ }
4629
+ async login() {
4630
+ console.log(import_chalk3.default.blue("Starting login flow...\n"));
4631
+ this.loginToken = this.generateLoginToken();
4632
+ console.log(import_chalk3.default.blue("Starting local callback server..."));
4633
+ await this.startCallbackServer();
4634
+ try {
4635
+ const loginUrl = this.buildLoginUrl();
4636
+ console.log(import_chalk3.default.blue("Opening browser..."));
4637
+ console.log(import_chalk3.default.white("If browser does not open automatically, please visit manually:"));
4638
+ console.log(import_chalk3.default.cyan(` ${loginUrl}
4639
+ `));
4640
+ openBrowser(loginUrl);
4641
+ console.log(import_chalk3.default.yellow("Please complete login in browser..."));
4642
+ console.log(import_chalk3.default.gray("Browser will close automatically after successful login.\n"));
4643
+ const authToken = await this.waitForCallback();
4644
+ const authConfig = this.parseAuthToken(authToken);
4645
+ this.saveAuthConfig(authConfig);
4646
+ console.log(import_chalk3.default.green("\nLogin successful!"));
4647
+ if (authConfig.email) {
4648
+ console.log(import_chalk3.default.green(`Welcome, ${authConfig.email}`));
4649
+ }
4650
+ console.log(import_chalk3.default.gray(`Address: ${authConfig.address}`));
4651
+ return authConfig;
4652
+ } catch (error) {
4653
+ console.error(import_chalk3.default.red(`
4654
+ Login failed: ${error.message}`));
4655
+ throw error;
4656
+ } finally {
4657
+ this.closeServer();
4658
+ }
4659
+ }
4660
+ generateLoginToken() {
4661
+ return import_crypto.default.randomBytes(32).toString("hex");
4662
+ }
4663
+ async startCallbackServer() {
4664
+ return new Promise((resolve, reject) => {
4665
+ this.server = import_http3.default.createServer(async (req, res) => {
4666
+ try {
4667
+ const url2 = new import_url2.URL(req.url || "", `http://localhost:${this.config.callbackPort}`);
4668
+ if (url2.pathname === this.config.callbackPath) {
4669
+ const authToken = url2.searchParams.get("token");
4670
+ const error = url2.searchParams.get("error");
4671
+ const loginToken = url2.searchParams.get("login_token");
4672
+ if (error) {
4673
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
4674
+ res.end(this.getErrorHtml(error));
4675
+ if (this.rejectPromise) {
4676
+ this.rejectPromise(new Error(error));
4677
+ }
4678
+ return;
4679
+ }
4680
+ if (!authToken) {
4681
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
4682
+ res.end(this.getErrorHtml("Auth token not received"));
4683
+ if (this.rejectPromise) {
4684
+ this.rejectPromise(new Error("Auth token not received"));
4685
+ }
4686
+ return;
4687
+ }
4688
+ if (loginToken !== this.loginToken) {
4689
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
4690
+ res.end(this.getErrorHtml("Login token invalid or expired"));
4691
+ if (this.rejectPromise) {
4692
+ this.rejectPromise(new Error("Login token invalid or expired"));
4693
+ }
4694
+ return;
4695
+ }
4696
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
4697
+ res.end(this.getSuccessHtml());
4698
+ if (this.resolvePromise) {
4699
+ this.resolvePromise(authToken);
4700
+ }
4701
+ } else {
4702
+ res.writeHead(404, { "Content-Type": "text/plain" });
4703
+ res.end("Not Found");
4704
+ }
4705
+ } catch (err) {
4706
+ console.error("Callback error:", err);
4707
+ res.writeHead(500, { "Content-Type": "text/plain" });
4708
+ res.end("Internal Server Error");
4709
+ }
4710
+ });
4711
+ this.server.on("error", (err) => {
4712
+ reject(err);
4713
+ });
4714
+ this.server.listen(this.config.callbackPort, "127.0.0.1", () => {
4715
+ console.log(import_chalk3.default.gray(`Local server: http://localhost:${this.config.callbackPort}`));
4716
+ resolve();
4717
+ });
4718
+ setTimeout(() => {
4719
+ if (this.rejectPromise) {
4720
+ this.rejectPromise(new Error("Login timeout, please try again"));
4721
+ }
4722
+ this.closeServer();
4723
+ }, 10 * 60 * 1e3);
4724
+ });
4725
+ }
4726
+ buildLoginUrl() {
4727
+ const callbackUrl = `http://localhost:${this.config.callbackPort}${this.config.callbackPath}`;
4728
+ const url2 = `${this.config.webBaseUrl}/#/cli-login?login_token=${this.loginToken}&callback_url=${encodeURIComponent(callbackUrl)}`;
4729
+ return url2;
4730
+ }
4731
+ waitForCallback() {
4732
+ return new Promise((resolve, reject) => {
4733
+ this.resolvePromise = resolve;
4734
+ this.rejectPromise = reject;
4735
+ });
4736
+ }
4737
+ parseAuthToken(authToken) {
4738
+ const firstDash = authToken.indexOf("-");
4739
+ if (firstDash <= 0 || firstDash === authToken.length - 1) {
4740
+ throw new Error("Invalid token format");
4741
+ }
4742
+ const address = authToken.slice(0, firstDash).trim();
4743
+ const token = authToken.slice(firstDash + 1).trim();
4744
+ if (!address || !token) {
4745
+ throw new Error("Token parsing failed: address or token is empty");
4746
+ }
4747
+ return { address, token };
4748
+ }
4749
+ saveAuthConfig(config) {
4750
+ import_fs_extra4.default.ensureDirSync(CONFIG_DIR2);
4751
+ import_fs_extra4.default.writeJsonSync(AUTH_FILE2, config, { spaces: 2 });
4752
+ import_fs_extra4.default.chmodSync(AUTH_FILE2, 384);
4753
+ }
4754
+ closeServer() {
4755
+ if (this.server) {
4756
+ this.server.close();
4757
+ this.server = null;
4758
+ }
4759
+ }
4760
+ // HTML templates
4761
+ getSuccessHtml() {
4762
+ return `
4763
+ <!DOCTYPE html>
4764
+ <html>
4765
+ <head>
4766
+ <title>Login Success - PinMe</title>
4767
+ <style>
4768
+ * { margin: 0; padding: 0; box-sizing: border-box; }
4769
+ body {
4770
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
4771
+ display: flex;
4772
+ justify-content: center;
4773
+ align-items: center;
4774
+ min-height: 100vh;
4775
+ background: #000;
4776
+ overflow: hidden;
4777
+ }
4778
+ .bg {
4779
+ position: fixed;
4780
+ top: 0;
4781
+ left: 0;
4782
+ width: 100%;
4783
+ height: 100%;
4784
+ background:
4785
+ radial-gradient(ellipse at 20% 80%, rgba(120, 0, 255, 0.3) 0%, transparent 50%),
4786
+ radial-gradient(ellipse at 80% 20%, rgba(0, 200, 255, 0.3) 0%, transparent 50%),
4787
+ radial-gradient(ellipse at 50% 50%, rgba(255, 0, 150, 0.15) 0%, transparent 60%);
4788
+ animation: bgPulse 6s ease-in-out infinite;
4789
+ }
4790
+ @keyframes bgPulse {
4791
+ 0%, 100% { opacity: 1; transform: scale(1); }
4792
+ 50% { opacity: 0.8; transform: scale(1.05); }
4793
+ }
4794
+ .grid {
4795
+ position: fixed;
4796
+ top: 0;
4797
+ left: 0;
4798
+ width: 200%;
4799
+ height: 200%;
4800
+ background-image:
4801
+ linear-gradient(rgba(0, 200, 255, 0.03) 1px, transparent 1px),
4802
+ linear-gradient(90deg, rgba(0, 200, 255, 0.03) 1px, transparent 1px);
4803
+ background-size: 50px 50px;
4804
+ transform: perspective(500px) rotateX(60deg) translateY(-50%) translateZ(-200px);
4805
+ animation: gridMove 20s linear infinite;
4806
+ }
4807
+ @keyframes gridMove {
4808
+ 0% { transform: perspective(500px) rotateX(60deg) translateY(0) translateZ(-200px); }
4809
+ 100% { transform: perspective(500px) rotateX(60deg) translateY(50px) translateZ(-200px); }
4810
+ }
4811
+ .container {
4812
+ position: relative;
4813
+ z-index: 10;
4814
+ background: linear-gradient(135deg, rgba(20, 20, 40, 0.9) 0%, rgba(10, 10, 30, 0.95) 100%);
4815
+ padding: 3.5rem 4rem;
4816
+ border-radius: 32px;
4817
+ box-shadow:
4818
+ 0 0 60px rgba(0, 200, 255, 0.15),
4819
+ 0 25px 50px rgba(0, 0, 0, 0.5),
4820
+ inset 0 1px 0 rgba(255, 255, 255, 0.1),
4821
+ inset 0 -1px 0 rgba(0, 200, 255, 0.1);
4822
+ text-align: center;
4823
+ border: 1px solid rgba(0, 200, 255, 0.2);
4824
+ max-width: 440px;
4825
+ backdrop-filter: blur(30px);
4826
+ }
4827
+ .container::before {
4828
+ content: '';
4829
+ position: absolute;
4830
+ top: -1px;
4831
+ left: -1px;
4832
+ right: -1px;
4833
+ bottom: -1px;
4834
+ border-radius: 32px;
4835
+ background: linear-gradient(135deg, rgba(0, 200, 255, 0.5), rgba(255, 0, 150, 0.5), rgba(120, 0, 255, 0.5));
4836
+ z-index: -1;
4837
+ opacity: 0.5;
4838
+ animation: borderGlow 3s ease-in-out infinite;
4839
+ }
4840
+ @keyframes borderGlow {
4841
+ 0%, 100% { opacity: 0.3; }
4842
+ 50% { opacity: 0.7; }
4843
+ }
4844
+ .success-icon {
4845
+ font-size: 5rem;
4846
+ margin-bottom: 1.5rem;
4847
+ animation: bounceIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
4848
+ filter: drop-shadow(0 0 20px rgba(0, 200, 255, 0.5));
4849
+ }
4850
+ @keyframes bounceIn {
4851
+ 0% { transform: scale(0); opacity: 0; }
4852
+ 50% { transform: scale(1.2); }
4853
+ 100% { transform: scale(1); opacity: 1; }
4854
+ }
4855
+ h1 {
4856
+ color: #fff;
4857
+ font-size: 2.2rem;
4858
+ font-weight: 700;
4859
+ margin: 0 0 0.75rem 0;
4860
+ background: linear-gradient(90deg, #fff, #00d4ff);
4861
+ -webkit-background-clip: text;
4862
+ -webkit-text-fill-color: transparent;
4863
+ background-clip: text;
4864
+ }
4865
+ p {
4866
+ color: rgba(255, 255, 255, 0.6);
4867
+ font-size: 1.1rem;
4868
+ margin: 0 0 2rem 0;
4869
+ line-height: 1.6;
4870
+ }
4871
+ .highlight { color: #00d4ff; font-weight: 600; }
4872
+ .sparkle {
4873
+ position: absolute;
4874
+ width: 4px;
4875
+ height: 4px;
4876
+ background: #00d4ff;
4877
+ border-radius: 50%;
4878
+ animation: sparkle 2s ease-in-out infinite;
4879
+ }
4880
+ .sparkle:nth-child(1) { top: 20%; left: 10%; animation-delay: 0s; }
4881
+ .sparkle:nth-child(2) { top: 30%; right: 15%; animation-delay: 0.5s; }
4882
+ .sparkle:nth-child(3) { bottom: 25%; left: 20%; animation-delay: 1s; }
4883
+ .sparkle:nth-child(4) { bottom: 35%; right: 10%; animation-delay: 1.5s; }
4884
+ @keyframes sparkle {
4885
+ 0%, 100% { opacity: 0; transform: scale(0); }
4886
+ 50% { opacity: 1; transform: scale(1); }
4887
+ }
4888
+ </style>
4889
+ </head>
4890
+ <body>
4891
+ <div class="bg"></div>
4892
+ <div class="grid"></div>
4893
+ <div class="container">
4894
+ <div class="sparkle"></div>
4895
+ <div class="sparkle"></div>
4896
+ <div class="sparkle"></div>
4897
+ <div class="sparkle"></div>
4898
+ <div class="success-icon">\u{1F389}</div>
4899
+ <h1>Welcome to PinMe</h1>
4900
+ <p>You are now logged in! <span class="highlight">\u{1F680}</span><br>Return to your terminal to continue.</p>
4901
+ </div>
4902
+ </body>
4903
+ </html>`;
4904
+ }
4905
+ getErrorHtml(error) {
4906
+ const encodedError = encodeURIComponent(error);
4907
+ return `
4908
+ <!DOCTYPE html>
4909
+ <html>
4910
+ <head>
4911
+ <title>Login Failed - PinMe</title>
4912
+ <style>
4913
+ * { margin: 0; padding: 0; box-sizing: border-box; }
4914
+ body {
4915
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
4916
+ display: flex;
4917
+ justify-content: center;
4918
+ align-items: center;
4919
+ min-height: 100vh;
4920
+ background: #000;
4921
+ overflow: hidden;
4922
+ }
4923
+ .bg {
4924
+ position: fixed;
4925
+ top: 0;
4926
+ left: 0;
4927
+ width: 100%;
4928
+ height: 100%;
4929
+ background:
4930
+ radial-gradient(ellipse at 20% 80%, rgba(255, 50, 50, 0.2) 0%, transparent 50%),
4931
+ radial-gradient(ellipse at 80% 20%, rgba(255, 100, 50, 0.2) 0%, transparent 50%),
4932
+ radial-gradient(ellipse at 50% 50%, rgba(100, 0, 50, 0.15) 0%, transparent 60%);
4933
+ animation: bgPulse 6s ease-in-out infinite;
4934
+ }
4935
+ @keyframes bgPulse {
4936
+ 0%, 100% { opacity: 1; transform: scale(1); }
4937
+ 50% { opacity: 0.8; transform: scale(1.05); }
4938
+ }
4939
+ .grid {
4940
+ position: fixed;
4941
+ top: 0;
4942
+ left: 0;
4943
+ width: 200%;
4944
+ height: 200%;
4945
+ background-image:
4946
+ linear-gradient(rgba(255, 80, 80, 0.03) 1px, transparent 1px),
4947
+ linear-gradient(90deg, rgba(255, 80, 80, 0.03) 1px, transparent 1px);
4948
+ background-size: 50px 50px;
4949
+ transform: perspective(500px) rotateX(60deg) translateY(-50%) translateZ(-200px);
4950
+ animation: gridMove 20s linear infinite;
4951
+ }
4952
+ @keyframes gridMove {
4953
+ 0% { transform: perspective(500px) rotateX(60deg) translateY(0) translateZ(-200px); }
4954
+ 100% { transform: perspective(500px) rotateX(60deg) translateY(50px) translateZ(-200px); }
4955
+ }
4956
+ .container {
4957
+ position: relative;
4958
+ z-index: 10;
4959
+ background: linear-gradient(135deg, rgba(40, 20, 20, 0.9) 0%, rgba(30, 10, 10, 0.95) 100%);
4960
+ padding: 3.5rem 4rem;
4961
+ border-radius: 32px;
4962
+ box-shadow:
4963
+ 0 0 60px rgba(255, 50, 50, 0.15),
4964
+ 0 25px 50px rgba(0, 0, 0, 0.5),
4965
+ inset 0 1px 0 rgba(255, 255, 255, 0.1),
4966
+ inset 0 -1px 0 rgba(255, 50, 50, 0.1);
4967
+ text-align: center;
4968
+ border: 1px solid rgba(255, 50, 50, 0.2);
4969
+ max-width: 440px;
4970
+ backdrop-filter: blur(30px);
4971
+ }
4972
+ .container::before {
4973
+ content: '';
4974
+ position: absolute;
4975
+ top: -1px;
4976
+ left: -1px;
4977
+ right: -1px;
4978
+ bottom: -1px;
4979
+ border-radius: 32px;
4980
+ background: linear-gradient(135deg, rgba(255, 50, 50, 0.5), rgba(255, 150, 50, 0.5), rgba(150, 0, 50, 0.5));
4981
+ z-index: -1;
4982
+ opacity: 0.5;
4983
+ animation: borderGlow 3s ease-in-out infinite;
4984
+ }
4985
+ @keyframes borderGlow {
4986
+ 0%, 100% { opacity: 0.3; }
4987
+ 50% { opacity: 0.7; }
4988
+ }
4989
+ .error-icon {
4990
+ font-size: 5rem;
4991
+ margin-bottom: 1.5rem;
4992
+ animation: shake 0.5s ease-in-out;
4993
+ filter: drop-shadow(0 0 20px rgba(255, 50, 50, 0.5));
4994
+ }
4995
+ @keyframes shake {
4996
+ 0%, 100% { transform: translateX(0); }
4997
+ 20% { transform: translateX(-10px) rotate(-5deg); }
4998
+ 40% { transform: translateX(10px) rotate(5deg); }
4999
+ 60% { transform: translateX(-10px) rotate(-5deg); }
5000
+ 80% { transform: translateX(10px) rotate(5deg); }
5001
+ }
5002
+ h1 {
5003
+ color: #fff;
5004
+ font-size: 2.2rem;
5005
+ font-weight: 700;
5006
+ margin: 0 0 0.75rem 0;
5007
+ background: linear-gradient(90deg, #fff, #ff5050);
5008
+ -webkit-background-clip: text;
5009
+ -webkit-text-fill-color: transparent;
5010
+ background-clip: text;
5011
+ }
5012
+ .error {
5013
+ color: #ff6b6b;
5014
+ font-size: 1rem;
5015
+ margin: 0 0 2rem 0;
5016
+ padding: 1.25rem;
5017
+ background: rgba(255, 50, 50, 0.1);
5018
+ border-radius: 16px;
5019
+ border: 1px solid rgba(255, 50, 50, 0.2);
5020
+ font-weight: 500;
5021
+ box-shadow: 0 0 20px rgba(255, 50, 50, 0.1);
5022
+ }
5023
+ </style>
5024
+ </head>
5025
+ <body>
5026
+ <div class="bg"></div>
5027
+ <div class="grid"></div>
5028
+ <div class="container">
5029
+ <div class="error-icon">\u{1F635}</div>
5030
+ <h1>Oops!</h1>
5031
+ <div class="error">${error}</div>
5032
+ </div>
5033
+ </body>
5034
+ </html>`;
5035
+ }
5036
+ };
5037
+ var webLoginManager = new WebLoginManager();
5038
+ function setAuthToken(combined) {
5039
+ const firstDash = combined.indexOf("-");
5040
+ if (firstDash <= 0 || firstDash === combined.length - 1) {
5041
+ throw new Error('Invalid token format. Expected "<address>-<jwt>".');
5042
+ }
5043
+ const address = combined.slice(0, firstDash).trim();
5044
+ const token = combined.slice(firstDash + 1).trim();
5045
+ if (!address || !token) {
5046
+ throw new Error("Invalid token content. Address or token is empty.");
5047
+ }
5048
+ const config = { address, token };
5049
+ import_fs_extra4.default.ensureDirSync(CONFIG_DIR2);
5050
+ import_fs_extra4.default.writeJsonSync(AUTH_FILE2, config, { spaces: 2 });
5051
+ return config;
5052
+ }
5053
+ function getAuthConfig2() {
5054
+ try {
5055
+ if (!import_fs_extra4.default.existsSync(AUTH_FILE2)) return null;
5056
+ const data = import_fs_extra4.default.readJsonSync(AUTH_FILE2);
5057
+ if (!(data == null ? void 0 : data.address) || !(data == null ? void 0 : data.token)) return null;
5058
+ return data;
5059
+ } catch {
5060
+ return null;
5061
+ }
5062
+ }
5063
+ function clearAuthToken() {
5064
+ try {
5065
+ if (import_fs_extra4.default.existsSync(AUTH_FILE2)) {
5066
+ import_fs_extra4.default.removeSync(AUTH_FILE2);
5067
+ }
5068
+ } catch (error) {
5069
+ console.error(`Failed to clear auth token: ${error}`);
5070
+ }
5071
+ }
5072
+ function getAuthHeaders() {
5073
+ const conf = getAuthConfig2();
5074
+ if (!conf) {
5075
+ throw new Error("Auth not set. Run: pinme login");
5076
+ }
5077
+ return {
5078
+ "token-address": conf.address,
5079
+ "authentication-tokens": conf.token
5080
+ };
5081
+ }
5082
+
4629
5083
  // bin/utils/uploadToIpfsSplit.ts
4630
- var IPFS_API_URL = "https://pinme.dev/api/v3";
5084
+ var IPFS_API_URL = "https://pinme.benny1996.win/api/v3";
4631
5085
  var MAX_RETRIES = parseInt(process.env.MAX_RETRIES || "2");
4632
5086
  var RETRY_DELAY = parseInt(process.env.RETRY_DELAY_MS || "1000");
4633
5087
  var TIMEOUT = parseInt(process.env.TIMEOUT_MS || "600000");
@@ -4737,8 +5191,8 @@ var StepProgressBar = class {
4737
5191
  };
4738
5192
  async function calculateMD5(filePath) {
4739
5193
  return new Promise((resolve, reject) => {
4740
- const hash = crypto.createHash("md5");
4741
- const stream4 = import_fs_extra4.default.createReadStream(filePath);
5194
+ const hash = crypto2.createHash("md5");
5195
+ const stream4 = import_fs_extra5.default.createReadStream(filePath);
4742
5196
  stream4.on("data", hash.update.bind(hash));
4743
5197
  stream4.on("end", () => resolve(hash.digest("hex")));
4744
5198
  stream4.on("error", reject);
@@ -4747,20 +5201,20 @@ async function calculateMD5(filePath) {
4747
5201
  async function compressDirectory(sourcePath) {
4748
5202
  return new Promise((resolve, reject) => {
4749
5203
  const tempDir = require("os").tmpdir();
4750
- if (!import_fs_extra4.default.existsSync(tempDir)) {
4751
- import_fs_extra4.default.mkdirSync(tempDir, { recursive: true });
5204
+ if (!import_fs_extra5.default.existsSync(tempDir)) {
5205
+ import_fs_extra5.default.mkdirSync(tempDir, { recursive: true });
4752
5206
  }
4753
- const outputPath = import_path5.default.join(
5207
+ const outputPath = import_path6.default.join(
4754
5208
  tempDir,
4755
- `pinme_${import_path5.default.basename(sourcePath)}_${Date.now()}.zip`
5209
+ `pinme_${import_path6.default.basename(sourcePath)}_${Date.now()}.zip`
4756
5210
  );
4757
- const output = import_fs_extra4.default.createWriteStream(outputPath);
5211
+ const output = import_fs_extra5.default.createWriteStream(outputPath);
4758
5212
  const zlib2 = require("zlib");
4759
5213
  const gzip = zlib2.createGzip({ level: 9 });
4760
5214
  output.on("close", () => resolve(outputPath));
4761
5215
  gzip.on("error", reject);
4762
5216
  gzip.pipe(output);
4763
- const stats = import_fs_extra4.default.statSync(sourcePath);
5217
+ const stats = import_fs_extra5.default.statSync(sourcePath);
4764
5218
  if (stats.isDirectory()) {
4765
5219
  const archive = require("archiver");
4766
5220
  const archiveStream = archive("zip", { zlib: { level: 9 } });
@@ -4769,14 +5223,14 @@ async function compressDirectory(sourcePath) {
4769
5223
  archiveStream.directory(sourcePath, false);
4770
5224
  archiveStream.finalize();
4771
5225
  } else {
4772
- const fileStream = import_fs_extra4.default.createReadStream(sourcePath);
5226
+ const fileStream = import_fs_extra5.default.createReadStream(sourcePath);
4773
5227
  fileStream.pipe(gzip);
4774
5228
  }
4775
5229
  });
4776
5230
  }
4777
5231
  async function initChunkSession(filePath, deviceId, isDirectory = false) {
4778
- const stats = import_fs_extra4.default.statSync(filePath);
4779
- const fileName = import_path5.default.basename(filePath);
5232
+ const stats = import_fs_extra5.default.statSync(filePath);
5233
+ const fileName = import_path6.default.basename(filePath);
4780
5234
  const fileSize = stats.size;
4781
5235
  const md5 = await calculateMD5(filePath);
4782
5236
  try {
@@ -4877,7 +5331,7 @@ async function delayWithAbortCheck(delay, signal) {
4877
5331
  });
4878
5332
  }
4879
5333
  async function uploadFileChunks(filePath, sessionId, totalChunks, chunkSize, deviceId, progressBar) {
4880
- const fileData = import_fs_extra4.default.readFileSync(filePath);
5334
+ const fileData = import_fs_extra5.default.readFileSync(filePath);
4881
5335
  const abortController = new AbortController();
4882
5336
  let completedCount = 0;
4883
5337
  let hasFatalError = false;
@@ -4929,17 +5383,27 @@ async function uploadFileChunks(filePath, sessionId, totalChunks, chunkSize, dev
4929
5383
  }
4930
5384
  }
4931
5385
  async function completeChunkUpload(sessionId, deviceId, importAsCar = false) {
5386
+ var _a;
4932
5387
  try {
4933
5388
  const requestBody = { session_id: sessionId, uid: deviceId };
5389
+ const projectName = (_a = process.env.PINME_PROJECT_NAME) == null ? void 0 : _a.trim();
5390
+ let authHeaders = {};
4934
5391
  if (importAsCar) {
4935
5392
  requestBody.import_as_car = true;
4936
5393
  }
5394
+ if (projectName) {
5395
+ requestBody.project_name = projectName;
5396
+ authHeaders = getAuthHeaders();
5397
+ }
4937
5398
  const response = await axios_default.post(
4938
5399
  `${IPFS_API_URL}/chunk/complete`,
4939
5400
  requestBody,
4940
5401
  {
4941
5402
  timeout: TIMEOUT,
4942
- headers: { "Content-Type": "application/json" }
5403
+ headers: {
5404
+ "Content-Type": "application/json",
5405
+ ...authHeaders
5406
+ }
4943
5407
  }
4944
5408
  );
4945
5409
  const { code, msg, data } = response.data;
@@ -4955,11 +5419,19 @@ async function completeChunkUpload(sessionId, deviceId, importAsCar = false) {
4955
5419
  }
4956
5420
  }
4957
5421
  async function getChunkStatus(sessionId, deviceId) {
5422
+ var _a;
4958
5423
  try {
5424
+ const projectName = (_a = process.env.PINME_PROJECT_NAME) == null ? void 0 : _a.trim();
5425
+ const queryParams = new URLSearchParams({
5426
+ trace_id: sessionId,
5427
+ uid: deviceId
5428
+ });
5429
+ if (projectName) {
5430
+ queryParams.append("project_name", projectName);
5431
+ }
4959
5432
  const response = await axios_default.get(
4960
- `${IPFS_API_URL}/up_status`,
5433
+ `${IPFS_API_URL}/up_status?${queryParams.toString()}`,
4961
5434
  {
4962
- params: { trace_id: sessionId, uid: deviceId },
4963
5435
  timeout: TIMEOUT,
4964
5436
  headers: { "Content-Type": "application/json" }
4965
5437
  }
@@ -4991,9 +5463,12 @@ async function monitorChunkProgress(traceId, deviceId, progressBar) {
4991
5463
  if (progressBar) {
4992
5464
  progressBar.stopSimulatingProgress();
4993
5465
  }
5466
+ const shortUrl = status.upload_rst.ShortUrl;
5467
+ const domain = status.domain;
5468
+ const fullShortUrl = shortUrl && domain ? `${shortUrl}.${domain}` : shortUrl;
4994
5469
  return {
4995
5470
  hash: status.upload_rst.Hash,
4996
- shortUrl: status.upload_rst.ShortUrl
5471
+ shortUrl: fullShortUrl
4997
5472
  };
4998
5473
  }
4999
5474
  } catch (error) {
@@ -5021,7 +5496,7 @@ async function uploadDirectoryInChunks(directoryPath, deviceId, importAsCar = fa
5021
5496
  )} (size: ${formatSize(sizeCheck.size)})`
5022
5497
  );
5023
5498
  }
5024
- const progressBar = new StepProgressBar(import_path5.default.basename(directoryPath), true);
5499
+ const progressBar = new StepProgressBar(import_path6.default.basename(directoryPath), true);
5025
5500
  try {
5026
5501
  progressBar.startStep(0, "Preparing compression");
5027
5502
  const compressedPath = await compressDirectory(directoryPath);
@@ -5046,12 +5521,12 @@ async function uploadDirectoryInChunks(directoryPath, deviceId, importAsCar = fa
5046
5521
  const result = await monitorChunkProgress(traceId, deviceId, progressBar);
5047
5522
  progressBar.completeStep();
5048
5523
  try {
5049
- import_fs_extra4.default.unlinkSync(compressedPath);
5524
+ import_fs_extra5.default.unlinkSync(compressedPath);
5050
5525
  } catch (error) {
5051
5526
  }
5052
5527
  const uploadData = {
5053
5528
  path: directoryPath,
5054
- filename: import_path5.default.basename(directoryPath),
5529
+ filename: import_path6.default.basename(directoryPath),
5055
5530
  contentHash: (result == null ? void 0 : result.hash) || "unknown",
5056
5531
  size: sizeCheck.size,
5057
5532
  fileCount: 0,
@@ -5078,7 +5553,7 @@ async function uploadFileInChunks(filePath, deviceId, importAsCar = false) {
5078
5553
  )} (size: ${formatSize(sizeCheck.size)})`
5079
5554
  );
5080
5555
  }
5081
- const fileName = import_path5.default.basename(filePath);
5556
+ const fileName = import_path6.default.basename(filePath);
5082
5557
  const progressBar = new StepProgressBar(fileName, false);
5083
5558
  try {
5084
5559
  progressBar.startStep(0, "Initializing session");
@@ -5127,7 +5602,7 @@ async function uploadToIpfsSplit_default(filePath, importAsCar = false) {
5127
5602
  throw new Error("Device ID not found");
5128
5603
  }
5129
5604
  try {
5130
- const isDirectory = import_fs_extra4.default.statSync(filePath).isDirectory();
5605
+ const isDirectory = import_fs_extra5.default.statSync(filePath).isDirectory();
5131
5606
  const result = isDirectory ? await uploadDirectoryInChunks(filePath, deviceId, importAsCar) : await uploadFileInChunks(filePath, deviceId, importAsCar);
5132
5607
  if (result == null ? void 0 : result.hash) {
5133
5608
  return {
@@ -5136,9 +5611,9 @@ async function uploadToIpfsSplit_default(filePath, importAsCar = false) {
5136
5611
  shortUrl: result.shortUrl
5137
5612
  };
5138
5613
  }
5139
- return null;
5614
+ throw new Error("Upload failed: no hash returned");
5140
5615
  } catch (error) {
5141
- return null;
5616
+ throw error;
5142
5617
  }
5143
5618
  }
5144
5619
 
@@ -5147,8 +5622,8 @@ var import_fs2 = __toESM(require("fs"));
5147
5622
  var import_crypto_js = __toESM(require("crypto-js"));
5148
5623
 
5149
5624
  // bin/utils/pinmeApi.ts
5150
- var import_chalk3 = __toESM(require("chalk"));
5151
- var DEFAULT_BASE = "https://pinme.dev/api/v4";
5625
+ var import_chalk4 = __toESM(require("chalk"));
5626
+ var DEFAULT_BASE = "https://pinme.benny1996.win/api/v4";
5152
5627
  var TOKEN_EXPIRED_CODES = [
5153
5628
  401,
5154
5629
  403,
@@ -5186,8 +5661,8 @@ function isTokenExpired(error) {
5186
5661
  );
5187
5662
  }
5188
5663
  function showTokenExpiredHint() {
5189
- console.log(import_chalk3.default.red("\n\u26A0\uFE0F Token has expired or is invalid."));
5190
- console.log(import_chalk3.default.yellow("Please re-run: pinme set-appkey <AppKey>\n"));
5664
+ console.log(import_chalk4.default.red("\n\u26A0\uFE0F Token has expired or is invalid."));
5665
+ console.log(import_chalk4.default.yellow("Please re-run: pinme set-appkey <AppKey>\n"));
5191
5666
  }
5192
5667
  function createClient() {
5193
5668
  const headers = getAuthHeaders();
@@ -5216,7 +5691,7 @@ async function bindAnonymousDevice(anonymousUid) {
5216
5691
  return false;
5217
5692
  }
5218
5693
  console.log(
5219
- import_chalk3.default.yellow(`Failed to trigger anonymous binding: ${(e == null ? void 0 : e.message) || e}`)
5694
+ import_chalk4.default.yellow(`Failed to trigger anonymous binding: ${(e == null ? void 0 : e.message) || e}`)
5220
5695
  );
5221
5696
  return false;
5222
5697
  }
@@ -5329,7 +5804,7 @@ async function isVip(tokenAddress, authToken) {
5329
5804
  throw e;
5330
5805
  }
5331
5806
  }
5332
- var CAR_API_BASE = process.env.CAR_API_BASE || "https://pinme.dev/api/v4";
5807
+ var CAR_API_BASE = process.env.CAR_API_BASE || "https://pinme.benny1996.win/api/v3";
5333
5808
  function createCarClient() {
5334
5809
  let headers = {};
5335
5810
  try {
@@ -5402,7 +5877,7 @@ async function checkCarExportStatus(taskId) {
5402
5877
  }
5403
5878
 
5404
5879
  // bin/upload.ts
5405
- var URL2 = "https://pinme.eth.limo/#/preview/";
5880
+ var URL3 = "https://pinme.eth.limo/#/preview/";
5406
5881
  var secretKey = "pinme-secret-key";
5407
5882
  checkNodeVersion();
5408
5883
  function isDnsDomain(domain) {
@@ -5450,16 +5925,41 @@ function encryptHash(contentHash, key, uid) {
5450
5925
  }
5451
5926
  function checkPathSync(inputPath) {
5452
5927
  try {
5453
- const absolutePath = import_path6.default.resolve(inputPath);
5928
+ const absolutePath = import_path7.default.resolve(inputPath);
5454
5929
  if (import_fs2.default.existsSync(absolutePath)) {
5455
5930
  return absolutePath;
5456
5931
  }
5457
5932
  return null;
5458
5933
  } catch (error) {
5459
- console.error(import_chalk4.default.red(`error checking path: ${error.message}`));
5934
+ console.error(import_chalk5.default.red(`error checking path: ${error.message}`));
5460
5935
  return null;
5461
5936
  }
5462
5937
  }
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
+ function printUploadUrls(contentHash, shortUrl) {
5947
+ var _a;
5948
+ const uid = getUid();
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();
5952
+ if (projectName) {
5953
+ const ensUrl = formatEnsUrl(shortUrl);
5954
+ console.log(import_chalk5.default.cyan(`URL:`));
5955
+ console.log(import_chalk5.default.cyan(ensUrl || previewUrl));
5956
+ console.log(import_chalk5.default.cyan(`Management page:`));
5957
+ console.log(import_chalk5.default.cyan(previewUrl));
5958
+ return;
5959
+ }
5960
+ console.log(import_chalk5.default.cyan(`URL:`));
5961
+ console.log(import_chalk5.default.cyan(previewUrl));
5962
+ }
5463
5963
  function getDomainFromArgs() {
5464
5964
  const args = process.argv.slice(2);
5465
5965
  const dIdx = args.findIndex((a) => a === "--domain" || a === "-d");
@@ -5474,43 +5974,43 @@ function getDnsFromArgs() {
5474
5974
  }
5475
5975
  async function checkVipStatus(authConfig) {
5476
5976
  var _a;
5477
- console.log(import_chalk4.default.blue("Checking VIP status..."));
5977
+ console.log(import_chalk5.default.blue("Checking VIP status..."));
5478
5978
  try {
5479
5979
  const vipResult = await isVip(authConfig.address, authConfig.token);
5480
5980
  if (!((_a = vipResult.data) == null ? void 0 : _a.is_vip)) {
5481
5981
  return false;
5482
5982
  }
5483
- console.log(import_chalk4.default.green("VIP verified."));
5983
+ console.log(import_chalk5.default.green("VIP verified."));
5484
5984
  return true;
5485
5985
  } catch (e) {
5486
5986
  if (e.message === "Token expired") {
5487
5987
  throw e;
5488
5988
  }
5489
- console.log(import_chalk4.default.yellow("Failed to check VIP status, continuing..."));
5989
+ console.log(import_chalk5.default.yellow("Failed to check VIP status, continuing..."));
5490
5990
  return true;
5491
5991
  }
5492
5992
  }
5493
5993
  async function bindDomain(domain, contentHash, isDns, authConfig) {
5494
5994
  const displayDomain = domain.replace(/^https?:\/\//, "").replace(/\/$/, "");
5495
5995
  if (isDns) {
5496
- console.log(import_chalk4.default.blue("Binding DNS domain..."));
5996
+ console.log(import_chalk5.default.blue("Binding DNS domain..."));
5497
5997
  const dnsResult = await bindDnsDomainV4(displayDomain, contentHash, authConfig.address, authConfig.token);
5498
5998
  if (dnsResult.code !== 200) {
5499
- console.log(import_chalk4.default.red(`DNS binding failed: ${dnsResult.msg}`));
5999
+ console.log(import_chalk5.default.red(`DNS binding failed: ${dnsResult.msg}`));
5500
6000
  return false;
5501
6001
  }
5502
- console.log(import_chalk4.default.green(`DNS bind success: ${displayDomain}`));
5503
- console.log(import_chalk4.default.white(`Visit: https://${displayDomain}`));
5504
- console.log(import_chalk4.default.cyan("\n\u{1F4DA} DNS Setup Guide: https://pinme.eth.limo/#/docs?id=custom-domain"));
6002
+ console.log(import_chalk5.default.green(`DNS bind success: ${displayDomain}`));
6003
+ console.log(import_chalk5.default.white(`Visit: https://${displayDomain}`));
6004
+ console.log(import_chalk5.default.cyan("\n\u{1F4DA} DNS Setup Guide: https://pinme.eth.limo/#/docs?id=custom-domain"));
5505
6005
  } else {
5506
- console.log(import_chalk4.default.blue("Binding Pinme subdomain..."));
6006
+ console.log(import_chalk5.default.blue("Binding Pinme subdomain..."));
5507
6007
  const ok = await bindPinmeDomain(displayDomain, contentHash);
5508
6008
  if (!ok) {
5509
- console.log(import_chalk4.default.red("Binding failed. Please try again later."));
6009
+ console.log(import_chalk5.default.red("Binding failed. Please try again later."));
5510
6010
  return false;
5511
6011
  }
5512
- console.log(import_chalk4.default.green(`Bind success: ${displayDomain}`));
5513
- console.log(import_chalk4.default.white(`Visit: https://${displayDomain}.pinit.eth.limo`));
6012
+ console.log(import_chalk5.default.green(`Bind success: ${displayDomain}`));
6013
+ console.log(import_chalk5.default.white(`Visit: https://${displayDomain}.pinit.eth.limo`));
5514
6014
  }
5515
6015
  return true;
5516
6016
  }
@@ -5530,9 +6030,9 @@ var upload_default = async (options) => {
5530
6030
  const needsAuth = !!domainArg || dnsArg;
5531
6031
  let authConfig = null;
5532
6032
  if (needsAuth) {
5533
- authConfig = getAuthConfig();
6033
+ authConfig = getAuthConfig2();
5534
6034
  if (!authConfig) {
5535
- console.log(import_chalk4.default.red("Please login first. Run: pinme set-appkey <AppKey>"));
6035
+ console.log(import_chalk5.default.red("Please login first. Run: pinme set-appkey <AppKey>"));
5536
6036
  return;
5537
6037
  }
5538
6038
  }
@@ -5540,7 +6040,7 @@ var upload_default = async (options) => {
5540
6040
  if (argPath && !argPath.startsWith("-")) {
5541
6041
  const absolutePath = checkPathSync(argPath);
5542
6042
  if (!absolutePath) {
5543
- console.log(import_chalk4.default.red(`path ${argPath} does not exist`));
6043
+ console.log(import_chalk5.default.red(`path ${argPath} does not exist`));
5544
6044
  return;
5545
6045
  }
5546
6046
  const isDns = dnsArg || (domainArg ? isDnsDomain(domainArg) : false);
@@ -5548,7 +6048,7 @@ var upload_default = async (options) => {
5548
6048
  if (isDns && domainArg) {
5549
6049
  const validation = validateDnsDomain(domainArg);
5550
6050
  if (!validation.valid) {
5551
- console.log(import_chalk4.default.red(validation.message));
6051
+ console.log(import_chalk5.default.red(validation.message));
5552
6052
  return;
5553
6053
  }
5554
6054
  }
@@ -5556,7 +6056,7 @@ var upload_default = async (options) => {
5556
6056
  try {
5557
6057
  const isVipUser = await checkVipStatus(authConfig);
5558
6058
  if (!isVipUser) {
5559
- console.log(import_chalk4.default.red("Domain binding requires VIP. Please upgrade to VIP first."));
6059
+ console.log(import_chalk5.default.red("Domain binding requires VIP. Please upgrade to VIP first."));
5560
6060
  return;
5561
6061
  }
5562
6062
  } catch (e) {
@@ -5571,13 +6071,13 @@ var upload_default = async (options) => {
5571
6071
  const check = await checkDomainAvailable(displayDomain);
5572
6072
  if (!check.is_valid) {
5573
6073
  console.log(
5574
- import_chalk4.default.red(
6074
+ import_chalk5.default.red(
5575
6075
  `Domain not available: ${check.error || "unknown reason"}`
5576
6076
  )
5577
6077
  );
5578
6078
  return;
5579
6079
  }
5580
- console.log(import_chalk4.default.green(`Domain available: ${displayDomain}`));
6080
+ console.log(import_chalk5.default.green(`Domain available: ${displayDomain}`));
5581
6081
  } catch (e) {
5582
6082
  if (e.message === "Token expired") {
5583
6083
  return;
@@ -5585,39 +6085,40 @@ var upload_default = async (options) => {
5585
6085
  throw e;
5586
6086
  }
5587
6087
  }
5588
- console.log(import_chalk4.default.blue(`uploading ${absolutePath} to ipfs...`));
6088
+ console.log(import_chalk5.default.blue(`uploading ${absolutePath} to ipfs...`));
6089
+ let result;
5589
6090
  try {
5590
- const result = await uploadToIpfsSplit_default(absolutePath);
5591
- if (result) {
5592
- const uid = getUid();
5593
- const encryptedCID = encryptHash(result.contentHash, secretKey, uid);
5594
- console.log(
5595
- import_chalk4.default.cyan(
5596
- import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
5597
- )
5598
- );
5599
- console.log(import_chalk4.default.cyan(`URL:`));
5600
- console.log(import_chalk4.default.cyan(`${URL2}${encryptedCID}`));
5601
- if (domainArg) {
5602
- console.log(
5603
- import_chalk4.default.blue(
5604
- `Binding domain: ${displayDomain} with CID: ${result.contentHash}`
5605
- )
5606
- );
5607
- try {
5608
- await bindDomain(domainArg, result.contentHash, isDns, authConfig);
5609
- } catch (e) {
5610
- if (e.message === "Token expired") {
5611
- return;
5612
- }
5613
- throw e;
5614
- }
6091
+ result = await uploadToIpfsSplit_default(absolutePath);
6092
+ } catch (error) {
6093
+ console.error(import_chalk5.default.red(`Upload error: ${error.message}`));
6094
+ process.exit(1);
6095
+ }
6096
+ if (!result) {
6097
+ console.error(import_chalk5.default.red("Upload failed: no result returned"));
6098
+ process.exit(1);
6099
+ }
6100
+ console.log(
6101
+ import_chalk5.default.cyan(
6102
+ import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
6103
+ )
6104
+ );
6105
+ printUploadUrls(result.contentHash, result.shortUrl);
6106
+ if (domainArg) {
6107
+ console.log(
6108
+ import_chalk5.default.blue(
6109
+ `Binding domain: ${displayDomain} with CID: ${result.contentHash}`
6110
+ )
6111
+ );
6112
+ try {
6113
+ await bindDomain(domainArg, result.contentHash, isDns, authConfig);
6114
+ } catch (e) {
6115
+ if (e.message === "Token expired") {
6116
+ process.exit(1);
5615
6117
  }
5616
- console.log(import_chalk4.default.green("\n\u{1F389} upload successful, program exit"));
6118
+ throw e;
5617
6119
  }
5618
- } catch (error) {
5619
- console.error(import_chalk4.default.red(`Error: ${error.message}`));
5620
6120
  }
6121
+ console.log(import_chalk5.default.green("\n\u{1F389} upload successful, program exit"));
5621
6122
  process.exit(0);
5622
6123
  }
5623
6124
  const answer = await import_inquirer.default.prompt([
@@ -5630,7 +6131,7 @@ var upload_default = async (options) => {
5630
6131
  if (answer.path) {
5631
6132
  const absolutePath = checkPathSync(answer.path);
5632
6133
  if (!absolutePath) {
5633
- console.log(import_chalk4.default.red(`path ${answer.path} does not exist`));
6134
+ console.log(import_chalk5.default.red(`path ${answer.path} does not exist`));
5634
6135
  return;
5635
6136
  }
5636
6137
  const isDns = dnsArg || (domainArg ? isDnsDomain(domainArg) : false);
@@ -5638,7 +6139,7 @@ var upload_default = async (options) => {
5638
6139
  if (isDns && domainArg) {
5639
6140
  const validation = validateDnsDomain(domainArg);
5640
6141
  if (!validation.valid) {
5641
- console.log(import_chalk4.default.red(validation.message));
6142
+ console.log(import_chalk5.default.red(validation.message));
5642
6143
  return;
5643
6144
  }
5644
6145
  }
@@ -5646,7 +6147,7 @@ var upload_default = async (options) => {
5646
6147
  try {
5647
6148
  const isVipUser = await checkVipStatus(authConfig);
5648
6149
  if (!isVipUser) {
5649
- console.log(import_chalk4.default.red("Domain binding requires VIP. Please upgrade to VIP first."));
6150
+ console.log(import_chalk5.default.red("Domain binding requires VIP. Please upgrade to VIP first."));
5650
6151
  return;
5651
6152
  }
5652
6153
  } catch (e) {
@@ -5661,13 +6162,13 @@ var upload_default = async (options) => {
5661
6162
  const check = await checkDomainAvailable(displayDomain);
5662
6163
  if (!check.is_valid) {
5663
6164
  console.log(
5664
- import_chalk4.default.red(
6165
+ import_chalk5.default.red(
5665
6166
  `Domain not available: ${check.error || "unknown reason"}`
5666
6167
  )
5667
6168
  );
5668
6169
  return;
5669
6170
  }
5670
- console.log(import_chalk4.default.green(`Domain available: ${displayDomain}`));
6171
+ console.log(import_chalk5.default.green(`Domain available: ${displayDomain}`));
5671
6172
  } catch (e) {
5672
6173
  if (e.message === "Token expired") {
5673
6174
  return;
@@ -5675,55 +6176,56 @@ var upload_default = async (options) => {
5675
6176
  throw e;
5676
6177
  }
5677
6178
  }
5678
- console.log(import_chalk4.default.blue(`uploading ${absolutePath} to ipfs...`));
6179
+ console.log(import_chalk5.default.blue(`uploading ${absolutePath} to ipfs...`));
6180
+ let result;
5679
6181
  try {
5680
- const result = await uploadToIpfsSplit_default(absolutePath);
5681
- if (result) {
5682
- const uid = getUid();
5683
- const encryptedCID = encryptHash(result.contentHash, secretKey, uid);
5684
- console.log(
5685
- import_chalk4.default.cyan(
5686
- import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
5687
- )
5688
- );
5689
- console.log(import_chalk4.default.cyan(`URL:`));
5690
- console.log(import_chalk4.default.cyan(`${URL2}${encryptedCID}`));
5691
- if (domainArg) {
5692
- console.log(
5693
- import_chalk4.default.blue(
5694
- `Binding domain: ${displayDomain} with CID: ${result.contentHash}`
5695
- )
5696
- );
5697
- try {
5698
- await bindDomain(domainArg, result.contentHash, isDns, authConfig);
5699
- } catch (e) {
5700
- if (e.message === "Token expired") {
5701
- return;
5702
- }
5703
- throw e;
5704
- }
6182
+ result = await uploadToIpfsSplit_default(absolutePath);
6183
+ } catch (error) {
6184
+ console.error(import_chalk5.default.red(`Upload error: ${error.message}`));
6185
+ process.exit(1);
6186
+ }
6187
+ if (!result) {
6188
+ console.error(import_chalk5.default.red("Upload failed: no result returned"));
6189
+ process.exit(1);
6190
+ }
6191
+ console.log(
6192
+ import_chalk5.default.cyan(
6193
+ import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
6194
+ )
6195
+ );
6196
+ printUploadUrls(result.contentHash, result.shortUrl);
6197
+ if (domainArg) {
6198
+ console.log(
6199
+ import_chalk5.default.blue(
6200
+ `Binding domain: ${displayDomain} with CID: ${result.contentHash}`
6201
+ )
6202
+ );
6203
+ try {
6204
+ await bindDomain(domainArg, result.contentHash, isDns, authConfig);
6205
+ } catch (e) {
6206
+ if (e.message === "Token expired") {
6207
+ process.exit(1);
5705
6208
  }
5706
- console.log(import_chalk4.default.green("\n\u{1F389} upload successful, program exit"));
6209
+ throw e;
5707
6210
  }
5708
- } catch (error) {
5709
- console.error(import_chalk4.default.red(`Error: ${error.message}`));
5710
6211
  }
6212
+ console.log(import_chalk5.default.green("\n\u{1F389} upload successful, program exit"));
5711
6213
  process.exit(0);
5712
6214
  }
5713
6215
  } catch (error) {
5714
- console.error(import_chalk4.default.red(`error executing: ${error.message}`));
6216
+ console.error(import_chalk5.default.red(`error executing: ${error.message}`));
5715
6217
  console.error(error.stack);
5716
6218
  }
5717
6219
  };
5718
6220
 
5719
6221
  // bin/importCar.ts
5720
- var import_path7 = __toESM(require("path"));
5721
- var import_chalk5 = __toESM(require("chalk"));
6222
+ var import_path8 = __toESM(require("path"));
6223
+ var import_chalk6 = __toESM(require("chalk"));
5722
6224
  var import_inquirer2 = __toESM(require("inquirer"));
5723
6225
  var import_figlet2 = __toESM(require("figlet"));
5724
6226
  var import_fs3 = __toESM(require("fs"));
5725
6227
  var import_crypto_js2 = __toESM(require("crypto-js"));
5726
- var URL3 = "https://pinme.eth.limo/#/preview/";
6228
+ var URL4 = "https://pinme.eth.limo/#/preview/";
5727
6229
  var secretKey2 = "pinme-secret-key";
5728
6230
  checkNodeVersion();
5729
6231
  function encryptHash2(contentHash, key, uid) {
@@ -5742,13 +6244,13 @@ function encryptHash2(contentHash, key, uid) {
5742
6244
  }
5743
6245
  function checkPathSync2(inputPath) {
5744
6246
  try {
5745
- const absolutePath = import_path7.default.resolve(inputPath);
6247
+ const absolutePath = import_path8.default.resolve(inputPath);
5746
6248
  if (import_fs3.default.existsSync(absolutePath)) {
5747
6249
  return absolutePath;
5748
6250
  }
5749
6251
  return null;
5750
6252
  } catch (error) {
5751
- console.error(import_chalk5.default.red(`error checking path: ${error.message}`));
6253
+ console.error(import_chalk6.default.red(`error checking path: ${error.message}`));
5752
6254
  return null;
5753
6255
  }
5754
6256
  }
@@ -5761,7 +6263,7 @@ function getDomainFromArgs2() {
5761
6263
  return null;
5762
6264
  }
5763
6265
  function getUid2() {
5764
- const auth = getAuthConfig();
6266
+ const auth = getAuthConfig2();
5765
6267
  if (auth == null ? void 0 : auth.address) {
5766
6268
  return auth.address;
5767
6269
  }
@@ -5783,44 +6285,44 @@ var importCar_default = async (options) => {
5783
6285
  if (argPath && !argPath.startsWith("-")) {
5784
6286
  const absolutePath = checkPathSync2(argPath);
5785
6287
  if (!absolutePath) {
5786
- console.log(import_chalk5.default.red(`path ${argPath} does not exist`));
6288
+ console.log(import_chalk6.default.red(`path ${argPath} does not exist`));
5787
6289
  return;
5788
6290
  }
5789
6291
  if (domainArg) {
5790
6292
  const check = await checkDomainAvailable(domainArg);
5791
6293
  if (!check.is_valid) {
5792
- console.log(import_chalk5.default.red(`Domain not available: ${check.error || "unknown reason"}`));
6294
+ console.log(import_chalk6.default.red(`Domain not available: ${check.error || "unknown reason"}`));
5793
6295
  return;
5794
6296
  }
5795
- console.log(import_chalk5.default.green(`Domain available: ${domainArg}`));
6297
+ console.log(import_chalk6.default.green(`Domain available: ${domainArg}`));
5796
6298
  }
5797
- console.log(import_chalk5.default.blue(`importing ${absolutePath} to ipfs as CAR...`));
6299
+ console.log(import_chalk6.default.blue(`importing ${absolutePath} to ipfs as CAR...`));
5798
6300
  try {
5799
6301
  const result = await uploadToIpfsSplit_default(absolutePath, true);
5800
6302
  if (result) {
5801
6303
  const uid = getUid2();
5802
6304
  const encryptedCID = encryptHash2(result.contentHash, secretKey2, uid);
5803
6305
  console.log(
5804
- import_chalk5.default.cyan(
6306
+ import_chalk6.default.cyan(
5805
6307
  import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
5806
6308
  )
5807
6309
  );
5808
- console.log(import_chalk5.default.cyan(`URL:`));
5809
- console.log(import_chalk5.default.cyan(`${URL3}${encryptedCID}`));
6310
+ console.log(import_chalk6.default.cyan(`URL:`));
6311
+ console.log(import_chalk6.default.cyan(`${URL4}${encryptedCID}`));
5810
6312
  if (domainArg) {
5811
- console.log(import_chalk5.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
6313
+ console.log(import_chalk6.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
5812
6314
  const ok = await bindPinmeDomain(domainArg, result.contentHash);
5813
6315
  if (ok) {
5814
- console.log(import_chalk5.default.green(`Bind success: ${domainArg}`));
5815
- console.log(import_chalk5.default.white(`Visit (Pinme subdomain example): https://${domainArg}.pinit.eth.limo`));
6316
+ console.log(import_chalk6.default.green(`Bind success: ${domainArg}`));
6317
+ console.log(import_chalk6.default.white(`Visit (Pinme subdomain example): https://${domainArg}.pinit.eth.limo`));
5816
6318
  } else {
5817
- console.log(import_chalk5.default.red("Binding failed. Please try again later."));
6319
+ console.log(import_chalk6.default.red("Binding failed. Please try again later."));
5818
6320
  }
5819
6321
  }
5820
- console.log(import_chalk5.default.green("\n\u{1F389} import successful, program exit"));
6322
+ console.log(import_chalk6.default.green("\n\u{1F389} import successful, program exit"));
5821
6323
  }
5822
6324
  } catch (error) {
5823
- console.error(import_chalk5.default.red(`Error: ${error.message}`));
6325
+ console.error(import_chalk6.default.red(`Error: ${error.message}`));
5824
6326
  }
5825
6327
  process.exit(0);
5826
6328
  }
@@ -5834,56 +6336,56 @@ var importCar_default = async (options) => {
5834
6336
  if (answer.path) {
5835
6337
  const absolutePath = checkPathSync2(answer.path);
5836
6338
  if (!absolutePath) {
5837
- console.log(import_chalk5.default.red(`path ${answer.path} does not exist`));
6339
+ console.log(import_chalk6.default.red(`path ${answer.path} does not exist`));
5838
6340
  return;
5839
6341
  }
5840
6342
  if (domainArg) {
5841
6343
  const check = await checkDomainAvailable(domainArg);
5842
6344
  if (!check.is_valid) {
5843
- console.log(import_chalk5.default.red(`Domain not available: ${check.error || "unknown reason"}`));
6345
+ console.log(import_chalk6.default.red(`Domain not available: ${check.error || "unknown reason"}`));
5844
6346
  return;
5845
6347
  }
5846
- console.log(import_chalk5.default.green(`Domain available: ${domainArg}`));
6348
+ console.log(import_chalk6.default.green(`Domain available: ${domainArg}`));
5847
6349
  }
5848
- console.log(import_chalk5.default.blue(`importing ${absolutePath} to ipfs as CAR...`));
6350
+ console.log(import_chalk6.default.blue(`importing ${absolutePath} to ipfs as CAR...`));
5849
6351
  try {
5850
6352
  const result = await uploadToIpfsSplit_default(absolutePath, true);
5851
6353
  if (result) {
5852
6354
  const uid = getUid2();
5853
6355
  const encryptedCID = encryptHash2(result.contentHash, secretKey2, uid);
5854
6356
  console.log(
5855
- import_chalk5.default.cyan(
6357
+ import_chalk6.default.cyan(
5856
6358
  import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
5857
6359
  )
5858
6360
  );
5859
- console.log(import_chalk5.default.cyan(`URL:`));
5860
- console.log(import_chalk5.default.cyan(`${URL3}${encryptedCID}`));
6361
+ console.log(import_chalk6.default.cyan(`URL:`));
6362
+ console.log(import_chalk6.default.cyan(`${URL4}${encryptedCID}`));
5861
6363
  if (domainArg) {
5862
- console.log(import_chalk5.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
6364
+ console.log(import_chalk6.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
5863
6365
  const ok = await bindPinmeDomain(domainArg, result.contentHash);
5864
6366
  if (ok) {
5865
- console.log(import_chalk5.default.green(`Bind success: ${domainArg}`));
5866
- console.log(import_chalk5.default.white(`Visit (Pinme subdomain example): https://${domainArg}.pinit.eth.limo`));
6367
+ console.log(import_chalk6.default.green(`Bind success: ${domainArg}`));
6368
+ console.log(import_chalk6.default.white(`Visit (Pinme subdomain example): https://${domainArg}.pinit.eth.limo`));
5867
6369
  } else {
5868
- console.log(import_chalk5.default.red("Binding failed. Please try again later."));
6370
+ console.log(import_chalk6.default.red("Binding failed. Please try again later."));
5869
6371
  }
5870
6372
  }
5871
- console.log(import_chalk5.default.green("\n\u{1F389} import successful, program exit"));
6373
+ console.log(import_chalk6.default.green("\n\u{1F389} import successful, program exit"));
5872
6374
  }
5873
6375
  } catch (error) {
5874
- console.error(import_chalk5.default.red(`Error: ${error.message}`));
6376
+ console.error(import_chalk6.default.red(`Error: ${error.message}`));
5875
6377
  }
5876
6378
  process.exit(0);
5877
6379
  }
5878
6380
  } catch (error) {
5879
- console.error(import_chalk5.default.red(`error executing: ${error.message}`));
6381
+ console.error(import_chalk6.default.red(`error executing: ${error.message}`));
5880
6382
  console.error(error.stack);
5881
6383
  }
5882
6384
  };
5883
6385
 
5884
6386
  // bin/exportCar.ts
5885
- var import_path8 = __toESM(require("path"));
5886
- var import_chalk6 = __toESM(require("chalk"));
6387
+ var import_path9 = __toESM(require("path"));
6388
+ var import_chalk7 = __toESM(require("chalk"));
5887
6389
  var import_inquirer3 = __toESM(require("inquirer"));
5888
6390
  var import_figlet3 = __toESM(require("figlet"));
5889
6391
  var import_fs4 = __toESM(require("fs"));
@@ -5908,7 +6410,7 @@ async function pollExportStatus(taskId, cid, spinner, startTime) {
5908
6410
  spinner.text = `Exporting CAR file... (${minutes}m ${seconds}s)`;
5909
6411
  }
5910
6412
  } catch (error) {
5911
- console.log(import_chalk6.default.yellow(`Polling error: ${error.message}`));
6413
+ console.log(import_chalk7.default.yellow(`Polling error: ${error.message}`));
5912
6414
  }
5913
6415
  await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL2));
5914
6416
  }
@@ -5948,7 +6450,7 @@ async function downloadCarFile(downloadUrl, outputPath) {
5948
6450
  });
5949
6451
  });
5950
6452
  } catch (error) {
5951
- console.error(import_chalk6.default.red(`Download error: ${error.message}`));
6453
+ console.error(import_chalk7.default.red(`Download error: ${error.message}`));
5952
6454
  return false;
5953
6455
  }
5954
6456
  }
@@ -6006,7 +6508,7 @@ var exportCar_default = async () => {
6006
6508
  cid = answer.cid.trim();
6007
6509
  }
6008
6510
  if (!cid || !isValidCID(cid)) {
6009
- console.log(import_chalk6.default.red("Invalid CID format. CID should start with Qm, bafy, bafk, or bafz"));
6511
+ console.log(import_chalk7.default.red("Invalid CID format. CID should start with Qm, bafy, bafk, or bafz"));
6010
6512
  return;
6011
6513
  }
6012
6514
  let outputDir = getOutputPathFromArgs();
@@ -6022,14 +6524,14 @@ var exportCar_default = async () => {
6022
6524
  ]);
6023
6525
  outputDir = answer.output.trim() || currentDir;
6024
6526
  }
6025
- outputDir = import_path8.default.resolve(outputDir);
6527
+ outputDir = import_path9.default.resolve(outputDir);
6026
6528
  if (!import_fs4.default.existsSync(outputDir)) {
6027
6529
  import_fs4.default.mkdirSync(outputDir, { recursive: true });
6028
6530
  } else if (!import_fs4.default.statSync(outputDir).isDirectory()) {
6029
- console.log(import_chalk6.default.red(`Error: ${outputDir} exists but is not a directory.`));
6531
+ console.log(import_chalk7.default.red(`Error: ${outputDir} exists but is not a directory.`));
6030
6532
  return;
6031
6533
  }
6032
- const finalOutputPath = import_path8.default.join(outputDir, `${cid}.car`);
6534
+ const finalOutputPath = import_path9.default.join(outputDir, `${cid}.car`);
6033
6535
  if (import_fs4.default.existsSync(finalOutputPath)) {
6034
6536
  const answer = await import_inquirer3.default.prompt([
6035
6537
  {
@@ -6040,7 +6542,7 @@ var exportCar_default = async () => {
6040
6542
  }
6041
6543
  ]);
6042
6544
  if (!answer.overwrite) {
6043
- console.log(import_chalk6.default.blue("Export cancelled."));
6545
+ console.log(import_chalk7.default.blue("Export cancelled."));
6044
6546
  return;
6045
6547
  }
6046
6548
  }
@@ -6058,7 +6560,7 @@ var exportCar_default = async () => {
6058
6560
  startTime
6059
6561
  );
6060
6562
  if (!downloadUrl) {
6061
- console.log(import_chalk6.default.red("Export failed or timed out."));
6563
+ console.log(import_chalk7.default.red("Export failed or timed out."));
6062
6564
  return;
6063
6565
  }
6064
6566
  const success = await downloadCarFile(downloadUrl, finalOutputPath);
@@ -6066,40 +6568,40 @@ var exportCar_default = async () => {
6066
6568
  const fileSize = import_fs4.default.statSync(finalOutputPath).size;
6067
6569
  const fileSizeMB = (fileSize / (1024 * 1024)).toFixed(2);
6068
6570
  console.log(
6069
- import_chalk6.default.cyan(
6571
+ import_chalk7.default.cyan(
6070
6572
  import_figlet3.default.textSync("Successful", { horizontalLayout: "full" })
6071
6573
  )
6072
6574
  );
6073
- console.log(import_chalk6.default.green(`
6575
+ console.log(import_chalk7.default.green(`
6074
6576
  \u{1F389} Export successful!`));
6075
- console.log(import_chalk6.default.cyan(`File: ${finalOutputPath}`));
6076
- console.log(import_chalk6.default.cyan(`Size: ${fileSizeMB} MB`));
6077
- console.log(import_chalk6.default.cyan(`CID: ${cid}`));
6577
+ console.log(import_chalk7.default.cyan(`File: ${finalOutputPath}`));
6578
+ console.log(import_chalk7.default.cyan(`Size: ${fileSizeMB} MB`));
6579
+ console.log(import_chalk7.default.cyan(`CID: ${cid}`));
6078
6580
  } else {
6079
- console.log(import_chalk6.default.red("Download failed."));
6581
+ console.log(import_chalk7.default.red("Download failed."));
6080
6582
  }
6081
6583
  } catch (error) {
6082
6584
  spinner.fail(`Error: ${error.message}`);
6083
- console.error(import_chalk6.default.red(`Export error: ${error.message}`));
6585
+ console.error(import_chalk7.default.red(`Export error: ${error.message}`));
6084
6586
  }
6085
6587
  } catch (error) {
6086
- console.error(import_chalk6.default.red(`error executing: ${error.message}`));
6588
+ console.error(import_chalk7.default.red(`error executing: ${error.message}`));
6087
6589
  console.error(error.stack);
6088
6590
  }
6089
6591
  };
6090
6592
 
6091
6593
  // bin/remove.ts
6092
- var import_chalk8 = __toESM(require("chalk"));
6594
+ var import_chalk9 = __toESM(require("chalk"));
6093
6595
  var import_inquirer4 = __toESM(require("inquirer"));
6094
6596
  var import_figlet4 = __toESM(require("figlet"));
6095
6597
 
6096
6598
  // bin/utils/removeFromIpfs.ts
6097
- var import_chalk7 = __toESM(require("chalk"));
6098
- var ipfsApiUrl = "https://pinme.dev/api/v3";
6599
+ var import_chalk8 = __toESM(require("chalk"));
6600
+ var ipfsApiUrl = "https://pinme.benny1996.win/api/v3";
6099
6601
  async function removeFromIpfs(value, type = "hash") {
6100
6602
  try {
6101
6603
  const uid = getUid();
6102
- console.log(import_chalk7.default.blue(`Removing content from IPFS: ${value}...`));
6604
+ console.log(import_chalk8.default.blue(`Removing content from IPFS: ${value}...`));
6103
6605
  const queryParams = new URLSearchParams({
6104
6606
  uid
6105
6607
  });
@@ -6117,49 +6619,49 @@ async function removeFromIpfs(value, type = "hash") {
6117
6619
  );
6118
6620
  const { code, msg, data } = response.data;
6119
6621
  if (code === 200) {
6120
- console.log(import_chalk7.default.green("\u2713 Removal successful!"));
6622
+ console.log(import_chalk8.default.green("\u2713 Removal successful!"));
6121
6623
  console.log(
6122
- import_chalk7.default.cyan(
6624
+ import_chalk8.default.cyan(
6123
6625
  `Content ${type}: ${value} has been removed from IPFS network`
6124
6626
  )
6125
6627
  );
6126
6628
  return true;
6127
6629
  } else {
6128
- console.log(import_chalk7.default.red("\u2717 Removal failed"));
6129
- console.log(import_chalk7.default.red(`Error: ${msg || "Unknown error occurred"}`));
6630
+ console.log(import_chalk8.default.red("\u2717 Removal failed"));
6631
+ console.log(import_chalk8.default.red(`Error: ${msg || "Unknown error occurred"}`));
6130
6632
  return false;
6131
6633
  }
6132
6634
  } catch (error) {
6133
- console.log(import_chalk7.default.red("\u2717 Removal failed", error));
6635
+ console.log(import_chalk8.default.red("\u2717 Removal failed", error));
6134
6636
  if (error.response) {
6135
6637
  const { status, data } = error.response;
6136
6638
  console.log(
6137
- import_chalk7.default.red(`HTTP Error ${status}: ${(data == null ? void 0 : data.msg) || "Server error"}`)
6639
+ import_chalk8.default.red(`HTTP Error ${status}: ${(data == null ? void 0 : data.msg) || "Server error"}`)
6138
6640
  );
6139
6641
  if (status === 404) {
6140
6642
  console.log(
6141
- import_chalk7.default.yellow("Content not found on the network or already removed")
6643
+ import_chalk8.default.yellow("Content not found on the network or already removed")
6142
6644
  );
6143
6645
  } else if (status === 403) {
6144
6646
  console.log(
6145
- import_chalk7.default.yellow(
6647
+ import_chalk8.default.yellow(
6146
6648
  "Permission denied - you may not have access to remove this content"
6147
6649
  )
6148
6650
  );
6149
6651
  } else if (status === 500) {
6150
6652
  console.log(
6151
- import_chalk7.default.yellow("Server internal error - please try again later")
6653
+ import_chalk8.default.yellow("Server internal error - please try again later")
6152
6654
  );
6153
6655
  }
6154
6656
  } else if (error.request) {
6155
6657
  console.log(
6156
- import_chalk7.default.red("Network error: Unable to connect to IPFS service")
6658
+ import_chalk8.default.red("Network error: Unable to connect to IPFS service")
6157
6659
  );
6158
6660
  console.log(
6159
- import_chalk7.default.yellow("Please check your internet connection and try again")
6661
+ import_chalk8.default.yellow("Please check your internet connection and try again")
6160
6662
  );
6161
6663
  } else {
6162
- console.log(import_chalk7.default.red(`Error: ${error.message}`));
6664
+ console.log(import_chalk8.default.red(`Error: ${error.message}`));
6163
6665
  }
6164
6666
  return false;
6165
6667
  }
@@ -6219,29 +6721,29 @@ var remove_default = async (options) => {
6219
6721
  if (argHash && !argHash.startsWith("-")) {
6220
6722
  const parsedInput = parseInput(argHash);
6221
6723
  if (!parsedInput) {
6222
- console.log(import_chalk8.default.red(`Invalid input format: ${argHash}`));
6223
- console.log(import_chalk8.default.yellow("Supported formats:"));
6224
- console.log(import_chalk8.default.yellow(" - IPFS hash: bafybeig..."));
6225
- console.log(import_chalk8.default.yellow(" - Subname: 3abt6ztu"));
6226
- console.log(import_chalk8.default.yellow(" - Subname URL: https://3abt6ztu.pinit.eth.limo"));
6724
+ console.log(import_chalk9.default.red(`Invalid input format: ${argHash}`));
6725
+ console.log(import_chalk9.default.yellow("Supported formats:"));
6726
+ console.log(import_chalk9.default.yellow(" - IPFS hash: bafybeig..."));
6727
+ console.log(import_chalk9.default.yellow(" - Subname: 3abt6ztu"));
6728
+ console.log(import_chalk9.default.yellow(" - Subname URL: https://3abt6ztu.pinit.eth.limo"));
6227
6729
  return;
6228
6730
  }
6229
6731
  try {
6230
6732
  const success = await removeFromIpfs(parsedInput.value, parsedInput.type);
6231
6733
  if (success) {
6232
6734
  console.log(
6233
- import_chalk8.default.cyan(
6735
+ import_chalk9.default.cyan(
6234
6736
  import_figlet4.default.textSync("Successful", { horizontalLayout: "full" })
6235
6737
  )
6236
6738
  );
6237
6739
  }
6238
6740
  } catch (error) {
6239
- console.error(import_chalk8.default.red(`Error: ${error.message}`));
6741
+ console.error(import_chalk9.default.red(`Error: ${error.message}`));
6240
6742
  }
6241
6743
  return;
6242
6744
  }
6243
- console.log(import_chalk8.default.yellow("\u26A0\uFE0F Warning: This action will permanently remove the content from IPFS network"));
6244
- console.log(import_chalk8.default.yellow("\u26A0\uFE0F Make sure you have the correct IPFS hash"));
6745
+ console.log(import_chalk9.default.yellow("\u26A0\uFE0F Warning: This action will permanently remove the content from IPFS network"));
6746
+ console.log(import_chalk9.default.yellow("\u26A0\uFE0F Make sure you have the correct IPFS hash"));
6245
6747
  console.log("");
6246
6748
  const confirmAnswer = await import_inquirer4.default.prompt([
6247
6749
  {
@@ -6252,7 +6754,7 @@ var remove_default = async (options) => {
6252
6754
  }
6253
6755
  ]);
6254
6756
  if (!confirmAnswer.confirm) {
6255
- console.log(import_chalk8.default.yellow("Operation cancelled"));
6757
+ console.log(import_chalk9.default.yellow("Operation cancelled"));
6256
6758
  return;
6257
6759
  }
6258
6760
  const answer = await import_inquirer4.default.prompt([
@@ -6275,7 +6777,7 @@ var remove_default = async (options) => {
6275
6777
  if (answer.input) {
6276
6778
  const parsedInput = parseInput(answer.input.trim());
6277
6779
  if (!parsedInput) {
6278
- console.log(import_chalk8.default.red("Invalid input format"));
6780
+ console.log(import_chalk9.default.red("Invalid input format"));
6279
6781
  return;
6280
6782
  }
6281
6783
  const finalConfirm = await import_inquirer4.default.prompt([
@@ -6287,30 +6789,30 @@ var remove_default = async (options) => {
6287
6789
  }
6288
6790
  ]);
6289
6791
  if (!finalConfirm.confirm) {
6290
- console.log(import_chalk8.default.yellow("Operation cancelled"));
6792
+ console.log(import_chalk9.default.yellow("Operation cancelled"));
6291
6793
  return;
6292
6794
  }
6293
6795
  try {
6294
6796
  const success = await removeFromIpfs(parsedInput.value, parsedInput.type);
6295
6797
  if (success) {
6296
6798
  console.log(
6297
- import_chalk8.default.cyan(
6799
+ import_chalk9.default.cyan(
6298
6800
  import_figlet4.default.textSync("Successful", { horizontalLayout: "full" })
6299
6801
  )
6300
6802
  );
6301
6803
  }
6302
6804
  } catch (error) {
6303
- console.error(import_chalk8.default.red(`Error: ${error.message}`));
6805
+ console.error(import_chalk9.default.red(`Error: ${error.message}`));
6304
6806
  }
6305
6807
  }
6306
6808
  } catch (error) {
6307
- console.error(import_chalk8.default.red(`Error executing remove command: ${error.message}`));
6809
+ console.error(import_chalk9.default.red(`Error executing remove command: ${error.message}`));
6308
6810
  console.error(error.stack);
6309
6811
  }
6310
6812
  };
6311
6813
 
6312
6814
  // bin/set-appkey.ts
6313
- var import_chalk9 = __toESM(require("chalk"));
6815
+ var import_chalk10 = __toESM(require("chalk"));
6314
6816
  var import_inquirer5 = __toESM(require("inquirer"));
6315
6817
  async function setAppKeyCmd() {
6316
6818
  try {
@@ -6327,31 +6829,31 @@ async function setAppKeyCmd() {
6327
6829
  appKey = ans.appKey;
6328
6830
  }
6329
6831
  if (!appKey) {
6330
- console.log(import_chalk9.default.red("AppKey not provided."));
6832
+ console.log(import_chalk10.default.red("AppKey not provided."));
6331
6833
  return;
6332
6834
  }
6333
6835
  const saved = setAuthToken(appKey);
6334
- console.log(import_chalk9.default.green(`Auth set for address: ${saved.address}`));
6836
+ console.log(import_chalk10.default.green(`Auth set for address: ${saved.address}`));
6335
6837
  const deviceId = getDeviceId();
6336
6838
  const ok = await bindAnonymousDevice(deviceId);
6337
6839
  if (ok) {
6338
- console.log(import_chalk9.default.green("Anonymous history merged to current account."));
6840
+ console.log(import_chalk10.default.green("Anonymous history merged to current account."));
6339
6841
  } else {
6340
- console.log(import_chalk9.default.yellow("Anonymous history merge not confirmed. You may retry later."));
6842
+ console.log(import_chalk10.default.yellow("Anonymous history merge not confirmed. You may retry later."));
6341
6843
  }
6342
6844
  } catch (e) {
6343
- console.log(import_chalk9.default.red(`Failed to set AppKey: ${(e == null ? void 0 : e.message) || e}`));
6845
+ console.log(import_chalk10.default.red(`Failed to set AppKey: ${(e == null ? void 0 : e.message) || e}`));
6344
6846
  }
6345
6847
  }
6346
6848
 
6347
6849
  // bin/logout.ts
6348
- var import_chalk10 = __toESM(require("chalk"));
6850
+ var import_chalk11 = __toESM(require("chalk"));
6349
6851
  var import_inquirer6 = __toESM(require("inquirer"));
6350
6852
  async function logoutCmd() {
6351
6853
  try {
6352
- const auth = getAuthConfig();
6854
+ const auth = getAuthConfig2();
6353
6855
  if (!auth) {
6354
- console.log(import_chalk10.default.yellow("No active session found. You are already logged out."));
6856
+ console.log(import_chalk11.default.yellow("No active session found. You are already logged out."));
6355
6857
  return;
6356
6858
  }
6357
6859
  const answer = await import_inquirer6.default.prompt([
@@ -6363,80 +6865,80 @@ async function logoutCmd() {
6363
6865
  }
6364
6866
  ]);
6365
6867
  if (!answer.confirm) {
6366
- console.log(import_chalk10.default.blue("Logout cancelled."));
6868
+ console.log(import_chalk11.default.blue("Logout cancelled."));
6367
6869
  return;
6368
6870
  }
6369
6871
  clearAuthToken();
6370
- console.log(import_chalk10.default.green("Successfully logged out."));
6371
- console.log(import_chalk10.default.gray(`Address ${auth.address} has been removed from local storage.`));
6872
+ console.log(import_chalk11.default.green("Successfully logged out."));
6873
+ console.log(import_chalk11.default.gray(`Address ${auth.address} has been removed from local storage.`));
6372
6874
  } catch (e) {
6373
- console.log(import_chalk10.default.red(`Failed to logout: ${(e == null ? void 0 : e.message) || e}`));
6875
+ console.log(import_chalk11.default.red(`Failed to logout: ${(e == null ? void 0 : e.message) || e}`));
6374
6876
  }
6375
6877
  }
6376
6878
 
6377
6879
  // bin/show-appkey.ts
6378
- var import_chalk11 = __toESM(require("chalk"));
6880
+ var import_chalk12 = __toESM(require("chalk"));
6379
6881
  function showAppKeyCmd() {
6380
6882
  try {
6381
- const auth = getAuthConfig();
6883
+ const auth = getAuthConfig2();
6382
6884
  if (!auth) {
6383
- console.log(import_chalk11.default.yellow("No AppKey found. Please set your AppKey first."));
6384
- console.log(import_chalk11.default.gray("Run: pinme set-appkey <AppKey>"));
6885
+ console.log(import_chalk12.default.yellow("No AppKey found. Please set your AppKey first."));
6886
+ console.log(import_chalk12.default.gray("Run: pinme set-appkey <AppKey>"));
6385
6887
  return;
6386
6888
  }
6387
- console.log(import_chalk11.default.green("Current AppKey Information:"));
6388
- console.log(import_chalk11.default.cyan(` Address: ${auth.address}`));
6889
+ console.log(import_chalk12.default.green("Current AppKey Information:"));
6890
+ console.log(import_chalk12.default.cyan(` Address: ${auth.address}`));
6389
6891
  const token = auth.token;
6390
6892
  if (token.length > 12) {
6391
6893
  const maskedToken = `${token.substring(0, 8)}${"*".repeat(token.length - 12)}${token.substring(token.length - 4)}`;
6392
- console.log(import_chalk11.default.cyan(` Token: ${maskedToken}`));
6894
+ console.log(import_chalk12.default.cyan(` Token: ${maskedToken}`));
6393
6895
  } else {
6394
- console.log(import_chalk11.default.cyan(` Token: ${"*".repeat(token.length)}`));
6896
+ console.log(import_chalk12.default.cyan(` Token: ${"*".repeat(token.length)}`));
6395
6897
  }
6396
6898
  const combined = `${auth.address}-${auth.token}`;
6397
6899
  if (combined.length > 20) {
6398
6900
  const maskedAppKey = `${combined.substring(0, 12)}${"*".repeat(combined.length - 16)}${combined.substring(combined.length - 4)}`;
6399
- console.log(import_chalk11.default.cyan(` AppKey: ${maskedAppKey}`));
6901
+ console.log(import_chalk12.default.cyan(` AppKey: ${maskedAppKey}`));
6400
6902
  } else {
6401
- console.log(import_chalk11.default.cyan(` AppKey: ${"*".repeat(combined.length)}`));
6903
+ console.log(import_chalk12.default.cyan(` AppKey: ${"*".repeat(combined.length)}`));
6402
6904
  }
6403
6905
  } catch (e) {
6404
- console.log(import_chalk11.default.red(`Failed to show AppKey: ${(e == null ? void 0 : e.message) || e}`));
6906
+ console.log(import_chalk12.default.red(`Failed to show AppKey: ${(e == null ? void 0 : e.message) || e}`));
6405
6907
  }
6406
6908
  }
6407
6909
 
6408
6910
  // bin/my-domains.ts
6409
- var import_chalk12 = __toESM(require("chalk"));
6911
+ var import_chalk13 = __toESM(require("chalk"));
6410
6912
  var import_dayjs2 = __toESM(require("dayjs"));
6411
6913
  async function myDomainsCmd() {
6412
6914
  try {
6413
6915
  const list = await getMyDomains();
6414
6916
  if (!list.length) {
6415
- console.log(import_chalk12.default.yellow("No bound domains found."));
6917
+ console.log(import_chalk13.default.yellow("No bound domains found."));
6416
6918
  return;
6417
6919
  }
6418
- console.log(import_chalk12.default.cyan("My domains:"));
6419
- console.log(import_chalk12.default.cyan("-".repeat(80)));
6920
+ console.log(import_chalk13.default.cyan("My domains:"));
6921
+ console.log(import_chalk13.default.cyan("-".repeat(80)));
6420
6922
  list.forEach((item, i) => {
6421
- console.log(import_chalk12.default.green(`${i + 1}. ${item.domain_name}`));
6422
- console.log(import_chalk12.default.white(` Type: ${item.domain_type}`));
6923
+ console.log(import_chalk13.default.green(`${i + 1}. ${item.domain_name}`));
6924
+ console.log(import_chalk13.default.white(` Type: ${item.domain_type}`));
6423
6925
  if (item.bind_time) {
6424
- console.log(import_chalk12.default.white(` Bind time: ${(0, import_dayjs2.default)(item.bind_time * 1e3).format("YYYY-MM-DD HH:mm:ss")}`));
6926
+ console.log(import_chalk13.default.white(` Bind time: ${(0, import_dayjs2.default)(item.bind_time * 1e3).format("YYYY-MM-DD HH:mm:ss")}`));
6425
6927
  }
6426
6928
  if (typeof item.expire_time === "number") {
6427
6929
  const label = item.expire_time === 0 ? "Never" : (0, import_dayjs2.default)(item.expire_time * 1e3).format("YYYY-MM-DD HH:mm:ss");
6428
- console.log(import_chalk12.default.white(` Expire time: ${label}`));
6930
+ console.log(import_chalk13.default.white(` Expire time: ${label}`));
6429
6931
  }
6430
- console.log(import_chalk12.default.cyan("-".repeat(80)));
6932
+ console.log(import_chalk13.default.cyan("-".repeat(80)));
6431
6933
  });
6432
6934
  } catch (e) {
6433
- console.log(import_chalk12.default.red(`Failed to fetch domains: ${(e == null ? void 0 : e.message) || e}`));
6935
+ console.log(import_chalk13.default.red(`Failed to fetch domains: ${(e == null ? void 0 : e.message) || e}`));
6434
6936
  }
6435
6937
  }
6436
6938
 
6437
6939
  // bin/bind.ts
6438
- var import_path9 = __toESM(require("path"));
6439
- var import_chalk13 = __toESM(require("chalk"));
6940
+ var import_path10 = __toESM(require("path"));
6941
+ var import_chalk14 = __toESM(require("chalk"));
6440
6942
  var import_inquirer7 = __toESM(require("inquirer"));
6441
6943
  function isDnsDomain2(domain) {
6442
6944
  return domain.includes(".");
@@ -6487,19 +6989,19 @@ function parseArgs() {
6487
6989
  }
6488
6990
  async function checkVipStatus2(authConfig) {
6489
6991
  var _a;
6490
- console.log(import_chalk13.default.blue("Checking VIP status..."));
6992
+ console.log(import_chalk14.default.blue("Checking VIP status..."));
6491
6993
  try {
6492
6994
  const vipResult = await isVip(authConfig.address, authConfig.token);
6493
6995
  if (!((_a = vipResult.data) == null ? void 0 : _a.is_vip)) {
6494
6996
  return false;
6495
6997
  }
6496
- console.log(import_chalk13.default.green("VIP verified."));
6998
+ console.log(import_chalk14.default.green("VIP verified."));
6497
6999
  return true;
6498
7000
  } catch (e) {
6499
7001
  if (e.message === "Token expired") {
6500
7002
  throw e;
6501
7003
  }
6502
- console.log(import_chalk13.default.yellow("Failed to check VIP status, continuing..."));
7004
+ console.log(import_chalk14.default.yellow("Failed to check VIP status, continuing..."));
6503
7005
  return true;
6504
7006
  }
6505
7007
  }
@@ -6507,9 +7009,9 @@ async function bindCmd() {
6507
7009
  var _a;
6508
7010
  try {
6509
7011
  let { domain, targetPath, dns } = parseArgs();
6510
- const authConfig = getAuthConfig();
7012
+ const authConfig = getAuthConfig2();
6511
7013
  if (!authConfig) {
6512
- console.log(import_chalk13.default.red("Please login first. Run: pinme set-appkey <AppKey>"));
7014
+ console.log(import_chalk14.default.red("Please login first. Run: pinme set-appkey <AppKey>"));
6513
7015
  return;
6514
7016
  }
6515
7017
  if (!targetPath) {
@@ -6525,23 +7027,22 @@ async function bindCmd() {
6525
7027
  domain = (_a = ans.domain) == null ? void 0 : _a.trim();
6526
7028
  }
6527
7029
  if (!targetPath || !domain) {
6528
- console.log(import_chalk13.default.red("Missing parameters. Path and domain are required."));
7030
+ console.log(import_chalk14.default.red("Missing parameters. Path and domain are required."));
6529
7031
  return;
6530
7032
  }
6531
7033
  const isDns = dns || isDnsDomain2(domain);
6532
- console.log(isDns, "isDns");
6533
7034
  const displayDomain = domain.replace(/^https?:\/\//, "").replace(/\/$/, "");
6534
7035
  if (isDns) {
6535
7036
  const validation = validateDnsDomain2(domain);
6536
7037
  if (!validation.valid) {
6537
- console.log(import_chalk13.default.red(validation.message));
7038
+ console.log(import_chalk14.default.red(validation.message));
6538
7039
  return;
6539
7040
  }
6540
7041
  }
6541
7042
  try {
6542
7043
  const isVipUser = await checkVipStatus2(authConfig);
6543
7044
  if (!isVipUser) {
6544
- console.log(import_chalk13.default.red("Domain binding requires VIP. Please upgrade to VIP first."));
7045
+ console.log(import_chalk14.default.red("Domain binding requires VIP. Please upgrade to VIP first."));
6545
7046
  return;
6546
7047
  }
6547
7048
  } catch (e) {
@@ -6553,44 +7054,44 @@ async function bindCmd() {
6553
7054
  try {
6554
7055
  const check = await checkDomainAvailable(displayDomain);
6555
7056
  if (!check.is_valid) {
6556
- console.log(import_chalk13.default.red(`Domain not available: ${check.error || "unknown reason"}`));
7057
+ console.log(import_chalk14.default.red(`Domain not available: ${check.error || "unknown reason"}`));
6557
7058
  return;
6558
7059
  }
6559
- console.log(import_chalk13.default.green(`Domain available: ${displayDomain}`));
7060
+ console.log(import_chalk14.default.green(`Domain available: ${displayDomain}`));
6560
7061
  } catch (e) {
6561
7062
  if (e.message === "Token expired") {
6562
7063
  return;
6563
7064
  }
6564
7065
  throw e;
6565
7066
  }
6566
- const absolutePath = import_path9.default.resolve(targetPath);
6567
- console.log(import_chalk13.default.blue(`Uploading: ${absolutePath}`));
7067
+ const absolutePath = import_path10.default.resolve(targetPath);
7068
+ console.log(import_chalk14.default.blue(`Uploading: ${absolutePath}`));
6568
7069
  const up = await uploadToIpfsSplit_default(absolutePath);
6569
7070
  if (!(up == null ? void 0 : up.contentHash)) {
6570
- console.log(import_chalk13.default.red("Upload failed, binding aborted."));
7071
+ console.log(import_chalk14.default.red("Upload failed, binding aborted."));
6571
7072
  return;
6572
7073
  }
6573
- console.log(import_chalk13.default.green(`Upload success, CID: ${up.contentHash}`));
7074
+ console.log(import_chalk14.default.green(`Upload success, CID: ${up.contentHash}`));
6574
7075
  try {
6575
7076
  if (isDns) {
6576
- console.log(import_chalk13.default.blue("Binding DNS domain..."));
7077
+ console.log(import_chalk14.default.blue("Binding DNS domain..."));
6577
7078
  const dnsResult = await bindDnsDomainV4(displayDomain, up.contentHash, authConfig.address, authConfig.token);
6578
7079
  if (dnsResult.code !== 200) {
6579
- console.log(import_chalk13.default.red(`DNS binding failed: ${dnsResult.msg}`));
7080
+ console.log(import_chalk14.default.red(`DNS binding failed: ${dnsResult.msg}`));
6580
7081
  return;
6581
7082
  }
6582
- console.log(import_chalk13.default.green(`DNS bind success: ${displayDomain}`));
6583
- console.log(import_chalk13.default.white(`Visit: https://${displayDomain}`));
6584
- console.log(import_chalk13.default.cyan("\n\u{1F4DA} DNS Setup Guide: https://pinme.eth.limo/#/docs?id=custom-domain"));
7083
+ console.log(import_chalk14.default.green(`DNS bind success: ${displayDomain}`));
7084
+ console.log(import_chalk14.default.white(`Visit: https://${displayDomain}`));
7085
+ console.log(import_chalk14.default.cyan("\n\u{1F4DA} DNS Setup Guide: https://pinme.eth.limo/#/docs?id=custom-domain"));
6585
7086
  } else {
6586
- console.log(import_chalk13.default.blue("Binding Pinme subdomain..."));
7087
+ console.log(import_chalk14.default.blue("Binding Pinme subdomain..."));
6587
7088
  const ok = await bindPinmeDomain(displayDomain, up.contentHash);
6588
7089
  if (!ok) {
6589
- console.log(import_chalk13.default.red("Binding failed. Please try again later."));
7090
+ console.log(import_chalk14.default.red("Binding failed. Please try again later."));
6590
7091
  return;
6591
7092
  }
6592
- console.log(import_chalk13.default.green(`Bind success: ${displayDomain}`));
6593
- console.log(import_chalk13.default.white(`Visit: https://${displayDomain}.pinit.eth.limo`));
7093
+ console.log(import_chalk14.default.green(`Bind success: ${displayDomain}`));
7094
+ console.log(import_chalk14.default.white(`Visit: https://${displayDomain}.pinit.eth.limo`));
6594
7095
  }
6595
7096
  } catch (e) {
6596
7097
  if (e.message === "Token expired") {
@@ -6599,7 +7100,1143 @@ async function bindCmd() {
6599
7100
  throw e;
6600
7101
  }
6601
7102
  } catch (e) {
6602
- console.log(import_chalk13.default.red(`Execution failed: ${(e == null ? void 0 : e.message) || e}`));
7103
+ console.log(import_chalk14.default.red(`Execution failed: ${(e == null ? void 0 : e.message) || e}`));
7104
+ }
7105
+ }
7106
+
7107
+ // bin/login.ts
7108
+ var import_chalk15 = __toESM(require("chalk"));
7109
+ var ENV_URLS = {
7110
+ dev: "http://localhost:5173",
7111
+ test: "http://test-pinme.pinit.eth.limo",
7112
+ prod: "https://pinme.eth.limo"
7113
+ };
7114
+ async function loginCmd(options = {}) {
7115
+ try {
7116
+ let webBaseUrl;
7117
+ const env = (options.env || "prod").toLowerCase();
7118
+ if (ENV_URLS[env]) {
7119
+ webBaseUrl = ENV_URLS[env];
7120
+ console.log(import_chalk15.default.blue(`Using ${env} environment: ${webBaseUrl}`));
7121
+ } else {
7122
+ console.log(import_chalk15.default.yellow(`Unknown environment: ${options.env}. Using default prod.`));
7123
+ webBaseUrl = ENV_URLS.prod;
7124
+ console.log(import_chalk15.default.blue(`Using prod environment: ${webBaseUrl}`));
7125
+ }
7126
+ const manager = new WebLoginManager({ webBaseUrl });
7127
+ await manager.login();
7128
+ console.log(import_chalk15.default.blue("\nMerging history..."));
7129
+ const deviceId = getDeviceId();
7130
+ const ok = await bindAnonymousDevice(deviceId);
7131
+ if (ok) {
7132
+ console.log(import_chalk15.default.green("History merged to your account"));
7133
+ }
7134
+ process.exit(0);
7135
+ } catch (e) {
7136
+ console.log(import_chalk15.default.red(`
7137
+ Login failed: ${(e == null ? void 0 : e.message) || e}`));
7138
+ process.exit(1);
7139
+ }
7140
+ }
7141
+
7142
+ // bin/create.ts
7143
+ var import_chalk17 = __toESM(require("chalk"));
7144
+ var import_fs_extra6 = __toESM(require("fs-extra"));
7145
+ var import_path11 = __toESM(require("path"));
7146
+ var import_inquirer8 = __toESM(require("inquirer"));
7147
+ var import_child_process2 = require("child_process");
7148
+
7149
+ // bin/utils/cliError.ts
7150
+ var import_chalk16 = __toESM(require("chalk"));
7151
+ var CliError = class extends Error {
7152
+ stage;
7153
+ details;
7154
+ suggestions;
7155
+ cause;
7156
+ constructor(options) {
7157
+ super(options.summary);
7158
+ this.name = "CliError";
7159
+ this.stage = options.stage;
7160
+ this.details = options.details || [];
7161
+ this.suggestions = options.suggestions || [];
7162
+ this.cause = options.cause;
7163
+ }
7164
+ };
7165
+ function stringifyValue(value) {
7166
+ if (value === void 0 || value === null) {
7167
+ return "";
7168
+ }
7169
+ if (typeof value === "string") {
7170
+ return value;
7171
+ }
7172
+ try {
7173
+ return JSON.stringify(value);
7174
+ } catch (error) {
7175
+ return String(value);
7176
+ }
7177
+ }
7178
+ function getApiMessage(data) {
7179
+ var _a, _b, _c;
7180
+ return ((_a = data == null ? void 0 : data.data) == null ? void 0 : _a.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);
7181
+ }
7182
+ function getBusinessCode(data) {
7183
+ if ((data == null ? void 0 : data.code) === void 0 || (data == null ? void 0 : data.code) === null) {
7184
+ return void 0;
7185
+ }
7186
+ return String(data.code);
7187
+ }
7188
+ function getBusinessMessage(data) {
7189
+ if (!(data == null ? void 0 : data.msg)) {
7190
+ return void 0;
7191
+ }
7192
+ return String(data.msg);
7193
+ }
7194
+ function dedupeSuggestions(suggestions) {
7195
+ return Array.from(new Set(suggestions.filter(Boolean)));
7196
+ }
7197
+ function createConfigError(summary, suggestions = []) {
7198
+ return new CliError({
7199
+ summary,
7200
+ stage: "configuration",
7201
+ suggestions
7202
+ });
7203
+ }
7204
+ function createCommandError(stage, command, error, suggestions = []) {
7205
+ const exitCode = (error == null ? void 0 : error.status) ?? (error == null ? void 0 : error.code);
7206
+ const signal = error == null ? void 0 : error.signal;
7207
+ const detailLines = [`Command: ${command}`];
7208
+ if (exitCode !== void 0) {
7209
+ detailLines.push(`Exit code: ${exitCode}`);
7210
+ }
7211
+ if (signal) {
7212
+ detailLines.push(`Signal: ${signal}`);
7213
+ }
7214
+ if (error == null ? void 0 : error.message) {
7215
+ detailLines.push(`Reason: ${error.message}`);
7216
+ }
7217
+ return new CliError({
7218
+ summary: `${stage} failed.`,
7219
+ stage,
7220
+ details: detailLines,
7221
+ suggestions,
7222
+ cause: error
7223
+ });
7224
+ }
7225
+ function createApiError(stage, error, context = [], suggestions = []) {
7226
+ var _a, _b;
7227
+ const status = (_a = error == null ? void 0 : error.response) == null ? void 0 : _a.status;
7228
+ const responseData = (_b = error == null ? void 0 : error.response) == null ? void 0 : _b.data;
7229
+ const errorCode = error == null ? void 0 : error.code;
7230
+ const apiMessage = getApiMessage(responseData);
7231
+ const businessCode = getBusinessCode(responseData);
7232
+ const businessMessage = getBusinessMessage(responseData);
7233
+ const summary = apiMessage || (error == null ? void 0 : error.message) || `${stage} failed.`;
7234
+ const detailLines = [...context];
7235
+ if (status) {
7236
+ detailLines.push(`HTTP status: ${status}`);
7237
+ }
7238
+ if (businessCode) {
7239
+ detailLines.push(`Business code: ${businessCode}`);
7240
+ }
7241
+ if (businessMessage && businessMessage !== apiMessage) {
7242
+ detailLines.push(`Business message: ${businessMessage}`);
7243
+ }
7244
+ if (apiMessage && apiMessage !== summary) {
7245
+ detailLines.push(`Error message: ${apiMessage}`);
7246
+ }
7247
+ if (errorCode && errorCode !== "ERR_BAD_REQUEST" && !responseData) {
7248
+ detailLines.push(`Error code: ${errorCode}`);
7249
+ }
7250
+ if (!responseData && (error == null ? void 0 : error.message) && error.message !== apiMessage) {
7251
+ detailLines.push(`Reason: ${error.message}`);
7252
+ }
7253
+ return new CliError({
7254
+ summary,
7255
+ stage,
7256
+ details: detailLines,
7257
+ suggestions: dedupeSuggestions(suggestions),
7258
+ cause: error
7259
+ });
7260
+ }
7261
+ function normalizeCliError(error, fallbackSummary, suggestions = []) {
7262
+ if (error instanceof CliError) {
7263
+ return error;
7264
+ }
7265
+ if (error instanceof Error) {
7266
+ return new CliError({
7267
+ summary: error.message || fallbackSummary,
7268
+ suggestions: dedupeSuggestions(suggestions),
7269
+ cause: error
7270
+ });
7271
+ }
7272
+ return new CliError({
7273
+ summary: fallbackSummary,
7274
+ details: [`Raw error: ${stringifyValue(error)}`],
7275
+ suggestions: dedupeSuggestions(suggestions),
7276
+ cause: error
7277
+ });
7278
+ }
7279
+ function printCliError(error, fallbackSummary) {
7280
+ const cliError = normalizeCliError(error, fallbackSummary);
7281
+ console.error(import_chalk16.default.red(`
7282
+ Error: ${cliError.message}`));
7283
+ if (cliError.stage) {
7284
+ console.error(import_chalk16.default.gray(`Stage: ${cliError.stage}`));
7285
+ }
7286
+ for (const detail of cliError.details) {
7287
+ console.error(import_chalk16.default.gray(detail));
7288
+ }
7289
+ if (cliError.suggestions.length > 0) {
7290
+ console.error(import_chalk16.default.yellow("\nNext steps:"));
7291
+ for (const suggestion of cliError.suggestions) {
7292
+ console.error(import_chalk16.default.yellow(`- ${suggestion}`));
7293
+ }
7294
+ }
7295
+ }
7296
+
7297
+ // bin/create.ts
7298
+ var PROJECT_DIR = process.cwd();
7299
+ var API_BASE = "https://pinme.benny1996.win/api/v4";
7300
+ var TEMPLATE_REPO = "glitternetwork/pinme-worker-template";
7301
+ var TEMPLATE_ZIP_URL = `https://github.com/${TEMPLATE_REPO}/archive/refs/heads/main.zip`;
7302
+ async function createCmd(options) {
7303
+ try {
7304
+ const headers = getAuthHeaders();
7305
+ if (!headers["authentication-tokens"] || !headers["token-address"]) {
7306
+ throw createConfigError("No valid local login session was found.", [
7307
+ "Run `pinme login` and retry."
7308
+ ]);
7309
+ }
7310
+ console.log(import_chalk17.default.blue("Creating new project from template...\n"));
7311
+ let projectName = options.name;
7312
+ if (!projectName) {
7313
+ const answers = await import_inquirer8.default.prompt([
7314
+ {
7315
+ type: "input",
7316
+ name: "projectName",
7317
+ message: "Enter project name:",
7318
+ validate: (input) => {
7319
+ if (!input.trim()) return "Project name is required";
7320
+ if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
7321
+ return "Project name can only contain letters, numbers, hyphens and underscores";
7322
+ }
7323
+ return true;
7324
+ }
7325
+ }
7326
+ ]);
7327
+ projectName = answers.projectName;
7328
+ }
7329
+ const targetDir = import_path11.default.join(PROJECT_DIR, projectName);
7330
+ if (import_fs_extra6.default.existsSync(targetDir) && !options.force) {
7331
+ console.log(import_chalk17.default.yellow(`
7332
+ Directory "${projectName}" already exists.`));
7333
+ const answers = await import_inquirer8.default.prompt([
7334
+ {
7335
+ type: "confirm",
7336
+ name: "overwrite",
7337
+ message: "Do you want to overwrite it?",
7338
+ default: false
7339
+ }
7340
+ ]);
7341
+ if (!answers.overwrite) {
7342
+ console.log(import_chalk17.default.gray("Cancelled."));
7343
+ process.exit(0);
7344
+ }
7345
+ import_fs_extra6.default.removeSync(targetDir);
7346
+ }
7347
+ console.log(import_chalk17.default.blue("\n1. Creating worker and database..."));
7348
+ const apiUrl = `${API_BASE}/create_worker`;
7349
+ console.log(import_chalk17.default.gray(`API URL: ${apiUrl}`));
7350
+ const normalizedProjectName = projectName.toLowerCase();
7351
+ console.log(import_chalk17.default.gray(`Project name: ${normalizedProjectName}`));
7352
+ let workerData;
7353
+ try {
7354
+ const response = await axios_default.post(apiUrl, {
7355
+ project_name: normalizedProjectName
7356
+ }, {
7357
+ headers: {
7358
+ ...headers,
7359
+ "Content-Type": "application/json"
7360
+ }
7361
+ });
7362
+ const data = response.data;
7363
+ if (data.code !== 200) {
7364
+ throw createApiError("project creation", { response: { status: response.status, data } }, [
7365
+ `Project name: ${normalizedProjectName}`,
7366
+ `Endpoint: ${apiUrl}`
7367
+ ]);
7368
+ }
7369
+ workerData = data.data;
7370
+ console.log(import_chalk17.default.gray(` API Response: ${JSON.stringify(workerData)}`));
7371
+ console.log(import_chalk17.default.green(` API Domain: ${workerData.api_domain}`));
7372
+ console.log(import_chalk17.default.green(` Project Name: ${workerData.project_name}`));
7373
+ console.log(import_chalk17.default.green(` D1 UUID: ${workerData.uuid}`));
7374
+ } catch (error) {
7375
+ throw createApiError("project creation", error, [
7376
+ `Project name: ${normalizedProjectName}`,
7377
+ `Endpoint: ${apiUrl}`
7378
+ ]);
7379
+ }
7380
+ console.log(import_chalk17.default.blue("\n2. Downloading template from repository..."));
7381
+ const zipPath = import_path11.default.join(PROJECT_DIR, "template.zip");
7382
+ let downloadSuccess = false;
7383
+ for (let attempt = 1; attempt <= 3 && !downloadSuccess; attempt++) {
7384
+ try {
7385
+ console.log(import_chalk17.default.gray(` Download attempt ${attempt}/3...`));
7386
+ (0, import_child_process2.execSync)(`curl -L --retry 3 --retry-delay 2 -o "${zipPath}" "${TEMPLATE_ZIP_URL}"`, {
7387
+ stdio: "inherit"
7388
+ });
7389
+ if (!import_fs_extra6.default.existsSync(zipPath) || import_fs_extra6.default.statSync(zipPath).size < 100) {
7390
+ throw new Error("Downloaded file is too small or empty");
7391
+ }
7392
+ downloadSuccess = true;
7393
+ } catch (downloadError) {
7394
+ console.log(import_chalk17.default.yellow(` Attempt ${attempt} failed: ${downloadError.message}`));
7395
+ if (import_fs_extra6.default.existsSync(zipPath)) {
7396
+ import_fs_extra6.default.removeSync(zipPath);
7397
+ }
7398
+ if (attempt === 3) {
7399
+ throw new Error(`Failed to download template after 3 attempts: ${downloadError.message}`);
7400
+ }
7401
+ }
7402
+ }
7403
+ try {
7404
+ (0, import_child_process2.execSync)(`unzip -o "${zipPath}" -d "${PROJECT_DIR}"`, {
7405
+ stdio: "inherit"
7406
+ });
7407
+ const subDir = import_path11.default.join(PROJECT_DIR, "pinme-worker-template-main");
7408
+ if (import_fs_extra6.default.existsSync(subDir)) {
7409
+ import_fs_extra6.default.copySync(subDir, targetDir);
7410
+ import_fs_extra6.default.removeSync(subDir);
7411
+ }
7412
+ import_fs_extra6.default.removeSync(zipPath);
7413
+ console.log(import_chalk17.default.green(` Template downloaded to: ${targetDir}`));
7414
+ } catch (error) {
7415
+ throw createCommandError("template extraction", `unzip -o "${zipPath}" -d "${PROJECT_DIR}"`, error, [
7416
+ "Check whether `unzip` is available and the downloaded template archive is valid."
7417
+ ]);
7418
+ }
7419
+ console.log(import_chalk17.default.blue("\n3. Updating configuration..."));
7420
+ const configPath = import_path11.default.join(targetDir, "pinme.toml");
7421
+ const config = import_fs_extra6.default.readFileSync(configPath, "utf-8");
7422
+ let updatedConfig = config.replace(
7423
+ /project_name = ".*"/,
7424
+ `project_name = "${workerData.project_name}"`
7425
+ );
7426
+ import_fs_extra6.default.writeFileSync(configPath, updatedConfig);
7427
+ console.log(import_chalk17.default.green(` Updated pinme.toml`));
7428
+ console.log(import_chalk17.default.gray(` metadata: ${workerData.metadata}`));
7429
+ console.log(import_chalk17.default.gray(` VITE_API_URL: ${workerData.api_domain}`));
7430
+ const backendDir = import_path11.default.join(targetDir, "backend");
7431
+ if (import_fs_extra6.default.existsSync(backendDir) && workerData.metadata) {
7432
+ const metadataContent = typeof workerData.metadata === "string" ? workerData.metadata : JSON.stringify(workerData.metadata, null, 2);
7433
+ import_fs_extra6.default.writeFileSync(
7434
+ import_path11.default.join(backendDir, "metadata.json"),
7435
+ metadataContent
7436
+ );
7437
+ console.log(import_chalk17.default.green(` Saved metadata.json`));
7438
+ }
7439
+ const wranglerPath = import_path11.default.join(backendDir, "wrangler.toml");
7440
+ if (import_fs_extra6.default.existsSync(wranglerPath) && workerData.api_key) {
7441
+ let wranglerContent = import_fs_extra6.default.readFileSync(wranglerPath, "utf-8");
7442
+ wranglerContent = wranglerContent.replace(
7443
+ /^name = ".*"$/m,
7444
+ `name = "${workerData.project_name}"`
7445
+ );
7446
+ import_fs_extra6.default.writeFileSync(wranglerPath, wranglerContent);
7447
+ console.log(import_chalk17.default.green(` Updated backend/wrangler.toml API_KEY`));
7448
+ }
7449
+ const envExamplePath = import_path11.default.join(targetDir, "frontend", ".env.example");
7450
+ const envPath = import_path11.default.join(targetDir, "frontend", ".env");
7451
+ if (import_fs_extra6.default.existsSync(envExamplePath)) {
7452
+ let envContent = import_fs_extra6.default.readFileSync(envExamplePath, "utf-8");
7453
+ envContent = envContent.replace(/your-project/g, workerData.project_name);
7454
+ envContent = envContent.replace(
7455
+ /^VITE_API_URL=.*$/m,
7456
+ `VITE_API_URL=${workerData.api_domain}`
7457
+ );
7458
+ import_fs_extra6.default.writeFileSync(envPath, envContent);
7459
+ console.log(import_chalk17.default.green(` Created frontend/.env file`));
7460
+ }
7461
+ console.log(import_chalk17.default.blue("\n4. Building frontend..."));
7462
+ try {
7463
+ (0, import_child_process2.execSync)("npm install", {
7464
+ cwd: targetDir,
7465
+ stdio: "inherit"
7466
+ });
7467
+ console.log(import_chalk17.default.green(" Project dependencies installed"));
7468
+ } catch (error) {
7469
+ throw createCommandError("project dependency install", "npm install", error, [
7470
+ "Check network connectivity and npm registry availability.",
7471
+ "Inspect the generated workspace `package.json` files for dependency conflicts."
7472
+ ]);
7473
+ }
7474
+ const frontendDir = import_path11.default.join(targetDir, "frontend");
7475
+ if (import_fs_extra6.default.existsSync(frontendDir)) {
7476
+ try {
7477
+ (0, import_child_process2.execSync)("npm run build:frontend", {
7478
+ cwd: targetDir,
7479
+ stdio: "inherit"
7480
+ });
7481
+ console.log(import_chalk17.default.green(" Frontend built"));
7482
+ } catch (error) {
7483
+ throw createCommandError("frontend build", "npm run build:frontend", error, [
7484
+ "Fix the frontend build error shown above, then rerun `pinme create`."
7485
+ ]);
7486
+ }
7487
+ console.log(import_chalk17.default.blue(" Uploading to IPFS..."));
7488
+ try {
7489
+ (0, import_child_process2.execSync)("pinme upload ./dist", {
7490
+ cwd: frontendDir,
7491
+ stdio: "inherit",
7492
+ env: {
7493
+ ...process.env,
7494
+ PINME_PROJECT_NAME: workerData.project_name
7495
+ }
7496
+ });
7497
+ console.log(import_chalk17.default.green(" Frontend uploaded to IPFS"));
7498
+ } catch (error) {
7499
+ console.log(import_chalk17.default.yellow(" Warning: IPFS upload failed, you can upload manually later"));
7500
+ }
7501
+ }
7502
+ console.log(import_chalk17.default.green("\nProject created successfully."));
7503
+ console.log(import_chalk17.default.gray(`
7504
+ Project Details:`));
7505
+ console.log(import_chalk17.default.gray(` API Domain: ${workerData.api_domain}`));
7506
+ console.log(import_chalk17.default.gray(` Project Name: ${workerData.project_name}`));
7507
+ console.log(import_chalk17.default.gray(`
7508
+ Next steps:`));
7509
+ console.log(import_chalk17.default.gray(` cd ${projectName}`));
7510
+ console.log(import_chalk17.default.gray(` pinme save`));
7511
+ process.exit(0);
7512
+ } catch (error) {
7513
+ printCliError(error, "Project creation failed.");
7514
+ process.exit(1);
7515
+ }
7516
+ }
7517
+
7518
+ // bin/save.ts
7519
+ var import_chalk18 = __toESM(require("chalk"));
7520
+ var import_fs_extra7 = __toESM(require("fs-extra"));
7521
+ var import_path12 = __toESM(require("path"));
7522
+ var import_child_process3 = require("child_process");
7523
+ var PROJECT_DIR2 = process.cwd();
7524
+ var API_BASE2 = "https://pinme.benny1996.win/api/v4";
7525
+ function loadConfig() {
7526
+ const configPath = import_path12.default.join(PROJECT_DIR2, "pinme.toml");
7527
+ if (!import_fs_extra7.default.existsSync(configPath)) {
7528
+ throw createConfigError("`pinme.toml` not found in the current directory.", [
7529
+ "Run this command from the Pinme project root.",
7530
+ "If the project has not been initialized yet, create or restore `pinme.toml` first."
7531
+ ]);
7532
+ }
7533
+ const configContent = import_fs_extra7.default.readFileSync(configPath, "utf-8");
7534
+ const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
7535
+ return {
7536
+ project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
7537
+ };
7538
+ }
7539
+ function getMetadata() {
7540
+ const metadataPath = import_path12.default.join(PROJECT_DIR2, "backend", "metadata.json");
7541
+ if (!import_fs_extra7.default.existsSync(metadataPath)) {
7542
+ console.log(import_chalk18.default.yellow(" Warning: metadata.json not found, using empty metadata"));
7543
+ return {};
7544
+ }
7545
+ return import_fs_extra7.default.readJsonSync(metadataPath);
7546
+ }
7547
+ function buildWorker() {
7548
+ console.log(import_chalk18.default.blue("Building worker..."));
7549
+ try {
7550
+ (0, import_child_process3.execSync)("npm run build:worker", {
7551
+ cwd: PROJECT_DIR2,
7552
+ stdio: "inherit"
7553
+ });
7554
+ console.log(import_chalk18.default.green("Worker built"));
7555
+ } catch (error) {
7556
+ throw createCommandError("worker build", "npm run build:worker", error, [
7557
+ "Fix the build error shown above, then rerun `pinme save`."
7558
+ ]);
7559
+ }
7560
+ }
7561
+ function installDependencies() {
7562
+ console.log(import_chalk18.default.blue("Installing dependencies..."));
7563
+ try {
7564
+ (0, import_child_process3.execSync)("npm install", {
7565
+ cwd: PROJECT_DIR2,
7566
+ stdio: "inherit"
7567
+ });
7568
+ console.log(import_chalk18.default.green("Project dependencies installed"));
7569
+ } catch (error) {
7570
+ throw createCommandError("project dependency install", "npm install", error, [
7571
+ "Check network connectivity and npm registry availability.",
7572
+ "If `package-lock.json` is stale or conflicted, resolve that before retrying."
7573
+ ]);
7574
+ }
7575
+ }
7576
+ function getBuiltWorker() {
7577
+ const distWorkerDir = import_path12.default.join(PROJECT_DIR2, "dist-worker");
7578
+ if (!import_fs_extra7.default.existsSync(distWorkerDir)) {
7579
+ throw createConfigError("Built worker output not found: `dist-worker/`.", [
7580
+ "Make sure `npm run build:worker` completed successfully."
7581
+ ]);
7582
+ }
7583
+ const workerJsPath = import_path12.default.join(distWorkerDir, "worker.js");
7584
+ if (!import_fs_extra7.default.existsSync(workerJsPath)) {
7585
+ throw createConfigError("Built worker entry file not found: `dist-worker/worker.js`.", [
7586
+ "Check the worker build output and bundler config."
7587
+ ]);
7588
+ }
7589
+ const modulePaths = [];
7590
+ const files = import_fs_extra7.default.readdirSync(distWorkerDir);
7591
+ for (const file of files) {
7592
+ if (file.endsWith(".js") && file !== "worker.js") {
7593
+ modulePaths.push(import_path12.default.join(distWorkerDir, file));
7594
+ }
7595
+ }
7596
+ return { workerJsPath, modulePaths };
7597
+ }
7598
+ function getSqlFiles() {
7599
+ const sqlDir = import_path12.default.join(PROJECT_DIR2, "db");
7600
+ if (!import_fs_extra7.default.existsSync(sqlDir)) {
7601
+ return [];
7602
+ }
7603
+ const files = import_fs_extra7.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
7604
+ return files.map((f) => import_path12.default.join(sqlDir, f));
7605
+ }
7606
+ async function saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, projectName) {
7607
+ var _a, _b;
7608
+ console.log(import_chalk18.default.blue("Saving worker to platform..."));
7609
+ console.log(import_chalk18.default.gray(`Project: ${projectName}`));
7610
+ console.log(import_chalk18.default.gray(`workerJsPath: ${workerJsPath}`));
7611
+ console.log(import_chalk18.default.gray(`modulePaths: ${modulePaths}`));
7612
+ console.log(import_chalk18.default.gray(`sqlFiles: ${sqlFiles}`));
7613
+ console.log(import_chalk18.default.gray(`metadata: ${metadata}`));
7614
+ const apiUrl = `${API_BASE2}/save_worker?project_name=${encodeURIComponent(projectName)}`;
7615
+ const headers = getAuthHeaders();
7616
+ console.log(import_chalk18.default.gray(`API URL: ${apiUrl}`));
7617
+ try {
7618
+ const FormData4 = (await import("formdata-node")).FormData;
7619
+ const Blob2 = (await import("formdata-node")).Blob;
7620
+ const formData = new FormData4();
7621
+ formData.append("metadata", new Blob2([JSON.stringify(metadata)], {
7622
+ type: "application/json"
7623
+ }), "metadata.json");
7624
+ const workerCode = import_fs_extra7.default.readFileSync(workerJsPath, "utf-8");
7625
+ formData.append("worker.js", new Blob2([workerCode], {
7626
+ type: "application/javascript+module"
7627
+ }), "worker.js");
7628
+ for (const modulePath of modulePaths) {
7629
+ const filename = import_path12.default.basename(modulePath);
7630
+ const content = import_fs_extra7.default.readFileSync(modulePath, "utf-8");
7631
+ formData.append(filename, new Blob2([content], {
7632
+ type: "application/javascript+module"
7633
+ }), filename);
7634
+ }
7635
+ for (const sqlFile of sqlFiles) {
7636
+ const filename = import_path12.default.basename(sqlFile);
7637
+ const content = import_fs_extra7.default.readFileSync(sqlFile, "utf-8");
7638
+ formData.append("sql_file", new Blob2([content], {
7639
+ type: "application/sql"
7640
+ }), filename);
7641
+ console.log(import_chalk18.default.gray(` Including SQL: ${filename}`));
7642
+ }
7643
+ const response = await axios_default.put(apiUrl, formData, {
7644
+ headers: { ...headers },
7645
+ timeout: 12e4
7646
+ });
7647
+ console.log(import_chalk18.default.gray(` Response: ${JSON.stringify(response.data)}`));
7648
+ if (response.data) {
7649
+ console.log(import_chalk18.default.green("Worker saved"));
7650
+ if ((_b = (_a = response.data) == null ? void 0 : _a.data) == null ? void 0 : _b.sql_results) {
7651
+ for (const result of response.data.data.sql_results) {
7652
+ console.log(import_chalk18.default.gray(` SQL ${result.filename}: ${result.status}`));
7653
+ }
7654
+ }
7655
+ } else {
7656
+ throw createApiError("worker save", { response: { data: response.data } }, [
7657
+ `Project: ${projectName}`,
7658
+ `Endpoint: ${apiUrl}`
7659
+ ], [
7660
+ "Verify the project exists and your account has permission to update it."
7661
+ ]);
7662
+ }
7663
+ } catch (error) {
7664
+ throw createApiError("worker save", error, [
7665
+ `Project: ${projectName}`,
7666
+ `Endpoint: ${apiUrl}`
7667
+ ], [
7668
+ "Check whether backend metadata, SQL files, or worker bundle contains invalid content."
7669
+ ]);
7670
+ }
7671
+ }
7672
+ function buildFrontend() {
7673
+ console.log(import_chalk18.default.blue("Building frontend..."));
7674
+ try {
7675
+ (0, import_child_process3.execSync)("npm run build:frontend", {
7676
+ cwd: PROJECT_DIR2,
7677
+ stdio: "inherit"
7678
+ });
7679
+ console.log(import_chalk18.default.green("Frontend built"));
7680
+ } catch (error) {
7681
+ throw createCommandError("frontend build", "npm run build:frontend", error, [
7682
+ "Fix the frontend build error shown above, then rerun `pinme save`."
7683
+ ]);
7684
+ }
7685
+ }
7686
+ function deployFrontend(projectName) {
7687
+ console.log(import_chalk18.default.blue("Deploying frontend to IPFS..."));
7688
+ try {
7689
+ (0, import_child_process3.execSync)("pinme upload ./frontend/dist", {
7690
+ cwd: PROJECT_DIR2,
7691
+ stdio: "inherit",
7692
+ env: {
7693
+ ...process.env,
7694
+ PINME_PROJECT_NAME: projectName
7695
+ }
7696
+ });
7697
+ console.log(import_chalk18.default.green("Frontend deployed to IPFS"));
7698
+ } catch (error) {
7699
+ throw createCommandError("frontend deploy", "pinme upload ./frontend/dist", error, [
7700
+ "Make sure `frontend/dist` exists and `pinme upload` works in this environment."
7701
+ ]);
7702
+ }
7703
+ }
7704
+ async function saveCmd(options) {
7705
+ try {
7706
+ const headers = getAuthHeaders();
7707
+ if (!headers["authentication-tokens"] || !headers["token-address"]) {
7708
+ throw createConfigError("No valid local login session was found.", [
7709
+ "Run `pinme login` and retry."
7710
+ ]);
7711
+ }
7712
+ const projectDir = options.projectName || options.name ? import_path12.default.join(PROJECT_DIR2, options.projectName || options.name) : PROJECT_DIR2;
7713
+ const tokenFileSrc = import_path12.default.join(PROJECT_DIR2, ".token.json");
7714
+ const tokenFileDst = import_path12.default.join(projectDir, ".token.json");
7715
+ if (import_fs_extra7.default.existsSync(tokenFileSrc) && !import_fs_extra7.default.existsSync(tokenFileDst)) {
7716
+ import_fs_extra7.default.copySync(tokenFileSrc, tokenFileDst);
7717
+ }
7718
+ console.log(import_chalk18.default.blue("Deploying to platform...\n"));
7719
+ console.log(import_chalk18.default.gray(`Project dir: ${PROJECT_DIR2}`));
7720
+ const config = loadConfig();
7721
+ const projectName = config.project_name;
7722
+ if (!projectName) {
7723
+ throw createConfigError("`project_name` is missing in `pinme.toml`.", [
7724
+ 'Set `project_name = "your-project-name"` in `pinme.toml`.'
7725
+ ]);
7726
+ }
7727
+ console.log(import_chalk18.default.gray(`Project: ${projectName}`));
7728
+ const apiUrl = `${API_BASE2}/save_worker?project_name=${encodeURIComponent(projectName)}`;
7729
+ console.log(import_chalk18.default.gray(`API URL: ${apiUrl}`));
7730
+ console.log(import_chalk18.default.blue("\n--- Backend ---"));
7731
+ installDependencies();
7732
+ buildWorker();
7733
+ const metadata = getMetadata();
7734
+ const { workerJsPath, modulePaths } = getBuiltWorker();
7735
+ console.log(import_chalk18.default.gray(`Worker JS: ${workerJsPath}`));
7736
+ console.log(import_chalk18.default.gray(`Module paths: ${JSON.stringify(modulePaths)}`));
7737
+ const sqlFiles = getSqlFiles();
7738
+ console.log(import_chalk18.default.gray(`SQL files: ${JSON.stringify(sqlFiles)}`));
7739
+ await saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, projectName);
7740
+ console.log(import_chalk18.default.blue("\n--- Frontend ---"));
7741
+ buildFrontend();
7742
+ deployFrontend(projectName);
7743
+ console.log(import_chalk18.default.green("\nDeployment complete."));
7744
+ process.exit(0);
7745
+ } catch (error) {
7746
+ printCliError(error, "Save failed.");
7747
+ process.exit(1);
7748
+ }
7749
+ }
7750
+
7751
+ // bin/updateDb.ts
7752
+ var import_chalk19 = __toESM(require("chalk"));
7753
+ var import_fs_extra8 = __toESM(require("fs-extra"));
7754
+ var import_path13 = __toESM(require("path"));
7755
+ var PROJECT_DIR3 = process.cwd();
7756
+ var API_BASE3 = "https://pinme.benny1996.win/api/v4";
7757
+ function loadConfig2() {
7758
+ const configPath = import_path13.default.join(PROJECT_DIR3, "pinme.toml");
7759
+ if (!import_fs_extra8.default.existsSync(configPath)) {
7760
+ throw createConfigError("`pinme.toml` not found in the current directory.", [
7761
+ "Run this command from the Pinme project root."
7762
+ ]);
7763
+ }
7764
+ const configContent = import_fs_extra8.default.readFileSync(configPath, "utf-8");
7765
+ const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
7766
+ return {
7767
+ project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
7768
+ };
7769
+ }
7770
+ function getSqlFiles2() {
7771
+ const sqlDir = import_path13.default.join(PROJECT_DIR3, "db");
7772
+ if (!import_fs_extra8.default.existsSync(sqlDir)) {
7773
+ throw createConfigError("SQL directory not found: `db/`.", [
7774
+ "Create a `db/` directory and add at least one `.sql` migration file."
7775
+ ]);
7776
+ }
7777
+ const files = import_fs_extra8.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
7778
+ if (files.length === 0) {
7779
+ throw createConfigError("No `.sql` files were found in `db/`.", [
7780
+ "Add one or more migration files before running `pinme update-db`."
7781
+ ]);
7782
+ }
7783
+ return files.map((f) => import_path13.default.join(sqlDir, f));
7784
+ }
7785
+ async function updateDb(sqlFiles, projectName) {
7786
+ console.log(import_chalk19.default.blue("Importing SQL files to database..."));
7787
+ console.log(import_chalk19.default.gray(`Project: ${projectName}`));
7788
+ console.log(import_chalk19.default.gray(`SQL files: ${sqlFiles.length}`));
7789
+ const apiUrl = `${API_BASE3}/update_db?project_name=${encodeURIComponent(projectName)}`;
7790
+ const headers = getAuthHeaders();
7791
+ console.log(import_chalk19.default.gray(`API URL: ${apiUrl}`));
7792
+ try {
7793
+ const FormData4 = (await import("formdata-node")).FormData;
7794
+ const Blob2 = (await import("formdata-node")).Blob;
7795
+ const formData = new FormData4();
7796
+ let totalSize = 0;
7797
+ for (const sqlFile of sqlFiles) {
7798
+ const filename = import_path13.default.basename(sqlFile);
7799
+ const content = import_fs_extra8.default.readFileSync(sqlFile);
7800
+ totalSize += content.length;
7801
+ if (totalSize > 10 * 1024 * 1024) {
7802
+ throw createConfigError("Total SQL payload exceeds the 10MB platform limit.", [
7803
+ "Split migrations into smaller batches, then rerun `pinme update-db`."
7804
+ ]);
7805
+ }
7806
+ formData.append("file", new Blob2([content], {
7807
+ type: "application/sql"
7808
+ }), filename);
7809
+ console.log(import_chalk19.default.gray(` Including: ${filename} (${content.length} bytes)`));
7810
+ }
7811
+ const response = await axios_default.post(apiUrl, formData, {
7812
+ headers: { ...headers },
7813
+ timeout: 12e4
7814
+ });
7815
+ console.log(import_chalk19.default.gray(` Response: ${JSON.stringify(response.data)}`));
7816
+ if (response.data.code === 200) {
7817
+ console.log(import_chalk19.default.green("SQL files imported successfully!"));
7818
+ const results = response.data.data.results;
7819
+ for (const result of results) {
7820
+ if (result.status === "complete") {
7821
+ console.log(import_chalk19.default.green(` COMPLETE ${result.filename}: ${result.num_queries} queries, ${result.duration}ms`));
7822
+ if (result.changes !== void 0) {
7823
+ console.log(import_chalk19.default.gray(` Changes: ${result.changes}, Read: ${result.rows_read}, Written: ${result.rows_written}`));
7824
+ }
7825
+ } else if (result.status === "error") {
7826
+ console.log(import_chalk19.default.red(` ERROR ${result.filename}: ${result.error}`));
7827
+ }
7828
+ }
7829
+ } else {
7830
+ throw createApiError("database update", { response: { data: response.data } }, [
7831
+ `Project: ${projectName}`,
7832
+ `Endpoint: ${apiUrl}`
7833
+ ], [
7834
+ "Inspect the SQL result list above to identify the failing migration file."
7835
+ ]);
7836
+ }
7837
+ } catch (error) {
7838
+ throw createApiError("database update", error, [
7839
+ `Project: ${projectName}`,
7840
+ `Endpoint: ${apiUrl}`
7841
+ ], [
7842
+ "Validate the SQL syntax and check whether any migration is re-applying an existing schema change."
7843
+ ]);
7844
+ }
7845
+ }
7846
+ async function updateDbCmd(options) {
7847
+ try {
7848
+ const headers = getAuthHeaders();
7849
+ if (!headers["authentication-tokens"] || !headers["token-address"]) {
7850
+ throw createConfigError("No valid local login session was found.", [
7851
+ "Run `pinme login` and retry."
7852
+ ]);
7853
+ }
7854
+ const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path13.default.join(PROJECT_DIR3, options.projectName || options.name) : PROJECT_DIR3;
7855
+ const tokenFileSrc = import_path13.default.join(PROJECT_DIR3, ".token.json");
7856
+ const tokenFileDst = import_path13.default.join(projectDir, ".token.json");
7857
+ if (import_fs_extra8.default.existsSync(tokenFileSrc) && !import_fs_extra8.default.existsSync(tokenFileDst)) {
7858
+ import_fs_extra8.default.copySync(tokenFileSrc, tokenFileDst);
7859
+ }
7860
+ console.log(import_chalk19.default.blue("Importing SQL to database...\n"));
7861
+ console.log(import_chalk19.default.gray(`Project dir: ${PROJECT_DIR3}`));
7862
+ const config = loadConfig2();
7863
+ const projectName = config.project_name;
7864
+ if (!projectName) {
7865
+ throw createConfigError("`project_name` is missing in `pinme.toml`.", [
7866
+ 'Set `project_name = "your-project-name"` in `pinme.toml`.'
7867
+ ]);
7868
+ }
7869
+ console.log(import_chalk19.default.gray(`Project: ${projectName}`));
7870
+ const sqlFiles = getSqlFiles2();
7871
+ console.log(import_chalk19.default.gray(`Found ${sqlFiles.length} SQL file(s) in db`));
7872
+ await updateDb(sqlFiles, projectName);
7873
+ console.log(import_chalk19.default.green("\nDatabase update complete."));
7874
+ process.exit(0);
7875
+ } catch (error) {
7876
+ printCliError(error, "Database update failed.");
7877
+ process.exit(1);
7878
+ }
7879
+ }
7880
+
7881
+ // bin/updateWorker.ts
7882
+ var import_chalk20 = __toESM(require("chalk"));
7883
+ var import_fs_extra9 = __toESM(require("fs-extra"));
7884
+ var import_path14 = __toESM(require("path"));
7885
+ var import_child_process4 = require("child_process");
7886
+ var PROJECT_DIR4 = process.cwd();
7887
+ var API_BASE4 = "https://pinme.benny1996.win/api/v4";
7888
+ function loadConfig3() {
7889
+ const configPath = import_path14.default.join(PROJECT_DIR4, "pinme.toml");
7890
+ if (!import_fs_extra9.default.existsSync(configPath)) {
7891
+ throw createConfigError("`pinme.toml` not found in the current directory.", [
7892
+ "Run this command from the Pinme project root."
7893
+ ]);
7894
+ }
7895
+ const configContent = import_fs_extra9.default.readFileSync(configPath, "utf-8");
7896
+ const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
7897
+ return {
7898
+ project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
7899
+ };
7900
+ }
7901
+ function getMetadata2() {
7902
+ const metadataPath = import_path14.default.join(PROJECT_DIR4, "backend", "metadata.json");
7903
+ if (!import_fs_extra9.default.existsSync(metadataPath)) {
7904
+ throw createConfigError("`backend/metadata.json` not found.", [
7905
+ "Create `backend/metadata.json` or restore it from the project template."
7906
+ ]);
7907
+ }
7908
+ return import_fs_extra9.default.readJsonSync(metadataPath);
7909
+ }
7910
+ function buildWorker2() {
7911
+ console.log(import_chalk20.default.blue("Building worker..."));
7912
+ try {
7913
+ (0, import_child_process4.execSync)("npm run build:worker", {
7914
+ cwd: PROJECT_DIR4,
7915
+ stdio: "inherit"
7916
+ });
7917
+ console.log(import_chalk20.default.green("Worker built"));
7918
+ } catch (error) {
7919
+ throw createCommandError("worker build", "npm run build:worker", error, [
7920
+ "Fix the build error shown above, then rerun `pinme update-worker`."
7921
+ ]);
7922
+ }
7923
+ }
7924
+ function getBuiltWorker2() {
7925
+ const distWorkerDir = import_path14.default.join(PROJECT_DIR4, "dist-worker");
7926
+ if (!import_fs_extra9.default.existsSync(distWorkerDir)) {
7927
+ throw createConfigError("Built worker output not found: `dist-worker/`.", [
7928
+ "Make sure `npm run build:worker` completed successfully."
7929
+ ]);
7930
+ }
7931
+ const workerJsPath = import_path14.default.join(distWorkerDir, "worker.js");
7932
+ if (!import_fs_extra9.default.existsSync(workerJsPath)) {
7933
+ throw createConfigError("Built worker entry file not found: `dist-worker/worker.js`.", [
7934
+ "Check the worker build output and bundler config."
7935
+ ]);
7936
+ }
7937
+ const modulePaths = [];
7938
+ const files = import_fs_extra9.default.readdirSync(distWorkerDir);
7939
+ for (const file of files) {
7940
+ if (file.endsWith(".js") && file !== "worker.js") {
7941
+ modulePaths.push(import_path14.default.join(distWorkerDir, file));
7942
+ }
7943
+ }
7944
+ return { workerJsPath, modulePaths };
7945
+ }
7946
+ async function updateWorker(workerJsPath, modulePaths, metadata, projectName) {
7947
+ console.log(import_chalk20.default.blue("Updating worker on platform..."));
7948
+ console.log(import_chalk20.default.gray(`Project: ${projectName}`));
7949
+ console.log(import_chalk20.default.gray(`workerJsPath: ${workerJsPath}`));
7950
+ console.log(import_chalk20.default.gray(`modulePaths: ${modulePaths}`));
7951
+ console.log(import_chalk20.default.gray(`metadata: ${metadata}`));
7952
+ const apiUrl = `${API_BASE4}/update_worker?project_name=${encodeURIComponent(projectName)}`;
7953
+ const headers = getAuthHeaders();
7954
+ console.log(import_chalk20.default.gray(`API URL: ${apiUrl}`));
7955
+ try {
7956
+ const FormData4 = (await import("formdata-node")).FormData;
7957
+ const Blob2 = (await import("formdata-node")).Blob;
7958
+ const formData = new FormData4();
7959
+ formData.append("metadata", new Blob2([JSON.stringify(metadata)], {
7960
+ type: "application/json"
7961
+ }), "metadata.json");
7962
+ const workerCode = import_fs_extra9.default.readFileSync(workerJsPath, "utf-8");
7963
+ formData.append("worker.js", new Blob2([workerCode], {
7964
+ type: "application/javascript+module"
7965
+ }), "worker.js");
7966
+ for (const modulePath of modulePaths) {
7967
+ const filename = import_path14.default.basename(modulePath);
7968
+ const content = import_fs_extra9.default.readFileSync(modulePath, "utf-8");
7969
+ formData.append(filename, new Blob2([content], {
7970
+ type: "application/javascript+module"
7971
+ }), filename);
7972
+ }
7973
+ const response = await axios_default.put(apiUrl, formData, {
7974
+ headers: { ...headers },
7975
+ timeout: 12e4
7976
+ });
7977
+ console.log(import_chalk20.default.gray(` Response: ${JSON.stringify(response.data)}`));
7978
+ if (response.data) {
7979
+ console.log(import_chalk20.default.green("Worker updated"));
7980
+ const data = response.data.data;
7981
+ if (data.worker_id) {
7982
+ console.log(import_chalk20.default.gray(` Worker ID: ${data.worker_id}`));
7983
+ }
7984
+ if (data.deployment_id) {
7985
+ console.log(import_chalk20.default.gray(` Deployment ID: ${data.deployment_id}`));
7986
+ }
7987
+ if (data.entry_point) {
7988
+ console.log(import_chalk20.default.gray(` Entry Point: ${data.entry_point}`));
7989
+ }
7990
+ if (data.created_on) {
7991
+ console.log(import_chalk20.default.gray(` Created: ${data.created_on}`));
7992
+ }
7993
+ if (data.modified_on) {
7994
+ console.log(import_chalk20.default.gray(` Modified: ${data.modified_on}`));
7995
+ }
7996
+ if (data.startup_time_ms !== void 0) {
7997
+ console.log(import_chalk20.default.gray(` Startup Time: ${data.startup_time_ms}ms`));
7998
+ }
7999
+ if (data.has_modules !== void 0) {
8000
+ console.log(import_chalk20.default.gray(` Has Modules: ${data.has_modules}`));
8001
+ }
8002
+ if (data.domain) {
8003
+ console.log(import_chalk20.default.gray(` Domain: ${data.domain}`));
8004
+ }
8005
+ } else {
8006
+ throw createApiError("worker update", { response: { data: response.data } }, [
8007
+ `Project: ${projectName}`,
8008
+ `Endpoint: ${apiUrl}`
8009
+ ], [
8010
+ "Verify the project exists and your account has permission to update it."
8011
+ ]);
8012
+ }
8013
+ } catch (error) {
8014
+ throw createApiError("worker update", error, [
8015
+ `Project: ${projectName}`,
8016
+ `Endpoint: ${apiUrl}`
8017
+ ], [
8018
+ "Check whether `backend/metadata.json` and the built worker bundle are valid."
8019
+ ]);
8020
+ }
8021
+ }
8022
+ async function updateWorkerCmd(options) {
8023
+ try {
8024
+ const headers = getAuthHeaders();
8025
+ if (!headers["authentication-tokens"] || !headers["token-address"]) {
8026
+ throw createConfigError("No valid local login session was found.", [
8027
+ "Run `pinme login` and retry."
8028
+ ]);
8029
+ }
8030
+ const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path14.default.join(PROJECT_DIR4, options.projectName || options.name) : PROJECT_DIR4;
8031
+ const tokenFileSrc = import_path14.default.join(PROJECT_DIR4, ".token.json");
8032
+ const tokenFileDst = import_path14.default.join(projectDir, ".token.json");
8033
+ if (import_fs_extra9.default.existsSync(tokenFileSrc) && !import_fs_extra9.default.existsSync(tokenFileDst)) {
8034
+ import_fs_extra9.default.copySync(tokenFileSrc, tokenFileDst);
8035
+ }
8036
+ console.log(import_chalk20.default.blue("Updating worker...\n"));
8037
+ console.log(import_chalk20.default.gray(`Project dir: ${PROJECT_DIR4}`));
8038
+ const config = loadConfig3();
8039
+ const projectName = config.project_name;
8040
+ if (!projectName) {
8041
+ throw createConfigError("`project_name` is missing in `pinme.toml`.", [
8042
+ 'Set `project_name = "your-project-name"` in `pinme.toml`.'
8043
+ ]);
8044
+ }
8045
+ console.log(import_chalk20.default.gray(`Project: ${projectName}`));
8046
+ console.log(import_chalk20.default.blue("\n--- Worker Update ---"));
8047
+ buildWorker2();
8048
+ const metadata = getMetadata2();
8049
+ const { workerJsPath, modulePaths } = getBuiltWorker2();
8050
+ console.log(import_chalk20.default.gray(`Worker JS: ${workerJsPath}`));
8051
+ console.log(import_chalk20.default.gray(`Module paths: ${JSON.stringify(modulePaths)}`));
8052
+ console.log(import_chalk20.default.gray(`SQL files: ignored (not processed for update_worker)`));
8053
+ await updateWorker(workerJsPath, modulePaths, metadata, projectName);
8054
+ console.log(import_chalk20.default.green("\nWorker update complete."));
8055
+ process.exit(0);
8056
+ } catch (error) {
8057
+ printCliError(error, "Worker update failed.");
8058
+ process.exit(1);
8059
+ }
8060
+ }
8061
+
8062
+ // bin/updateWeb.ts
8063
+ var import_chalk21 = __toESM(require("chalk"));
8064
+ var import_fs_extra10 = __toESM(require("fs-extra"));
8065
+ var import_path15 = __toESM(require("path"));
8066
+ var import_child_process5 = require("child_process");
8067
+ var PROJECT_DIR5 = process.cwd();
8068
+ function loadConfig4() {
8069
+ const configPath = import_path15.default.join(PROJECT_DIR5, "pinme.toml");
8070
+ if (!import_fs_extra10.default.existsSync(configPath)) {
8071
+ throw createConfigError("`pinme.toml` not found in the current directory.", [
8072
+ "Run this command from the Pinme project root."
8073
+ ]);
8074
+ }
8075
+ const configContent = import_fs_extra10.default.readFileSync(configPath, "utf-8");
8076
+ const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
8077
+ return {
8078
+ project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
8079
+ };
8080
+ }
8081
+ function buildFrontend2() {
8082
+ console.log(import_chalk21.default.blue("Building frontend..."));
8083
+ try {
8084
+ (0, import_child_process5.execSync)("npm run build:frontend", {
8085
+ cwd: PROJECT_DIR5,
8086
+ stdio: "inherit"
8087
+ });
8088
+ console.log(import_chalk21.default.green("Frontend built"));
8089
+ } catch (error) {
8090
+ throw createCommandError("frontend build", "npm run build:frontend", error, [
8091
+ "Fix the frontend build error shown above, then rerun `pinme update-web`."
8092
+ ]);
8093
+ }
8094
+ }
8095
+ function deployFrontend2(projectName) {
8096
+ console.log(import_chalk21.default.blue("Deploying frontend to IPFS..."));
8097
+ try {
8098
+ (0, import_child_process5.execSync)("pinme upload ./frontend/dist", {
8099
+ cwd: PROJECT_DIR5,
8100
+ stdio: "inherit",
8101
+ env: {
8102
+ ...process.env,
8103
+ PINME_PROJECT_NAME: projectName
8104
+ }
8105
+ });
8106
+ console.log(import_chalk21.default.green("Frontend deployed to IPFS"));
8107
+ } catch (error) {
8108
+ throw createCommandError("frontend deploy", "pinme upload ./frontend/dist", error, [
8109
+ "Make sure `frontend/dist` exists and `pinme upload` can run successfully."
8110
+ ]);
8111
+ }
8112
+ }
8113
+ async function updateWebCmd(options) {
8114
+ try {
8115
+ const headers = getAuthHeaders();
8116
+ if (!headers["authentication-tokens"] || !headers["token-address"]) {
8117
+ throw createConfigError("No valid local login session was found.", [
8118
+ "Run `pinme login` and retry."
8119
+ ]);
8120
+ }
8121
+ const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path15.default.join(PROJECT_DIR5, options.projectName || options.name) : PROJECT_DIR5;
8122
+ const tokenFileSrc = import_path15.default.join(PROJECT_DIR5, ".token.json");
8123
+ const tokenFileDst = import_path15.default.join(projectDir, ".token.json");
8124
+ if (import_fs_extra10.default.existsSync(tokenFileSrc) && !import_fs_extra10.default.existsSync(tokenFileDst)) {
8125
+ import_fs_extra10.default.copySync(tokenFileSrc, tokenFileDst);
8126
+ }
8127
+ console.log(import_chalk21.default.blue("Updating web (frontend)...\n"));
8128
+ console.log(import_chalk21.default.gray(`Project dir: ${PROJECT_DIR5}`));
8129
+ const config = loadConfig4();
8130
+ const projectName = config.project_name;
8131
+ if (!projectName) {
8132
+ throw createConfigError("`project_name` is missing in `pinme.toml`.", [
8133
+ 'Set `project_name = "your-project-name"` in `pinme.toml`.'
8134
+ ]);
8135
+ }
8136
+ console.log(import_chalk21.default.gray(`Project: ${projectName}`));
8137
+ console.log(import_chalk21.default.blue("\n--- Frontend Update ---"));
8138
+ buildFrontend2();
8139
+ deployFrontend2(projectName);
8140
+ console.log(import_chalk21.default.green("\nWeb update complete."));
8141
+ process.exit(0);
8142
+ } catch (error) {
8143
+ printCliError(error, "Web update failed.");
8144
+ process.exit(1);
8145
+ }
8146
+ }
8147
+
8148
+ // bin/delete.ts
8149
+ var import_chalk22 = __toESM(require("chalk"));
8150
+ var import_inquirer9 = __toESM(require("inquirer"));
8151
+ var import_fs_extra11 = __toESM(require("fs-extra"));
8152
+ var import_path16 = __toESM(require("path"));
8153
+ var API_BASE5 = "https://pinme.benny1996.win/api/v4";
8154
+ function getProjectName() {
8155
+ const configPath = import_path16.default.join(process.cwd(), "pinme.toml");
8156
+ if (!import_fs_extra11.default.existsSync(configPath)) {
8157
+ return null;
8158
+ }
8159
+ const config = import_fs_extra11.default.readFileSync(configPath, "utf-8");
8160
+ const match = config.match(/project_name\s*=\s*"([^"]+)"/);
8161
+ return (match == null ? void 0 : match[1]) || null;
8162
+ }
8163
+ async function deleteCmd(options) {
8164
+ var _a, _b;
8165
+ try {
8166
+ const headers = getAuthHeaders();
8167
+ if (!headers["authentication-tokens"] || !headers["token-address"]) {
8168
+ console.log(import_chalk22.default.yellow("\n\u26A0\uFE0F You are not logged in."));
8169
+ console.log(import_chalk22.default.gray("Please run: pinme login"));
8170
+ process.exit(1);
8171
+ }
8172
+ console.log(import_chalk22.default.blue("Deleting project...\n"));
8173
+ let projectName = options.name || getProjectName();
8174
+ if (!projectName) {
8175
+ console.log(import_chalk22.default.red("\n\u274C Error: Cannot find project name."));
8176
+ console.log(import_chalk22.default.yellow(" Please make sure you are in the project directory."));
8177
+ console.log(import_chalk22.default.gray(" The project directory should contain a pinme.toml file."));
8178
+ console.log(import_chalk22.default.gray("\n Or specify the project name:"));
8179
+ console.log(import_chalk22.default.gray(" cd /path/to/your-project"));
8180
+ console.log(import_chalk22.default.gray(" pinme delete"));
8181
+ process.exit(1);
8182
+ }
8183
+ console.log(import_chalk22.default.gray(`Project: ${projectName}`));
8184
+ console.log(import_chalk22.default.gray(`Directory: ${process.cwd()}`));
8185
+ if (!options.force) {
8186
+ const answers = await import_inquirer9.default.prompt([
8187
+ {
8188
+ type: "confirm",
8189
+ name: "confirm",
8190
+ message: `Are you sure you want to delete project "${projectName}"? This will remove Worker, domain binding, and D1 database.`,
8191
+ default: false
8192
+ }
8193
+ ]);
8194
+ if (!answers.confirm) {
8195
+ console.log(import_chalk22.default.gray("Cancelled."));
8196
+ process.exit(0);
8197
+ }
8198
+ }
8199
+ console.log(import_chalk22.default.blue("Deleting project on platform..."));
8200
+ const apiUrl = `${API_BASE5}/delete_project`;
8201
+ console.log(import_chalk22.default.gray(`API URL: ${apiUrl}`));
8202
+ console.log(import_chalk22.default.gray(`Project name: ${projectName}`));
8203
+ const response = await axios_default.post(apiUrl, {
8204
+ project_name: projectName
8205
+ }, {
8206
+ headers: {
8207
+ ...headers,
8208
+ "Content-Type": "application/json"
8209
+ }
8210
+ }).catch((error) => {
8211
+ var _a2, _b2;
8212
+ if (error.response) {
8213
+ console.log(import_chalk22.default.red(` Response status: ${(_a2 = error.response) == null ? void 0 : _a2.status}`));
8214
+ console.log(import_chalk22.default.red(` Response data: ${JSON.stringify((_b2 = error.response) == null ? void 0 : _b2.data)}`));
8215
+ } else {
8216
+ console.log(import_chalk22.default.red("No Response"));
8217
+ }
8218
+ throw error;
8219
+ });
8220
+ const data = response.data;
8221
+ if (data.code === 200) {
8222
+ console.log(import_chalk22.default.green("\n\u2705 Project deleted successfully!"));
8223
+ console.log(import_chalk22.default.gray(`
8224
+ Project: ${data.data.project_name}`));
8225
+ console.log(import_chalk22.default.gray(` Domain deleted: ${data.data.domain_deleted ? "\u2705" : "\u274C"}`));
8226
+ console.log(import_chalk22.default.gray(` Worker deleted: ${data.data.worker_deleted ? "\u2705" : "\u274C"}`));
8227
+ console.log(import_chalk22.default.gray(` Database deleted: ${data.data.database_deleted ? "\u2705" : "\u274C"}`));
8228
+ console.log(import_chalk22.default.gray("\nLocal files are kept unchanged."));
8229
+ } else {
8230
+ const errorMsg = (data == null ? void 0 : data.msg) || "Failed to delete project";
8231
+ throw new Error(errorMsg);
8232
+ }
8233
+ process.exit(0);
8234
+ } catch (error) {
8235
+ console.log(import_chalk22.default.red(error));
8236
+ const errorMsg = ((_b = (_a = error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.msg) || error.message || "Failed to delete project";
8237
+ console.error(import_chalk22.default.red(`
8238
+ \u274C Error: ${errorMsg}`));
8239
+ process.exit(1);
6603
8240
  }
6604
8241
  }
6605
8242
 
@@ -6608,9 +8245,9 @@ import_dotenv.default.config();
6608
8245
  checkNodeVersion();
6609
8246
  function showBanner() {
6610
8247
  console.log(
6611
- import_chalk14.default.cyan(import_figlet5.default.textSync("Pinme", { horizontalLayout: "full" }))
8248
+ import_chalk23.default.cyan(import_figlet5.default.textSync("Pinme", { horizontalLayout: "full" }))
6612
8249
  );
6613
- console.log(import_chalk14.default.cyan("A command-line tool for uploading files to IPFS\n"));
8250
+ console.log(import_chalk23.default.cyan("A command-line tool for uploading files to IPFS\n"));
6614
8251
  }
6615
8252
  var program = new import_commander.Command();
6616
8253
  program.name("pinme").version(version).option("-v, --version", "output the current version");
@@ -6620,13 +8257,20 @@ program.command("upload").description(
6620
8257
  program.command("import").description("import a CAR file to IPFS. Supports --domain to bind after import").option("-d, --domain <name>", "Pinme subdomain").action(() => importCar_default());
6621
8258
  program.command("export").description("export IPFS content as CAR file").option("-o, --output <path>", "output file path for CAR file").action(() => exportCar_default());
6622
8259
  program.command("rm").description("remove a file from IPFS network").action(() => remove_default());
8260
+ program.command("login").description("Login via browser (opens web login page)").option("-e, --env <env>", "Environment: test, prod").action((options) => loginCmd(options));
6623
8261
  program.command("set-appkey").description(
6624
- "Set AppKey for authentication, and auto-merge anonymous history"
8262
+ "Set AppKey for authentication (alternative to login command)"
6625
8263
  ).action(() => setAppKeyCmd());
6626
8264
  program.command("logout").description("log out and clear authentication").action(() => logoutCmd());
6627
8265
  program.command("show-appkey").alias("appkey").description("show current AppKey information (masked)").action(() => showAppKeyCmd());
6628
8266
  program.command("my-domains").alias("domain").description("List domains owned by current account").action(() => myDomainsCmd());
6629
8267
  program.command("bind").description("Upload and bind to a domain (requires VIP)").option("-d, --domain <name>", "Domain name to bind").option("--dns", "Force DNS domain mode").action(() => bindCmd());
8268
+ 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 }));
8269
+ program.command("save").description("Deploy the project (frontend + backend)").action((options) => saveCmd(options));
8270
+ program.command("update-db").description("Execute database migration").action(() => updateDbCmd());
8271
+ program.command("update-worker").description("Execute worker migration").action(() => updateWorkerCmd());
8272
+ program.command("update-web").description("Deploy frontend to IPFS").action((options) => updateWebCmd(options));
8273
+ program.command("delete").description("Delete a project (Worker, domain, D1 database)").argument("[name]", "Project name").option("-f, --force", "Skip confirmation").action((name, options) => deleteCmd({ name, force: options == null ? void 0 : options.force }));
6630
8274
  program.command("domain").description("Alias for 'my-domains' command").action(() => myDomainsCmd());
6631
8275
  program.command("list").description("show upload history").option(
6632
8276
  "-l, --limit <number>",
@@ -6663,6 +8307,7 @@ program.on("--help", () => {
6663
8307
  console.log(" $ pinme import <path> --domain <name>");
6664
8308
  console.log(" $ pinme export <cid> --output <path>");
6665
8309
  console.log(" $ pinme rm <hash>");
8310
+ console.log(" $ pinme login");
6666
8311
  console.log(" $ pinme set-appkey <AppKey>");
6667
8312
  console.log(" $ pinme show-appkey");
6668
8313
  console.log(" $ pinme logout");