pinme 1.1.5 → 1.1.6-alpha.2

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 (3) hide show
  1. package/README.md +13 -0
  2. package/dist/index.js +330 -89
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,3 +1,16 @@
1
+ <p align="center">
2
+ <a href="https://pinme.eth.limo/">
3
+ <img src="https://2egc5b44.pinit.eth.limo/" height="92">
4
+ <h3 align="center">PinMe</h3>
5
+ </a>
6
+ </p>
7
+
8
+ <p align="center">
9
+ Deploy your site in one command.
10
+ </p>
11
+
12
+ <br/>
13
+
1
14
  # PinMe
2
15
 
3
16
  [PinMe](https://pinme.eth.limo/) is a one-command deploy tool that turns static sites into permanent, verifiable frontends by pinning to [IPFS](https://ipfs.tech/), writing contenthash to [ENS](https://ens.domains/) subnames, and serving through gateways like [eth.limo](https://eth.limo/)—no DNS, no servers.
package/dist/index.js CHANGED
@@ -96,9 +96,9 @@ 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 fs6 = require("fs");
100
- var path6 = require("path");
101
- var os3 = require("os");
99
+ var fs7 = require("fs");
100
+ var path7 = require("path");
101
+ var os4 = require("os");
102
102
  var crypto2 = require("crypto");
103
103
  var packageJson = require_package();
104
104
  var version2 = packageJson.version;
@@ -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 (fs6.existsSync(filepath)) {
203
+ if (fs7.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 = path6.resolve(process.cwd(), ".env.vault");
211
+ possibleVaultPath = path7.resolve(process.cwd(), ".env.vault");
212
212
  }
213
- if (fs6.existsSync(possibleVaultPath)) {
213
+ if (fs7.existsSync(possibleVaultPath)) {
214
214
  return possibleVaultPath;
215
215
  }
216
216
  return null;
217
217
  }
218
218
  function _resolveHome(envPath) {
219
- return envPath[0] === "~" ? path6.join(os3.homedir(), envPath.slice(1)) : envPath;
219
+ return envPath[0] === "~" ? path7.join(os4.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 = path6.resolve(process.cwd(), ".env");
235
+ const dotenvPath = path7.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 path7 of optionPaths) {
258
+ for (const path8 of optionPaths) {
259
259
  try {
260
- const parsed = DotenvModule.parse(fs6.readFileSync(path7, { encoding }));
260
+ const parsed = DotenvModule.parse(fs7.readFileSync(path8, { encoding }));
261
261
  DotenvModule.populate(parsedAll, parsed, options);
262
262
  } catch (e) {
263
263
  if (debug) {
264
- _debug(`Failed to load ${path7} ${e.message}`);
264
+ _debug(`Failed to load ${path8} ${e.message}`);
265
265
  }
266
266
  lastError = e;
267
267
  }
@@ -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 os3 = require("os");
813
+ var os4 = 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 = os3.release().split(".");
851
+ const osRelease = os4.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
  }
@@ -1519,15 +1519,15 @@ function checkNodeVersion() {
1519
1519
 
1520
1520
  // bin/index.ts
1521
1521
  var import_commander = require("commander");
1522
- var import_chalk6 = __toESM(require("chalk"));
1522
+ var import_chalk9 = __toESM(require("chalk"));
1523
1523
  var import_figlet3 = __toESM(require("figlet"));
1524
1524
 
1525
1525
  // package.json
1526
- var version = "1.1.5";
1526
+ var version = "1.1.6-alpha.2";
1527
1527
 
1528
1528
  // bin/upload.ts
1529
- var import_path5 = __toESM(require("path"));
1530
- var import_chalk3 = __toESM(require("chalk"));
1529
+ var import_path6 = __toESM(require("path"));
1530
+ var import_chalk4 = __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(path6, key, dots) {
1972
- if (!path6) return key;
1973
- return path6.concat(key).map(function each(token, i) {
1971
+ function renderKey(path7, key, dots) {
1972
+ if (!path7) return key;
1973
+ return path7.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, path6) {
2018
+ function defaultVisitor(value, key, path7) {
2019
2019
  let arr = value;
2020
- if (value && !path6 && typeof value === "object") {
2020
+ if (value && !path7 && 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(path6, key, dots), convertValue(value));
2039
+ formData.append(renderKey(path7, 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, path6) {
2048
+ function build(value, path7) {
2049
2049
  if (utils_default.isUndefined(value)) return;
2050
2050
  if (stack.indexOf(value) !== -1) {
2051
- throw Error("Circular reference detected in " + path6.join("."));
2051
+ throw Error("Circular reference detected in " + path7.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
- path6,
2059
+ path7,
2060
2060
  exposedHelpers
2061
2061
  );
2062
2062
  if (result === true) {
2063
- build(el, path6 ? path6.concat(key) : [key]);
2063
+ build(el, path7 ? path7.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, path6, helpers) {
2224
+ visitor: function(value, key, path7, 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(path6, value, target, index) {
2254
- let name = path6[index++];
2253
+ function buildPath(path7, value, target, index) {
2254
+ let name = path7[index++];
2255
2255
  const isNumericKey = Number.isFinite(+name);
2256
- const isLast = index >= path6.length;
2256
+ const isLast = index >= path7.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(path6, value, target[name], index);
2269
+ const result = buildPath(path7, 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 path6;
3331
+ let path7;
3332
3332
  try {
3333
- path6 = buildURL(
3333
+ path7 = 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: path6,
3351
+ path: path7,
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, path6, domain, secure) {
3570
+ write: function write(name, value, expires, path7, 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(path6)) {
3577
- cookie.push("path=" + path6);
3576
+ if (utils_default.isString(path7)) {
3577
+ cookie.push("path=" + path7);
3578
3578
  }
3579
3579
  if (utils_default.isString(domain)) {
3580
3580
  cookie.push("domain=" + domain);
@@ -5060,6 +5060,131 @@ async function uploadToIpfsSplit_default(filePath) {
5060
5060
  // bin/upload.ts
5061
5061
  var import_fs2 = __toESM(require("fs"));
5062
5062
  var import_crypto_js = __toESM(require("crypto-js"));
5063
+
5064
+ // bin/utils/pinmeApi.ts
5065
+ var import_chalk3 = __toESM(require("chalk"));
5066
+
5067
+ // bin/utils/auth.ts
5068
+ var import_fs_extra4 = __toESM(require("fs-extra"));
5069
+ var import_os3 = __toESM(require("os"));
5070
+ var import_path5 = __toESM(require("path"));
5071
+ var CONFIG_DIR = import_path5.default.join(import_os3.default.homedir(), ".pinme");
5072
+ var AUTH_FILE = import_path5.default.join(CONFIG_DIR, "auth.json");
5073
+ function ensureConfigDir() {
5074
+ if (!import_fs_extra4.default.existsSync(CONFIG_DIR)) {
5075
+ import_fs_extra4.default.mkdirSync(CONFIG_DIR, { recursive: true });
5076
+ }
5077
+ }
5078
+ function parseCombinedToken(combined) {
5079
+ const firstDash = combined.indexOf("-");
5080
+ if (firstDash <= 0 || firstDash === combined.length - 1) {
5081
+ throw new Error('Invalid token format. Expected "<address>-<jwt>".');
5082
+ }
5083
+ const address = combined.slice(0, firstDash).trim();
5084
+ const token = combined.slice(firstDash + 1).trim();
5085
+ if (!address || !token) {
5086
+ throw new Error("Invalid token content. Address or token is empty.");
5087
+ }
5088
+ return { address, token };
5089
+ }
5090
+ function setAuthToken(combined) {
5091
+ ensureConfigDir();
5092
+ const auth = parseCombinedToken(combined);
5093
+ import_fs_extra4.default.writeJsonSync(AUTH_FILE, auth, { spaces: 2 });
5094
+ return auth;
5095
+ }
5096
+ function getAuthConfig() {
5097
+ try {
5098
+ if (!import_fs_extra4.default.existsSync(AUTH_FILE)) return null;
5099
+ const data = import_fs_extra4.default.readJsonSync(AUTH_FILE);
5100
+ if (!(data == null ? void 0 : data.address) || !(data == null ? void 0 : data.token)) return null;
5101
+ return data;
5102
+ } catch {
5103
+ return null;
5104
+ }
5105
+ }
5106
+ function getAuthHeaders() {
5107
+ const conf = getAuthConfig();
5108
+ if (!conf) {
5109
+ throw new Error("Auth not set. Run: pinme set-appkey <AppKey>");
5110
+ }
5111
+ return {
5112
+ "token-address": conf.address,
5113
+ "authentication-tokens": conf.token
5114
+ };
5115
+ }
5116
+
5117
+ // bin/utils/pinmeApi.ts
5118
+ var DEFAULT_BASE = process.env.PINME_API_BASE || "http://ipfs-proxy.opena.chat/api/v4";
5119
+ function createClient() {
5120
+ const headers = getAuthHeaders();
5121
+ return axios_default.create({
5122
+ baseURL: DEFAULT_BASE,
5123
+ timeout: 2e4,
5124
+ headers: {
5125
+ ...headers,
5126
+ Accept: "*/*",
5127
+ "Content-Type": "application/json",
5128
+ "User-Agent": "Pinme-CLI",
5129
+ Connection: "keep-alive"
5130
+ }
5131
+ });
5132
+ }
5133
+ async function bindAnonymousDevice(anonymousUid) {
5134
+ try {
5135
+ const client = createClient();
5136
+ const { data } = await client.post("/bind_anonymous", {
5137
+ anonymous_uid: anonymousUid
5138
+ });
5139
+ return (data == null ? void 0 : data.code) === 200;
5140
+ } catch (e) {
5141
+ console.log(import_chalk3.default.yellow(`Failed to trigger anonymous binding: ${(e == null ? void 0 : e.message) || e}`));
5142
+ return false;
5143
+ }
5144
+ }
5145
+ async function checkDomainAvailable(domainName) {
5146
+ var _a;
5147
+ const client = createClient();
5148
+ const configured = process.env.PINME_CHECK_DOMAIN_PATH || "/check_domain";
5149
+ const fallbacks = [configured, "/check_domain_available"];
5150
+ for (const p of fallbacks) {
5151
+ try {
5152
+ const { data } = await client.post(p, { domain_name: domainName });
5153
+ if (typeof (data == null ? void 0 : data.is_valid) === "boolean") {
5154
+ return { is_valid: data.is_valid, error: data == null ? void 0 : data.error };
5155
+ }
5156
+ if ((data == null ? void 0 : data.data) && typeof data.data.is_valid === "boolean") {
5157
+ return { is_valid: data.data.is_valid, error: (_a = data.data) == null ? void 0 : _a.error };
5158
+ }
5159
+ } catch (e) {
5160
+ }
5161
+ }
5162
+ return { is_valid: true };
5163
+ }
5164
+ async function bindPinmeDomain(domainName, hash) {
5165
+ const client = createClient();
5166
+ const { data } = await client.post("/bind_pinme_domain", {
5167
+ domain_name: domainName,
5168
+ hash
5169
+ });
5170
+ return (data == null ? void 0 : data.code) === 200;
5171
+ }
5172
+ async function getMyDomains() {
5173
+ var _a;
5174
+ const client = createClient();
5175
+ const { data } = await client.get("/my_domains");
5176
+ if ((data == null ? void 0 : data.code) === 200) {
5177
+ if (Array.isArray(data == null ? void 0 : data.data)) {
5178
+ return data.data;
5179
+ }
5180
+ if (((_a = data == null ? void 0 : data.data) == null ? void 0 : _a.list) && Array.isArray(data.data.list)) {
5181
+ return data.data.list;
5182
+ }
5183
+ }
5184
+ return [];
5185
+ }
5186
+
5187
+ // bin/upload.ts
5063
5188
  var URL2 = "https://pinme.eth.limo/#/preview/";
5064
5189
  var secretKey = "pinme-secret-key";
5065
5190
  checkNodeVersion();
@@ -5078,16 +5203,24 @@ function encryptHash(hash, key) {
5078
5203
  }
5079
5204
  function checkPathSync(inputPath) {
5080
5205
  try {
5081
- const absolutePath = import_path5.default.resolve(inputPath);
5206
+ const absolutePath = import_path6.default.resolve(inputPath);
5082
5207
  if (import_fs2.default.existsSync(absolutePath)) {
5083
5208
  return absolutePath;
5084
5209
  }
5085
5210
  return null;
5086
5211
  } catch (error) {
5087
- console.error(import_chalk3.default.red(`error checking path: ${error.message}`));
5212
+ console.error(import_chalk4.default.red(`error checking path: ${error.message}`));
5088
5213
  return null;
5089
5214
  }
5090
5215
  }
5216
+ function getDomainFromArgs() {
5217
+ const args = process.argv.slice(2);
5218
+ const dIdx = args.findIndex((a) => a === "--domain" || a === "-d");
5219
+ if (dIdx >= 0 && args[dIdx + 1] && !args[dIdx + 1].startsWith("-")) {
5220
+ return String(args[dIdx + 1]).trim();
5221
+ }
5222
+ return null;
5223
+ }
5091
5224
  var upload_default = async (options) => {
5092
5225
  try {
5093
5226
  console.log(
@@ -5100,28 +5233,47 @@ var upload_default = async (options) => {
5100
5233
  })
5101
5234
  );
5102
5235
  const argPath = process.argv[3];
5236
+ const domainArg = getDomainFromArgs();
5103
5237
  if (argPath && !argPath.startsWith("-")) {
5104
5238
  const absolutePath = checkPathSync(argPath);
5105
5239
  if (!absolutePath) {
5106
- console.log(import_chalk3.default.red(`path ${argPath} does not exist`));
5240
+ console.log(import_chalk4.default.red(`path ${argPath} does not exist`));
5107
5241
  return;
5108
5242
  }
5109
- console.log(import_chalk3.default.blue(`uploading ${absolutePath} to ipfs...`));
5243
+ if (domainArg) {
5244
+ const check = await checkDomainAvailable(domainArg);
5245
+ if (!check.is_valid) {
5246
+ console.log(import_chalk4.default.red(`Domain not available: ${check.error || "unknown reason"}`));
5247
+ return;
5248
+ }
5249
+ console.log(import_chalk4.default.green(`Domain available: ${domainArg}`));
5250
+ }
5251
+ console.log(import_chalk4.default.blue(`uploading ${absolutePath} to ipfs...`));
5110
5252
  try {
5111
5253
  const result = await uploadToIpfsSplit_default(absolutePath);
5112
5254
  if (result) {
5113
5255
  const encryptedCID = encryptHash(result.contentHash, secretKey);
5114
5256
  console.log(
5115
- import_chalk3.default.cyan(
5257
+ import_chalk4.default.cyan(
5116
5258
  import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
5117
5259
  )
5118
5260
  );
5119
- console.log(import_chalk3.default.cyan(`URL:`));
5120
- console.log(import_chalk3.default.cyan(`${URL2}${encryptedCID}`));
5121
- console.log(import_chalk3.default.green("\n\u{1F389} upload successful, program exit"));
5261
+ console.log(import_chalk4.default.cyan(`URL:`));
5262
+ console.log(import_chalk4.default.cyan(`${URL2}${encryptedCID}`));
5263
+ if (domainArg) {
5264
+ console.log(import_chalk4.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
5265
+ const ok = await bindPinmeDomain(domainArg, result.contentHash);
5266
+ if (ok) {
5267
+ console.log(import_chalk4.default.green(`Bind success: ${domainArg}`));
5268
+ console.log(import_chalk4.default.white(`Visit (Pinme subdomain example): https://${domainArg}.pinit.eth.limo`));
5269
+ } else {
5270
+ console.log(import_chalk4.default.red("Binding failed. Please try again later."));
5271
+ }
5272
+ }
5273
+ console.log(import_chalk4.default.green("\n\u{1F389} upload successful, program exit"));
5122
5274
  }
5123
5275
  } catch (error) {
5124
- console.error(import_chalk3.default.red(`Error: ${error.message}`));
5276
+ console.error(import_chalk4.default.red(`Error: ${error.message}`));
5125
5277
  }
5126
5278
  process.exit(0);
5127
5279
  }
@@ -5135,46 +5287,64 @@ var upload_default = async (options) => {
5135
5287
  if (answer.path) {
5136
5288
  const absolutePath = checkPathSync(answer.path);
5137
5289
  if (!absolutePath) {
5138
- console.log(import_chalk3.default.red(`path ${answer.path} does not exist`));
5290
+ console.log(import_chalk4.default.red(`path ${answer.path} does not exist`));
5139
5291
  return;
5140
5292
  }
5141
- console.log(import_chalk3.default.blue(`uploading ${absolutePath} to ipfs...`));
5293
+ if (domainArg) {
5294
+ const check = await checkDomainAvailable(domainArg);
5295
+ if (!check.is_valid) {
5296
+ console.log(import_chalk4.default.red(`Domain not available: ${check.error || "unknown reason"}`));
5297
+ return;
5298
+ }
5299
+ console.log(import_chalk4.default.green(`Domain available: ${domainArg}`));
5300
+ }
5301
+ console.log(import_chalk4.default.blue(`uploading ${absolutePath} to ipfs...`));
5142
5302
  try {
5143
5303
  const result = await uploadToIpfsSplit_default(absolutePath);
5144
5304
  if (result) {
5145
5305
  const encryptedCID = encryptHash(result.contentHash, secretKey);
5146
5306
  console.log(
5147
- import_chalk3.default.cyan(
5307
+ import_chalk4.default.cyan(
5148
5308
  import_figlet.default.textSync("Successful", { horizontalLayout: "full" })
5149
5309
  )
5150
5310
  );
5151
- console.log(import_chalk3.default.cyan(`URL:`));
5152
- console.log(import_chalk3.default.cyan(`${URL2}${encryptedCID}`));
5153
- console.log(import_chalk3.default.green("\n\u{1F389} upload successful, program exit"));
5311
+ console.log(import_chalk4.default.cyan(`URL:`));
5312
+ console.log(import_chalk4.default.cyan(`${URL2}${encryptedCID}`));
5313
+ if (domainArg) {
5314
+ console.log(import_chalk4.default.blue(`Binding domain: ${domainArg} with CID: ${result.contentHash}`));
5315
+ const ok = await bindPinmeDomain(domainArg, result.contentHash);
5316
+ if (ok) {
5317
+ console.log(import_chalk4.default.green(`Bind success: ${domainArg}`));
5318
+ console.log(import_chalk4.default.white(`Visit (Pinme subdomain example): https://${domainArg}.pinit.eth.limo`));
5319
+ } else {
5320
+ console.log(import_chalk4.default.red("Binding failed. Please try again later."));
5321
+ }
5322
+ }
5323
+ console.log(import_chalk4.default.green("\n\u{1F389} upload successful, program exit"));
5154
5324
  }
5155
5325
  } catch (error) {
5156
- console.error(import_chalk3.default.red(`Error: ${error.message}`));
5326
+ console.error(import_chalk4.default.red(`Error: ${error.message}`));
5157
5327
  }
5158
5328
  process.exit(0);
5159
5329
  }
5160
5330
  } catch (error) {
5161
- console.error(import_chalk3.default.red(`error executing: ${error.message}`));
5331
+ console.error(import_chalk4.default.red(`error executing: ${error.message}`));
5162
5332
  console.error(error.stack);
5163
5333
  }
5164
5334
  };
5165
5335
 
5166
5336
  // bin/remove.ts
5167
- var import_chalk5 = __toESM(require("chalk"));
5337
+ var import_chalk6 = __toESM(require("chalk"));
5168
5338
  var import_inquirer2 = __toESM(require("inquirer"));
5169
5339
  var import_figlet2 = __toESM(require("figlet"));
5170
5340
 
5171
5341
  // bin/utils/removeFromIpfs.ts
5172
- var import_chalk4 = __toESM(require("chalk"));
5342
+ var import_chalk5 = __toESM(require("chalk"));
5173
5343
  var ipfsApiUrl = "https://pinme.dev/api/v3";
5174
5344
  async function removeFromIpfs(value, type = "hash") {
5175
5345
  try {
5176
5346
  const uid = getDeviceId();
5177
- console.log(import_chalk4.default.blue(`Removing content from IPFS: ${value}...`));
5347
+ console.log(import_chalk5.default.blue(`Removing content from IPFS: ${value}...`));
5178
5348
  const queryParams = new URLSearchParams({
5179
5349
  uid
5180
5350
  });
@@ -5189,31 +5359,31 @@ async function removeFromIpfs(value, type = "hash") {
5189
5359
  });
5190
5360
  const { code, msg, data } = response.data;
5191
5361
  if (code === 200) {
5192
- console.log(import_chalk4.default.green("\u2713 Removal successful!"));
5193
- console.log(import_chalk4.default.cyan(`Content ${type}: ${value} has been removed from IPFS network`));
5362
+ console.log(import_chalk5.default.green("\u2713 Removal successful!"));
5363
+ console.log(import_chalk5.default.cyan(`Content ${type}: ${value} has been removed from IPFS network`));
5194
5364
  return true;
5195
5365
  } else {
5196
- console.log(import_chalk4.default.red("\u2717 Removal failed"));
5197
- console.log(import_chalk4.default.red(`Error: ${msg || "Unknown error occurred"}`));
5366
+ console.log(import_chalk5.default.red("\u2717 Removal failed"));
5367
+ console.log(import_chalk5.default.red(`Error: ${msg || "Unknown error occurred"}`));
5198
5368
  return false;
5199
5369
  }
5200
5370
  } catch (error) {
5201
- console.log(import_chalk4.default.red("\u2717 Removal failed", error));
5371
+ console.log(import_chalk5.default.red("\u2717 Removal failed", error));
5202
5372
  if (error.response) {
5203
5373
  const { status, data } = error.response;
5204
- console.log(import_chalk4.default.red(`HTTP Error ${status}: ${(data == null ? void 0 : data.msg) || "Server error"}`));
5374
+ console.log(import_chalk5.default.red(`HTTP Error ${status}: ${(data == null ? void 0 : data.msg) || "Server error"}`));
5205
5375
  if (status === 404) {
5206
- console.log(import_chalk4.default.yellow("Content not found on the network or already removed"));
5376
+ console.log(import_chalk5.default.yellow("Content not found on the network or already removed"));
5207
5377
  } else if (status === 403) {
5208
- console.log(import_chalk4.default.yellow("Permission denied - you may not have access to remove this content"));
5378
+ console.log(import_chalk5.default.yellow("Permission denied - you may not have access to remove this content"));
5209
5379
  } else if (status === 500) {
5210
- console.log(import_chalk4.default.yellow("Server internal error - please try again later"));
5380
+ console.log(import_chalk5.default.yellow("Server internal error - please try again later"));
5211
5381
  }
5212
5382
  } else if (error.request) {
5213
- console.log(import_chalk4.default.red("Network error: Unable to connect to IPFS service"));
5214
- console.log(import_chalk4.default.yellow("Please check your internet connection and try again"));
5383
+ console.log(import_chalk5.default.red("Network error: Unable to connect to IPFS service"));
5384
+ console.log(import_chalk5.default.yellow("Please check your internet connection and try again"));
5215
5385
  } else {
5216
- console.log(import_chalk4.default.red(`Error: ${error.message}`));
5386
+ console.log(import_chalk5.default.red(`Error: ${error.message}`));
5217
5387
  }
5218
5388
  return false;
5219
5389
  }
@@ -5273,30 +5443,30 @@ var remove_default = async (options) => {
5273
5443
  if (argHash && !argHash.startsWith("-")) {
5274
5444
  const parsedInput = parseInput(argHash);
5275
5445
  if (!parsedInput) {
5276
- console.log(import_chalk5.default.red(`Invalid input format: ${argHash}`));
5277
- console.log(import_chalk5.default.yellow("Supported formats:"));
5278
- console.log(import_chalk5.default.yellow(" - IPFS hash: bafybeig..."));
5279
- console.log(import_chalk5.default.yellow(" - Full URL: https://bafybeig....pinme.dev"));
5280
- console.log(import_chalk5.default.yellow(" - Subname: 3abt6ztu"));
5281
- console.log(import_chalk5.default.yellow(" - Subname URL: https://3abt6ztu.pinit.eth.limo"));
5446
+ console.log(import_chalk6.default.red(`Invalid input format: ${argHash}`));
5447
+ console.log(import_chalk6.default.yellow("Supported formats:"));
5448
+ console.log(import_chalk6.default.yellow(" - IPFS hash: bafybeig..."));
5449
+ console.log(import_chalk6.default.yellow(" - Full URL: https://bafybeig....pinme.dev"));
5450
+ console.log(import_chalk6.default.yellow(" - Subname: 3abt6ztu"));
5451
+ console.log(import_chalk6.default.yellow(" - Subname URL: https://3abt6ztu.pinit.eth.limo"));
5282
5452
  return;
5283
5453
  }
5284
5454
  try {
5285
5455
  const success = await removeFromIpfs(parsedInput.value, parsedInput.type);
5286
5456
  if (success) {
5287
5457
  console.log(
5288
- import_chalk5.default.cyan(
5458
+ import_chalk6.default.cyan(
5289
5459
  import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
5290
5460
  )
5291
5461
  );
5292
5462
  }
5293
5463
  } catch (error) {
5294
- console.error(import_chalk5.default.red(`Error: ${error.message}`));
5464
+ console.error(import_chalk6.default.red(`Error: ${error.message}`));
5295
5465
  }
5296
5466
  return;
5297
5467
  }
5298
- console.log(import_chalk5.default.yellow("\u26A0\uFE0F Warning: This action will permanently remove the content from IPFS network"));
5299
- console.log(import_chalk5.default.yellow("\u26A0\uFE0F Make sure you have the correct IPFS hash"));
5468
+ console.log(import_chalk6.default.yellow("\u26A0\uFE0F Warning: This action will permanently remove the content from IPFS network"));
5469
+ console.log(import_chalk6.default.yellow("\u26A0\uFE0F Make sure you have the correct IPFS hash"));
5300
5470
  console.log("");
5301
5471
  const confirmAnswer = await import_inquirer2.default.prompt([
5302
5472
  {
@@ -5307,7 +5477,7 @@ var remove_default = async (options) => {
5307
5477
  }
5308
5478
  ]);
5309
5479
  if (!confirmAnswer.confirm) {
5310
- console.log(import_chalk5.default.yellow("Operation cancelled"));
5480
+ console.log(import_chalk6.default.yellow("Operation cancelled"));
5311
5481
  return;
5312
5482
  }
5313
5483
  const answer = await import_inquirer2.default.prompt([
@@ -5330,7 +5500,7 @@ var remove_default = async (options) => {
5330
5500
  if (answer.input) {
5331
5501
  const parsedInput = parseInput(answer.input.trim());
5332
5502
  if (!parsedInput) {
5333
- console.log(import_chalk5.default.red("Invalid input format"));
5503
+ console.log(import_chalk6.default.red("Invalid input format"));
5334
5504
  return;
5335
5505
  }
5336
5506
  const finalConfirm = await import_inquirer2.default.prompt([
@@ -5342,43 +5512,110 @@ var remove_default = async (options) => {
5342
5512
  }
5343
5513
  ]);
5344
5514
  if (!finalConfirm.confirm) {
5345
- console.log(import_chalk5.default.yellow("Operation cancelled"));
5515
+ console.log(import_chalk6.default.yellow("Operation cancelled"));
5346
5516
  return;
5347
5517
  }
5348
5518
  try {
5349
5519
  const success = await removeFromIpfs(parsedInput.value, parsedInput.type);
5350
5520
  if (success) {
5351
5521
  console.log(
5352
- import_chalk5.default.cyan(
5522
+ import_chalk6.default.cyan(
5353
5523
  import_figlet2.default.textSync("Successful", { horizontalLayout: "full" })
5354
5524
  )
5355
5525
  );
5356
5526
  }
5357
5527
  } catch (error) {
5358
- console.error(import_chalk5.default.red(`Error: ${error.message}`));
5528
+ console.error(import_chalk6.default.red(`Error: ${error.message}`));
5359
5529
  }
5360
5530
  }
5361
5531
  } catch (error) {
5362
- console.error(import_chalk5.default.red(`Error executing remove command: ${error.message}`));
5532
+ console.error(import_chalk6.default.red(`Error executing remove command: ${error.message}`));
5363
5533
  console.error(error.stack);
5364
5534
  }
5365
5535
  };
5366
5536
 
5537
+ // bin/set-appkey.ts
5538
+ var import_chalk7 = __toESM(require("chalk"));
5539
+ var import_inquirer3 = __toESM(require("inquirer"));
5540
+ async function setAppKeyCmd() {
5541
+ try {
5542
+ const argAppKey = process.argv[3];
5543
+ let appKey = argAppKey;
5544
+ if (!appKey) {
5545
+ const ans = await import_inquirer3.default.prompt([
5546
+ {
5547
+ type: "input",
5548
+ name: "appKey",
5549
+ message: "Enter AppKey: "
5550
+ }
5551
+ ]);
5552
+ appKey = ans.appKey;
5553
+ }
5554
+ if (!appKey) {
5555
+ console.log(import_chalk7.default.red("AppKey not provided."));
5556
+ return;
5557
+ }
5558
+ const saved = setAuthToken(appKey);
5559
+ console.log(import_chalk7.default.green(`Auth set for address: ${saved.address}`));
5560
+ const deviceId = getDeviceId();
5561
+ const ok = await bindAnonymousDevice(deviceId);
5562
+ if (ok) {
5563
+ console.log(import_chalk7.default.green("Anonymous history merged to current account."));
5564
+ } else {
5565
+ console.log(import_chalk7.default.yellow("Anonymous history merge not confirmed. You may retry later."));
5566
+ }
5567
+ } catch (e) {
5568
+ console.log(import_chalk7.default.red(`Failed to set AppKey: ${(e == null ? void 0 : e.message) || e}`));
5569
+ }
5570
+ }
5571
+
5572
+ // bin/my-domains.ts
5573
+ var import_chalk8 = __toESM(require("chalk"));
5574
+ var import_dayjs2 = __toESM(require("dayjs"));
5575
+ async function myDomainsCmd() {
5576
+ try {
5577
+ const list = await getMyDomains();
5578
+ if (!list.length) {
5579
+ console.log(import_chalk8.default.yellow("No bound domains found."));
5580
+ return;
5581
+ }
5582
+ console.log(import_chalk8.default.cyan("My domains:"));
5583
+ console.log(import_chalk8.default.cyan("-".repeat(80)));
5584
+ list.forEach((item, i) => {
5585
+ console.log(import_chalk8.default.green(`${i + 1}. ${item.domain_name}`));
5586
+ console.log(import_chalk8.default.white(` Type: ${item.domain_type}`));
5587
+ if (item.bind_time) {
5588
+ console.log(import_chalk8.default.white(` Bind time: ${(0, import_dayjs2.default)(item.bind_time * 1e3).format("YYYY-MM-DD HH:mm:ss")}`));
5589
+ }
5590
+ if (typeof item.expire_time === "number") {
5591
+ const label = item.expire_time === 0 ? "Never" : (0, import_dayjs2.default)(item.expire_time * 1e3).format("YYYY-MM-DD HH:mm:ss");
5592
+ console.log(import_chalk8.default.white(` Expire time: ${label}`));
5593
+ }
5594
+ console.log(import_chalk8.default.cyan("-".repeat(80)));
5595
+ });
5596
+ } catch (e) {
5597
+ console.log(import_chalk8.default.red(`Failed to fetch domains: ${(e == null ? void 0 : e.message) || e}`));
5598
+ }
5599
+ }
5600
+
5367
5601
  // bin/index.ts
5368
5602
  import_dotenv.default.config();
5369
5603
  checkNodeVersion();
5370
5604
  function showBanner() {
5371
5605
  console.log(
5372
- import_chalk6.default.cyan(
5606
+ import_chalk9.default.cyan(
5373
5607
  import_figlet3.default.textSync("Pinme", { horizontalLayout: "full" })
5374
5608
  )
5375
5609
  );
5376
- console.log(import_chalk6.default.cyan("A command-line tool for uploading files to IPFS\n"));
5610
+ console.log(import_chalk9.default.cyan("A command-line tool for uploading files to IPFS\n"));
5377
5611
  }
5378
5612
  var program = new import_commander.Command();
5379
5613
  program.name("pinme").version(version).option("-v, --version", "output the current version");
5380
- program.command("upload").description("upload a file or directory to IPFS").action(() => upload_default());
5614
+ program.command("upload").description("upload a file or directory to IPFS. Supports --domain to bind after upload").option("-d, --domain <name>", "Pinme subdomain").action(() => upload_default());
5381
5615
  program.command("rm").description("remove a file from IPFS network").action(() => remove_default());
5616
+ program.command("set-appkey").description("Set AppKey for authentication, and auto-merge anonymous history").action(() => setAppKeyCmd());
5617
+ program.command("my-domains").alias("domain").description("List domains owned by current account").action(() => myDomainsCmd());
5618
+ program.command("domain").description("Alias for 'my-domains' command").action(() => myDomainsCmd());
5382
5619
  program.command("list").description("show upload history").option("-l, --limit <number>", "limit the number of records to show", parseInt).option("-c, --clear", "clear all upload history").action((options) => {
5383
5620
  if (options.clear) {
5384
5621
  clearUploadHistory();
@@ -5401,7 +5638,11 @@ program.on("--help", () => {
5401
5638
  console.log("");
5402
5639
  console.log("Examples:");
5403
5640
  console.log(" $ pinme upload");
5641
+ console.log(" $ pinme upload <path> --domain <name>");
5404
5642
  console.log(" $ pinme rm <hash>");
5643
+ console.log(" $ pinme set-appkey <AppKey>");
5644
+ console.log(" $ pinme my-domains");
5645
+ console.log(" $ pinme domain");
5405
5646
  console.log(" $ pinme list -l 5");
5406
5647
  console.log(" $ pinme ls");
5407
5648
  console.log(" $ pinme help");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinme",
3
- "version": "1.1.5",
3
+ "version": "1.1.6-alpha.2",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },