clishop 1.4.3 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +82 -78
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -776,11 +776,10 @@ Addresses for agent "${agent.name}":
|
|
|
776
776
|
|
|
777
777
|
// src/commands/payment.ts
|
|
778
778
|
import chalk5 from "chalk";
|
|
779
|
-
import
|
|
779
|
+
import ora3 from "ora";
|
|
780
780
|
|
|
781
781
|
// src/commands/setup.ts
|
|
782
782
|
import chalk4 from "chalk";
|
|
783
|
-
import ora3 from "ora";
|
|
784
783
|
import inquirer3 from "inquirer";
|
|
785
784
|
import open from "open";
|
|
786
785
|
import { execFileSync } from "child_process";
|
|
@@ -809,6 +808,16 @@ async function openBrowser(url) {
|
|
|
809
808
|
function divider(color = chalk4.cyan) {
|
|
810
809
|
console.log(" " + color("\u2500".repeat(48)));
|
|
811
810
|
}
|
|
811
|
+
function printSetupLink(message, setupUrl) {
|
|
812
|
+
console.log();
|
|
813
|
+
console.log(chalk4.bold(` ${message}`));
|
|
814
|
+
console.log();
|
|
815
|
+
console.log(" " + chalk4.cyan.underline(setupUrl));
|
|
816
|
+
console.log();
|
|
817
|
+
console.log(chalk4.dim(" Setup URL (plain text):"));
|
|
818
|
+
console.log(" " + setupUrl);
|
|
819
|
+
console.log();
|
|
820
|
+
}
|
|
812
821
|
function registerSetupCommand(program2) {
|
|
813
822
|
program2.command("setup").description(
|
|
814
823
|
"Set up your CLISHOP account \u2014 links your payment method via a secure browser link"
|
|
@@ -847,7 +856,7 @@ async function runSetupWizard(emailArg) {
|
|
|
847
856
|
console.log();
|
|
848
857
|
console.log(chalk4.bold.cyan(" W E L C O M E T O C L I S H O P"));
|
|
849
858
|
console.log(chalk4.dim(" Order anything from your terminal."));
|
|
850
|
-
console.log(chalk4.dim(` Build: ${"2026-04-
|
|
859
|
+
console.log(chalk4.dim(` Build: ${"2026-04-04T17:39:27.295Z"}`));
|
|
851
860
|
console.log();
|
|
852
861
|
divider(chalk4.cyan);
|
|
853
862
|
console.log();
|
|
@@ -878,7 +887,7 @@ async function runSetupWizard(emailArg) {
|
|
|
878
887
|
]);
|
|
879
888
|
email = answers.email;
|
|
880
889
|
}
|
|
881
|
-
|
|
890
|
+
console.log(chalk4.dim(" Creating your account and payment link..."));
|
|
882
891
|
let setupUrl;
|
|
883
892
|
let deviceCode;
|
|
884
893
|
try {
|
|
@@ -886,22 +895,22 @@ async function runSetupWizard(emailArg) {
|
|
|
886
895
|
const res = await axios.post(`${baseUrl2}/auth/setup-link`, { email });
|
|
887
896
|
setupUrl = res.data.setupUrl;
|
|
888
897
|
deviceCode = res.data.deviceCode;
|
|
889
|
-
spinner.stop();
|
|
890
898
|
} catch (error) {
|
|
891
899
|
const msg = error?.response?.data?.message || error.message;
|
|
892
|
-
|
|
900
|
+
console.log(chalk4.red(` \u2717 Setup failed: ${msg}`));
|
|
893
901
|
console.log();
|
|
894
902
|
console.log(chalk4.dim(" You can try again with: ") + chalk4.white("clishop setup"));
|
|
895
903
|
console.log();
|
|
896
904
|
process.exitCode = 1;
|
|
897
905
|
return;
|
|
898
906
|
}
|
|
907
|
+
printSetupLink(
|
|
908
|
+
"Give this link to your human to configure the payment method:",
|
|
909
|
+
setupUrl
|
|
910
|
+
);
|
|
911
|
+
console.log(chalk4.dim(" Waiting for you to complete payment setup..."));
|
|
912
|
+
console.log(chalk4.dim(" If your terminal UI hides earlier output, use the plain-text URL above."));
|
|
899
913
|
console.log();
|
|
900
|
-
console.log(chalk4.bold(" Give this link to your human to configure the payment method:"));
|
|
901
|
-
console.log();
|
|
902
|
-
console.log(" " + chalk4.cyan.underline(setupUrl));
|
|
903
|
-
console.log();
|
|
904
|
-
const pollSpinner = ora3("Waiting for you to complete payment setup...").start();
|
|
905
914
|
const baseUrl = getApiBaseUrl();
|
|
906
915
|
const maxAttempts = 120;
|
|
907
916
|
let completed = false;
|
|
@@ -917,12 +926,12 @@ async function runSetupWizard(emailArg) {
|
|
|
917
926
|
user: data.user
|
|
918
927
|
});
|
|
919
928
|
config.set("setupCompleted", true);
|
|
920
|
-
|
|
929
|
+
console.log(chalk4.green(" \u2713 Payment linked and account activated!"));
|
|
921
930
|
completed = true;
|
|
922
931
|
break;
|
|
923
932
|
}
|
|
924
933
|
if (data.status === "expired") {
|
|
925
|
-
|
|
934
|
+
console.log(chalk4.red(" Setup link expired. Run ") + chalk4.white("clishop setup") + chalk4.red(" to try again."));
|
|
926
935
|
process.exitCode = 1;
|
|
927
936
|
return;
|
|
928
937
|
}
|
|
@@ -930,7 +939,7 @@ async function runSetupWizard(emailArg) {
|
|
|
930
939
|
}
|
|
931
940
|
}
|
|
932
941
|
if (!completed) {
|
|
933
|
-
|
|
942
|
+
console.log(chalk4.red(" Timed out waiting for setup. Run ") + chalk4.white("clishop setup") + chalk4.red(" to try again."));
|
|
934
943
|
process.exitCode = 1;
|
|
935
944
|
return;
|
|
936
945
|
}
|
|
@@ -962,19 +971,14 @@ async function runSetupWizard(emailArg) {
|
|
|
962
971
|
console.log();
|
|
963
972
|
}
|
|
964
973
|
async function runPaymentLinkFlow(config) {
|
|
965
|
-
|
|
974
|
+
console.log(chalk4.dim(" Requesting secure payment setup link..."));
|
|
966
975
|
try {
|
|
967
976
|
const api = getApiClient();
|
|
968
977
|
const agent = getActiveAgent();
|
|
969
978
|
await ensureAgentOnBackend(agent.name);
|
|
970
979
|
const res = await api.post("/payment-methods/setup", { agent: agent.name });
|
|
971
|
-
spinner.stop();
|
|
972
980
|
const { setupUrl } = res.data;
|
|
973
|
-
|
|
974
|
-
console.log(chalk4.bold(" Open this link to link your payment method:"));
|
|
975
|
-
console.log();
|
|
976
|
-
console.log(" " + chalk4.cyan.underline(setupUrl));
|
|
977
|
-
console.log();
|
|
981
|
+
printSetupLink("Open this link to link your payment method:", setupUrl);
|
|
978
982
|
const opened = await openBrowser(setupUrl);
|
|
979
983
|
if (opened) {
|
|
980
984
|
console.log(chalk4.dim(" (Browser opened automatically)"));
|
|
@@ -983,19 +987,19 @@ async function runPaymentLinkFlow(config) {
|
|
|
983
987
|
await inquirer3.prompt([
|
|
984
988
|
{ type: "input", name: "done", message: "Press Enter after completing payment setup in your browser..." }
|
|
985
989
|
]);
|
|
986
|
-
|
|
990
|
+
console.log(chalk4.dim(" Checking for your payment method..."));
|
|
987
991
|
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
988
992
|
const methods = pmRes.data.paymentMethods || [];
|
|
989
993
|
if (methods.length > 0) {
|
|
990
994
|
const latest = methods[methods.length - 1];
|
|
991
995
|
updateAgent(agent.name, { defaultPaymentMethodId: latest.id });
|
|
992
|
-
|
|
996
|
+
console.log(chalk4.green(` \u2713 Payment method "${latest.label}" linked and set as default.`));
|
|
993
997
|
config.set("setupCompleted", true);
|
|
994
998
|
} else {
|
|
995
|
-
|
|
999
|
+
console.log(chalk4.yellow(" \u26A0 No payment method found yet. Run ") + chalk4.white("clishop setup") + chalk4.yellow(" to try again."));
|
|
996
1000
|
}
|
|
997
1001
|
} catch (error) {
|
|
998
|
-
|
|
1002
|
+
console.log(chalk4.red(` \u2717 Could not get setup link: ${error?.response?.data?.message || error.message}`));
|
|
999
1003
|
}
|
|
1000
1004
|
console.log();
|
|
1001
1005
|
}
|
|
@@ -1007,7 +1011,7 @@ function registerPaymentCommands(program2) {
|
|
|
1007
1011
|
try {
|
|
1008
1012
|
const agent = getActiveAgent();
|
|
1009
1013
|
await ensureAgentOnBackend(agent.name);
|
|
1010
|
-
const spinner =
|
|
1014
|
+
const spinner = ora3("Fetching payment methods...").start();
|
|
1011
1015
|
const api = getApiClient();
|
|
1012
1016
|
const res = await api.get("/payment-methods", {
|
|
1013
1017
|
params: { agent: agent.name }
|
|
@@ -1035,7 +1039,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1035
1039
|
try {
|
|
1036
1040
|
const agent = getActiveAgent();
|
|
1037
1041
|
await ensureAgentOnBackend(agent.name);
|
|
1038
|
-
const spinner =
|
|
1042
|
+
const spinner = ora3("Requesting secure payment setup link...").start();
|
|
1039
1043
|
const api = getApiClient();
|
|
1040
1044
|
const res = await api.post("/payment-methods/setup", {
|
|
1041
1045
|
agent: agent.name
|
|
@@ -1052,7 +1056,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1052
1056
|
await inquirer10.prompt([
|
|
1053
1057
|
{ type: "input", name: "done", message: "Press Enter when done..." }
|
|
1054
1058
|
]);
|
|
1055
|
-
const checkSpinner =
|
|
1059
|
+
const checkSpinner = ora3("Checking for your payment method...").start();
|
|
1056
1060
|
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
1057
1061
|
const methods = pmRes.data.paymentMethods || [];
|
|
1058
1062
|
if (methods.length > 0) {
|
|
@@ -1072,7 +1076,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1072
1076
|
});
|
|
1073
1077
|
payment.command("remove <id>").alias("rm").description("Remove a payment method").action(async (id) => {
|
|
1074
1078
|
try {
|
|
1075
|
-
const spinner =
|
|
1079
|
+
const spinner = ora3("Removing payment method...").start();
|
|
1076
1080
|
const api = getApiClient();
|
|
1077
1081
|
await api.delete(`/payment-methods/${id}`);
|
|
1078
1082
|
spinner.succeed(chalk5.green("Payment method removed."));
|
|
@@ -1094,7 +1098,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1094
1098
|
|
|
1095
1099
|
// src/commands/search.ts
|
|
1096
1100
|
import chalk6 from "chalk";
|
|
1097
|
-
import
|
|
1101
|
+
import ora4 from "ora";
|
|
1098
1102
|
import inquirer4 from "inquirer";
|
|
1099
1103
|
function formatPrice(cents, currency) {
|
|
1100
1104
|
return new Intl.NumberFormat("en-US", {
|
|
@@ -1487,7 +1491,7 @@ function renderProductInfo(result, index, totalResults, formatPriceFn) {
|
|
|
1487
1491
|
function registerSearchCommands(program2) {
|
|
1488
1492
|
program2.command("search <query>").description("Search for products").option("-c, --category <category>", "Filter by category").option("--brand <brand>", "Filter by brand").option("--model <model>", "Filter by model name/number").option("--sku <sku>", "Filter by SKU").option("--gtin <gtin>", "Filter by GTIN (UPC/EAN/ISBN)").option("--variant <variant>", "Filter by variant (size/color/storage/etc.)").option("--min-price <price>", "Minimum price (cents)", parseFloat).option("--max-price <price>", "Maximum price (cents)", parseFloat).option("--max-shipping <price>", "Maximum shipping cost (cents)", parseInt).option("--max-total <price>", "Maximum landed total: item + shipping (cents)", parseInt).option("--free-shipping", "Only show items with free shipping").option("--ship-to <address>", "Saved address label or ID (resolves country/city/postal automatically)").option("--country <code>", "Delivery country (ISO 3166-1 alpha-2, e.g. US, BE, NL)").option("--city <city>", "Delivery city").option("--postal-code <code>", "Delivery postal/zip code").option("--region <region>", "Delivery state/province/region").option("--lat <latitude>", "Delivery latitude (for local/proximity search)", parseFloat).option("--lng <longitude>", "Delivery longitude (for local/proximity search)", parseFloat).option("--deliver-by <date>", "Need delivery by date (YYYY-MM-DD)").option("--max-delivery-days <days>", "Maximum delivery/transit days", parseInt).option("--in-stock", "Only show in-stock items").option("--exclude-backorder", "Exclude backordered items").option("--min-qty <qty>", "Minimum quantity available", parseInt).option("--free-returns", "Only show items with free returns").option("--min-return-window-days <days>", "Minimum return window in days", parseInt).option("--store <store>", "Limit to a store (ID, slug, or name)").option("--vendor <vendor>", "Filter by vendor name (alias for --store)").option("--trusted-only", "Only show products from verified stores").option("--min-store-rating <rating>", "Minimum store rating (0-5)", parseFloat).option("--min-rating <rating>", "Minimum product rating (1-5)", parseFloat).option("-s, --sort <field>", "Sort by: price, total-cost, rating, relevance, newest, delivery", "relevance").option("--order <dir>", "Sort order: asc, desc", "desc").option("-p, --page <page>", "Page number", parseInt, 1).option("-n, --per-page <count>", "Results per page", parseInt, 10).option("--express", "Only show items with 2-day or faster delivery").option("-e, --extended-search", "Enable extended search: query darkstores when no local results found").option("--no-extended-search", "Disable automatic extended search when no local results found").option("--extended-timeout <seconds>", "Extended search timeout in seconds (default: 30, max: 60)", parseInt).option("--json", "Output raw JSON").option("--compact", "Compact one-line-per-result output").option("--detailed", "Show full product details inline").option("-i, --interactive", "After results, interactively select products to get more info from their store").action(async (query, opts) => {
|
|
1489
1493
|
try {
|
|
1490
|
-
const spinner =
|
|
1494
|
+
const spinner = ora4(`Searching for "${query}"...`).start();
|
|
1491
1495
|
const api = getApiClient();
|
|
1492
1496
|
let maxDeliveryDays = opts.maxDeliveryDays;
|
|
1493
1497
|
if (!maxDeliveryDays && opts.deliverBy) {
|
|
@@ -1905,7 +1909,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
1905
1909
|
(id) => allProducts.find((p) => p.id === id && !p.isExtended)
|
|
1906
1910
|
);
|
|
1907
1911
|
if (extendedIds.length > 0) {
|
|
1908
|
-
const infoSpinner =
|
|
1912
|
+
const infoSpinner = ora4(`Requesting detailed info for ${extendedIds.length} product(s) from their stores...`).start();
|
|
1909
1913
|
try {
|
|
1910
1914
|
const infoRes = await api.post("/products/info", {
|
|
1911
1915
|
productIds: extendedIds
|
|
@@ -1932,7 +1936,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
1932
1936
|
}
|
|
1933
1937
|
if (localIds.length > 0) {
|
|
1934
1938
|
for (const localId of localIds) {
|
|
1935
|
-
const detailSpinner =
|
|
1939
|
+
const detailSpinner = ora4(`Fetching details for ${localId}...`).start();
|
|
1936
1940
|
try {
|
|
1937
1941
|
const detailRes = await api.get(`/products/${localId}`);
|
|
1938
1942
|
detailSpinner.stop();
|
|
@@ -2008,7 +2012,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
2008
2012
|
});
|
|
2009
2013
|
program2.command("product <id>").description("View detailed product information").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
2010
2014
|
try {
|
|
2011
|
-
const spinner =
|
|
2015
|
+
const spinner = ora4("Fetching product details...").start();
|
|
2012
2016
|
const api = getApiClient();
|
|
2013
2017
|
const res = await api.get(`/products/${id}`);
|
|
2014
2018
|
spinner.stop();
|
|
@@ -2090,7 +2094,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
2090
2094
|
ids.push(input);
|
|
2091
2095
|
}
|
|
2092
2096
|
}
|
|
2093
|
-
const spinner =
|
|
2097
|
+
const spinner = ora4(`Requesting detailed info for ${ids.length} product(s)...`).start();
|
|
2094
2098
|
const api = getApiClient();
|
|
2095
2099
|
const res = await api.post("/products/info", {
|
|
2096
2100
|
productIds: ids
|
|
@@ -2123,7 +2127,7 @@ Product Information \u2014 ${total} result(s)
|
|
|
2123
2127
|
|
|
2124
2128
|
// src/commands/order.ts
|
|
2125
2129
|
import chalk7 from "chalk";
|
|
2126
|
-
import
|
|
2130
|
+
import ora5 from "ora";
|
|
2127
2131
|
import inquirer5 from "inquirer";
|
|
2128
2132
|
function formatPrice2(cents, currency) {
|
|
2129
2133
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
@@ -2188,7 +2192,7 @@ function registerOrderCommands(program2) {
|
|
|
2188
2192
|
return;
|
|
2189
2193
|
}
|
|
2190
2194
|
const api = getApiClient();
|
|
2191
|
-
const prodSpinner =
|
|
2195
|
+
const prodSpinner = ora5("Fetching product info...").start();
|
|
2192
2196
|
let product;
|
|
2193
2197
|
let isExtended = false;
|
|
2194
2198
|
try {
|
|
@@ -2257,7 +2261,7 @@ function registerOrderCommands(program2) {
|
|
|
2257
2261
|
return;
|
|
2258
2262
|
}
|
|
2259
2263
|
}
|
|
2260
|
-
const spinner =
|
|
2264
|
+
const spinner = ora5("Placing order...").start();
|
|
2261
2265
|
const res = await api.post("/orders", {
|
|
2262
2266
|
agent: agent.name,
|
|
2263
2267
|
items: [{ productId, quantity: opts.quantity }],
|
|
@@ -2281,7 +2285,7 @@ function registerOrderCommands(program2) {
|
|
|
2281
2285
|
});
|
|
2282
2286
|
order.command("list").alias("ls").description("List your orders").option("--status <status>", "Filter by status").option("-p, --page <page>", "Page number", parseInt, 1).option("--json", "Output raw JSON").action(async (opts) => {
|
|
2283
2287
|
try {
|
|
2284
|
-
const spinner =
|
|
2288
|
+
const spinner = ora5("Fetching orders...").start();
|
|
2285
2289
|
const api = getApiClient();
|
|
2286
2290
|
const res = await api.get("/orders", {
|
|
2287
2291
|
params: {
|
|
@@ -2317,7 +2321,7 @@ function registerOrderCommands(program2) {
|
|
|
2317
2321
|
});
|
|
2318
2322
|
order.command("show <id>").description("Show order details").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
2319
2323
|
try {
|
|
2320
|
-
const spinner =
|
|
2324
|
+
const spinner = ora5("Fetching order...").start();
|
|
2321
2325
|
const api = getApiClient();
|
|
2322
2326
|
const res = await api.get(`/orders/${id}`);
|
|
2323
2327
|
spinner.stop();
|
|
@@ -2400,7 +2404,7 @@ function registerOrderCommands(program2) {
|
|
|
2400
2404
|
}
|
|
2401
2405
|
]);
|
|
2402
2406
|
if (!confirm) return;
|
|
2403
|
-
const spinner =
|
|
2407
|
+
const spinner = ora5("Cancelling order...").start();
|
|
2404
2408
|
const api = getApiClient();
|
|
2405
2409
|
await api.post(`/orders/${id}/cancel`);
|
|
2406
2410
|
spinner.succeed(chalk7.green("Order cancelled."));
|
|
@@ -2412,7 +2416,7 @@ function registerOrderCommands(program2) {
|
|
|
2412
2416
|
|
|
2413
2417
|
// src/commands/review.ts
|
|
2414
2418
|
import chalk8 from "chalk";
|
|
2415
|
-
import
|
|
2419
|
+
import ora6 from "ora";
|
|
2416
2420
|
import inquirer6 from "inquirer";
|
|
2417
2421
|
function renderStars2(rating) {
|
|
2418
2422
|
const filled = Math.round(rating);
|
|
@@ -2441,7 +2445,7 @@ function registerReviewCommands(program2) {
|
|
|
2441
2445
|
review.command("order <orderId>").description("Review items and store from an order").action(async (orderId) => {
|
|
2442
2446
|
try {
|
|
2443
2447
|
const api = getApiClient();
|
|
2444
|
-
const spinner =
|
|
2448
|
+
const spinner = ora6("Fetching order details...").start();
|
|
2445
2449
|
let reviewable;
|
|
2446
2450
|
try {
|
|
2447
2451
|
const res = await api.get(`/orders/${orderId}/reviewable`);
|
|
@@ -2546,7 +2550,7 @@ function registerReviewCommands(program2) {
|
|
|
2546
2550
|
console.log(chalk8.yellow("\nNo reviews submitted.\n"));
|
|
2547
2551
|
return;
|
|
2548
2552
|
}
|
|
2549
|
-
const submitSpinner =
|
|
2553
|
+
const submitSpinner = ora6("Submitting reviews...").start();
|
|
2550
2554
|
try {
|
|
2551
2555
|
const res = await api.post(`/orders/${orderId}/reviews`, {
|
|
2552
2556
|
itemReviews,
|
|
@@ -2589,7 +2593,7 @@ function registerReviewCommands(program2) {
|
|
|
2589
2593
|
message: "Review body (opens your editor):"
|
|
2590
2594
|
}
|
|
2591
2595
|
]);
|
|
2592
|
-
const spinner =
|
|
2596
|
+
const spinner = ora6("Submitting review...").start();
|
|
2593
2597
|
const api = getApiClient();
|
|
2594
2598
|
const res = await api.post(`/products/${productId}/reviews`, {
|
|
2595
2599
|
rating: answers.rating,
|
|
@@ -2622,7 +2626,7 @@ function registerReviewCommands(program2) {
|
|
|
2622
2626
|
message: "Review body (opens your editor):"
|
|
2623
2627
|
}
|
|
2624
2628
|
]);
|
|
2625
|
-
const spinner =
|
|
2629
|
+
const spinner = ora6("Submitting store review...").start();
|
|
2626
2630
|
const api = getApiClient();
|
|
2627
2631
|
const res = await api.post(`/stores/${storeId}/reviews`, {
|
|
2628
2632
|
rating: answers.rating,
|
|
@@ -2641,7 +2645,7 @@ function registerReviewCommands(program2) {
|
|
|
2641
2645
|
});
|
|
2642
2646
|
review.command("list").alias("ls").description("List your reviews").option("--json", "Output raw JSON").action(async (opts) => {
|
|
2643
2647
|
try {
|
|
2644
|
-
const spinner =
|
|
2648
|
+
const spinner = ora6("Fetching reviews...").start();
|
|
2645
2649
|
const api = getApiClient();
|
|
2646
2650
|
const res = await api.get("/reviews/mine");
|
|
2647
2651
|
spinner.stop();
|
|
@@ -2680,7 +2684,7 @@ function registerReviewCommands(program2) {
|
|
|
2680
2684
|
});
|
|
2681
2685
|
review.command("rating <id>").description("View rating details for a product or store").option("--store", "View store rating instead of product").action(async (id, opts) => {
|
|
2682
2686
|
try {
|
|
2683
|
-
const spinner =
|
|
2687
|
+
const spinner = ora6("Fetching rating...").start();
|
|
2684
2688
|
const api = getApiClient();
|
|
2685
2689
|
const endpoint = opts.store ? `/stores/${id}/rating` : `/products/${id}/rating`;
|
|
2686
2690
|
const res = await api.get(endpoint);
|
|
@@ -2719,7 +2723,7 @@ function registerReviewCommands(program2) {
|
|
|
2719
2723
|
}
|
|
2720
2724
|
]);
|
|
2721
2725
|
if (!confirm) return;
|
|
2722
|
-
const spinner =
|
|
2726
|
+
const spinner = ora6("Deleting review...").start();
|
|
2723
2727
|
const api = getApiClient();
|
|
2724
2728
|
const endpoint = opts.store ? `/store-reviews/${reviewId}` : `/reviews/${reviewId}`;
|
|
2725
2729
|
await api.delete(endpoint);
|
|
@@ -2766,7 +2770,7 @@ function registerConfigCommands(program2) {
|
|
|
2766
2770
|
|
|
2767
2771
|
// src/commands/store.ts
|
|
2768
2772
|
import chalk10 from "chalk";
|
|
2769
|
-
import
|
|
2773
|
+
import ora7 from "ora";
|
|
2770
2774
|
function formatPrice3(cents, currency) {
|
|
2771
2775
|
return new Intl.NumberFormat("en-US", {
|
|
2772
2776
|
style: "currency",
|
|
@@ -2789,7 +2793,7 @@ function registerStoreCommands(program2) {
|
|
|
2789
2793
|
const store = program2.command("store").description("Browse stores and their catalogs");
|
|
2790
2794
|
store.command("list").alias("ls").description("List available stores").option("-q, --query <query>", "Search stores by name").option("--verified", "Only show verified stores").option("--min-rating <rating>", "Minimum store rating (0-5)", parseFloat).option("--country <country>", "Filter by country").option("-s, --sort <field>", "Sort by: name, rating, newest, products", "name").option("--order <dir>", "Sort order: asc, desc", "asc").option("-p, --page <page>", "Page number", parseInt, 1).option("-n, --per-page <count>", "Results per page", parseInt, 20).option("--json", "Output raw JSON").action(async (opts) => {
|
|
2791
2795
|
try {
|
|
2792
|
-
const spinner =
|
|
2796
|
+
const spinner = ora7("Fetching stores...").start();
|
|
2793
2797
|
const api = getApiClient();
|
|
2794
2798
|
const res = await api.get("/stores", {
|
|
2795
2799
|
params: {
|
|
@@ -2840,7 +2844,7 @@ Stores \u2014 ${total} found (page ${page})
|
|
|
2840
2844
|
});
|
|
2841
2845
|
store.command("info <store>").description("View store details (by name, slug, or ID)").option("--json", "Output raw JSON").action(async (storeId, opts) => {
|
|
2842
2846
|
try {
|
|
2843
|
-
const spinner =
|
|
2847
|
+
const spinner = ora7("Fetching store info...").start();
|
|
2844
2848
|
const api = getApiClient();
|
|
2845
2849
|
const res = await api.get(`/stores/${encodeURIComponent(storeId)}`);
|
|
2846
2850
|
spinner.stop();
|
|
@@ -2874,7 +2878,7 @@ Stores \u2014 ${total} found (page ${page})
|
|
|
2874
2878
|
});
|
|
2875
2879
|
store.command("catalog <store>").description("Browse a store's product catalog (by name, slug, or ID)").option("-q, --query <query>", "Search within the store's products").option("-c, --category <category>", "Filter by category").option("--min-price <price>", "Minimum price (cents)", parseFloat).option("--max-price <price>", "Maximum price (cents)", parseFloat).option("--min-rating <rating>", "Minimum product rating (1-5)", parseFloat).option("--in-stock", "Only show in-stock items").option("--free-shipping", "Only show items with free shipping").option("-s, --sort <field>", "Sort by: price, rating, newest, name", "newest").option("--order <dir>", "Sort order: asc, desc", "desc").option("-p, --page <page>", "Page number", parseInt, 1).option("-n, --per-page <count>", "Results per page", parseInt, 20).option("--json", "Output raw JSON").action(async (storeId, opts) => {
|
|
2876
2880
|
try {
|
|
2877
|
-
const spinner =
|
|
2881
|
+
const spinner = ora7(`Fetching catalog for "${storeId}"...`).start();
|
|
2878
2882
|
const api = getApiClient();
|
|
2879
2883
|
const res = await api.get(`/stores/${encodeURIComponent(storeId)}/catalog`, {
|
|
2880
2884
|
params: {
|
|
@@ -2944,7 +2948,7 @@ ${storeInfo.name}${badge}${storeRating} \u2014 ${total} products (page ${page})
|
|
|
2944
2948
|
|
|
2945
2949
|
// src/commands/status.ts
|
|
2946
2950
|
import chalk11 from "chalk";
|
|
2947
|
-
import
|
|
2951
|
+
import ora8 from "ora";
|
|
2948
2952
|
function registerStatusCommand(program2) {
|
|
2949
2953
|
program2.command("status").description("Show full account overview \u2014 user, agents, addresses, payment methods").option("--json", "Output raw JSON").action(async (opts) => {
|
|
2950
2954
|
try {
|
|
@@ -2952,7 +2956,7 @@ function registerStatusCommand(program2) {
|
|
|
2952
2956
|
console.log(chalk11.yellow("\nNot set up yet. Run: clishop setup\n"));
|
|
2953
2957
|
return;
|
|
2954
2958
|
}
|
|
2955
|
-
const spinner =
|
|
2959
|
+
const spinner = ora8("Fetching account overview...").start();
|
|
2956
2960
|
const api = getApiClient();
|
|
2957
2961
|
const cfg = getConfig();
|
|
2958
2962
|
const activeAgentName = cfg.get("activeAgent") || "default";
|
|
@@ -3044,7 +3048,7 @@ function registerStatusCommand(program2) {
|
|
|
3044
3048
|
|
|
3045
3049
|
// src/commands/advertise.ts
|
|
3046
3050
|
import chalk12 from "chalk";
|
|
3047
|
-
import
|
|
3051
|
+
import ora9 from "ora";
|
|
3048
3052
|
import inquirer7 from "inquirer";
|
|
3049
3053
|
function formatPrice4(cents, currency) {
|
|
3050
3054
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
@@ -3190,7 +3194,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3190
3194
|
]);
|
|
3191
3195
|
const api = getApiClient();
|
|
3192
3196
|
let addressId;
|
|
3193
|
-
const addrSpinner =
|
|
3197
|
+
const addrSpinner = ora9("Fetching your addresses...").start();
|
|
3194
3198
|
try {
|
|
3195
3199
|
const addrRes = await api.get("/addresses", { params: { agent: agent.name } });
|
|
3196
3200
|
addrSpinner.stop();
|
|
@@ -3226,7 +3230,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3226
3230
|
console.log(chalk12.dim(" Could not fetch addresses. Skipping delivery location."));
|
|
3227
3231
|
}
|
|
3228
3232
|
let paymentMethods;
|
|
3229
|
-
const paySpinner =
|
|
3233
|
+
const paySpinner = ora9("Fetching your payment methods...").start();
|
|
3230
3234
|
try {
|
|
3231
3235
|
const payRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
3232
3236
|
paySpinner.stop();
|
|
@@ -3296,7 +3300,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3296
3300
|
body.minReturnDays = days;
|
|
3297
3301
|
}
|
|
3298
3302
|
}
|
|
3299
|
-
const spinner =
|
|
3303
|
+
const spinner = ora9("Publishing your request...").start();
|
|
3300
3304
|
const res = await api.post("/advertise", body);
|
|
3301
3305
|
spinner.succeed(chalk12.green(`Request published! ID: ${chalk12.bold(res.data.advertise.id)}`));
|
|
3302
3306
|
console.log(chalk12.dim("\n Vendors can now see your request and submit bids."));
|
|
@@ -3345,7 +3349,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3345
3349
|
if (opts.minReturnDays) {
|
|
3346
3350
|
body.minReturnDays = opts.minReturnDays;
|
|
3347
3351
|
}
|
|
3348
|
-
const spinner =
|
|
3352
|
+
const spinner = ora9("Publishing your request...").start();
|
|
3349
3353
|
const api = getApiClient();
|
|
3350
3354
|
const res = await api.post("/advertise", body);
|
|
3351
3355
|
spinner.succeed(chalk12.green(`Request published! ID: ${chalk12.bold(res.data.advertise.id)}`));
|
|
@@ -3355,7 +3359,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3355
3359
|
});
|
|
3356
3360
|
advertise.command("list").alias("ls").description("List your advertised requests").option("--status <status>", "Filter by status (open, closed, accepted, cancelled, expired)").option("-p, --page <page>", "Page number", parseInt, 1).option("--json", "Output raw JSON").action(async (opts) => {
|
|
3357
3361
|
try {
|
|
3358
|
-
const spinner =
|
|
3362
|
+
const spinner = ora9("Fetching your requests...").start();
|
|
3359
3363
|
const api = getApiClient();
|
|
3360
3364
|
const res = await api.get("/advertise", {
|
|
3361
3365
|
params: { status: opts.status, page: opts.page }
|
|
@@ -3405,7 +3409,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3405
3409
|
});
|
|
3406
3410
|
advertise.command("show <id>").description("View an advertised request and its bids").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
3407
3411
|
try {
|
|
3408
|
-
const spinner =
|
|
3412
|
+
const spinner = ora9("Fetching request...").start();
|
|
3409
3413
|
const api = getApiClient();
|
|
3410
3414
|
const res = await api.get(`/advertise/${id}`);
|
|
3411
3415
|
spinner.stop();
|
|
@@ -3490,7 +3494,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3490
3494
|
advertise.command("accept <advertiseId> <bidId>").description("Accept a vendor's bid on your request").action(async (advertiseId, bidId) => {
|
|
3491
3495
|
try {
|
|
3492
3496
|
const api = getApiClient();
|
|
3493
|
-
const detailSpinner =
|
|
3497
|
+
const detailSpinner = ora9("Fetching bid details...").start();
|
|
3494
3498
|
const detailRes = await api.get(`/advertise/${advertiseId}`);
|
|
3495
3499
|
detailSpinner.stop();
|
|
3496
3500
|
const ad = detailRes.data.advertise;
|
|
@@ -3520,7 +3524,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3520
3524
|
console.log(chalk12.yellow("Cancelled."));
|
|
3521
3525
|
return;
|
|
3522
3526
|
}
|
|
3523
|
-
const spinner =
|
|
3527
|
+
const spinner = ora9("Accepting bid...").start();
|
|
3524
3528
|
await api.post(`/advertise/${advertiseId}/bids/${bidId}/accept`);
|
|
3525
3529
|
spinner.succeed(chalk12.green("Bid accepted! The vendor will now fulfill your request."));
|
|
3526
3530
|
} catch (error) {
|
|
@@ -3538,7 +3542,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3538
3542
|
}
|
|
3539
3543
|
]);
|
|
3540
3544
|
if (!confirm) return;
|
|
3541
|
-
const spinner =
|
|
3545
|
+
const spinner = ora9("Rejecting bid...").start();
|
|
3542
3546
|
const api = getApiClient();
|
|
3543
3547
|
await api.post(`/advertise/${advertiseId}/bids/${bidId}/reject`);
|
|
3544
3548
|
spinner.succeed(chalk12.green("Bid rejected."));
|
|
@@ -3557,7 +3561,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3557
3561
|
}
|
|
3558
3562
|
]);
|
|
3559
3563
|
if (!confirm) return;
|
|
3560
|
-
const spinner =
|
|
3564
|
+
const spinner = ora9("Cancelling request...").start();
|
|
3561
3565
|
const api = getApiClient();
|
|
3562
3566
|
await api.post(`/advertise/${id}/cancel`);
|
|
3563
3567
|
spinner.succeed(chalk12.green("Request cancelled."));
|
|
@@ -3569,7 +3573,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3569
3573
|
|
|
3570
3574
|
// src/commands/support.ts
|
|
3571
3575
|
import chalk13 from "chalk";
|
|
3572
|
-
import
|
|
3576
|
+
import ora10 from "ora";
|
|
3573
3577
|
import inquirer8 from "inquirer";
|
|
3574
3578
|
var CATEGORY_CHOICES = [
|
|
3575
3579
|
{ name: "General question", value: "general" },
|
|
@@ -3634,7 +3638,7 @@ function registerSupportCommands(program2) {
|
|
|
3634
3638
|
console.error(chalk13.red("\n\u2717 Message is required.\n"));
|
|
3635
3639
|
return;
|
|
3636
3640
|
}
|
|
3637
|
-
const spinner =
|
|
3641
|
+
const spinner = ora10("Creating support ticket...").start();
|
|
3638
3642
|
const api = getApiClient();
|
|
3639
3643
|
const res = await api.post("/support", {
|
|
3640
3644
|
orderId,
|
|
@@ -3661,7 +3665,7 @@ function registerSupportCommands(program2) {
|
|
|
3661
3665
|
});
|
|
3662
3666
|
support.command("list").alias("ls").description("List your support tickets").option("--status <status>", "Filter by status").option("--json", "Output raw JSON").action(async (opts) => {
|
|
3663
3667
|
try {
|
|
3664
|
-
const spinner =
|
|
3668
|
+
const spinner = ora10("Fetching tickets...").start();
|
|
3665
3669
|
const api = getApiClient();
|
|
3666
3670
|
const res = await api.get("/support", {
|
|
3667
3671
|
params: { status: opts.status }
|
|
@@ -3698,7 +3702,7 @@ function registerSupportCommands(program2) {
|
|
|
3698
3702
|
});
|
|
3699
3703
|
support.command("show <ticketId>").description("View a support ticket and its messages").option("--json", "Output raw JSON").action(async (ticketId, opts) => {
|
|
3700
3704
|
try {
|
|
3701
|
-
const spinner =
|
|
3705
|
+
const spinner = ora10("Fetching ticket...").start();
|
|
3702
3706
|
const api = getApiClient();
|
|
3703
3707
|
const res = await api.get(`/support/${ticketId}`);
|
|
3704
3708
|
spinner.stop();
|
|
@@ -3746,7 +3750,7 @@ function registerSupportCommands(program2) {
|
|
|
3746
3750
|
console.error(chalk13.red("\n\u2717 Message is required.\n"));
|
|
3747
3751
|
return;
|
|
3748
3752
|
}
|
|
3749
|
-
const spinner =
|
|
3753
|
+
const spinner = ora10("Sending reply...").start();
|
|
3750
3754
|
const api = getApiClient();
|
|
3751
3755
|
const res = await api.post(`/support/${ticketId}/reply`, {
|
|
3752
3756
|
message: message.trim()
|
|
@@ -3769,7 +3773,7 @@ function registerSupportCommands(program2) {
|
|
|
3769
3773
|
}
|
|
3770
3774
|
]);
|
|
3771
3775
|
if (!confirm) return;
|
|
3772
|
-
const spinner =
|
|
3776
|
+
const spinner = ora10("Closing ticket...").start();
|
|
3773
3777
|
const api = getApiClient();
|
|
3774
3778
|
await api.patch(`/support/${ticketId}/status`, { status: "closed" });
|
|
3775
3779
|
spinner.succeed(chalk13.green("Ticket closed."));
|
|
@@ -3781,7 +3785,7 @@ function registerSupportCommands(program2) {
|
|
|
3781
3785
|
|
|
3782
3786
|
// src/commands/feedback.ts
|
|
3783
3787
|
import chalk14 from "chalk";
|
|
3784
|
-
import
|
|
3788
|
+
import ora11 from "ora";
|
|
3785
3789
|
import inquirer9 from "inquirer";
|
|
3786
3790
|
var STATUS_COLORS4 = {
|
|
3787
3791
|
open: chalk14.green,
|
|
@@ -3856,7 +3860,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3856
3860
|
console.error(chalk14.red("\n\u2717 Steps to reproduce are required.\n"));
|
|
3857
3861
|
return;
|
|
3858
3862
|
}
|
|
3859
|
-
const spinner =
|
|
3863
|
+
const spinner = ora11("Submitting bug report...").start();
|
|
3860
3864
|
const api = getApiClient();
|
|
3861
3865
|
const res = await api.post("/feedback", {
|
|
3862
3866
|
type: "bug",
|
|
@@ -3907,7 +3911,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3907
3911
|
console.error(chalk14.red("\n\u2717 Description is required.\n"));
|
|
3908
3912
|
return;
|
|
3909
3913
|
}
|
|
3910
|
-
const spinner =
|
|
3914
|
+
const spinner = ora11("Submitting suggestion...").start();
|
|
3911
3915
|
const api = getApiClient();
|
|
3912
3916
|
const res = await api.post("/feedback", {
|
|
3913
3917
|
type: "suggestion",
|
|
@@ -3930,7 +3934,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3930
3934
|
});
|
|
3931
3935
|
feedback.command("list").alias("ls").description("List your bug reports and suggestions").option("--type <type>", "Filter by type (bug or suggestion)").option("--status <status>", "Filter by status").option("--json", "Output raw JSON").action(async (opts) => {
|
|
3932
3936
|
try {
|
|
3933
|
-
const spinner =
|
|
3937
|
+
const spinner = ora11("Fetching feedback...").start();
|
|
3934
3938
|
const api = getApiClient();
|
|
3935
3939
|
const res = await api.get("/feedback", {
|
|
3936
3940
|
params: {
|
|
@@ -3969,7 +3973,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3969
3973
|
});
|
|
3970
3974
|
feedback.command("show <id>").description("View a bug report or suggestion").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
3971
3975
|
try {
|
|
3972
|
-
const spinner =
|
|
3976
|
+
const spinner = ora11("Fetching feedback...").start();
|
|
3973
3977
|
const api = getApiClient();
|
|
3974
3978
|
const res = await api.get(`/feedback/${id}`);
|
|
3975
3979
|
spinner.stop();
|
|
@@ -4067,7 +4071,7 @@ function registerDoctorCommand(program2) {
|
|
|
4067
4071
|
|
|
4068
4072
|
// src/index.ts
|
|
4069
4073
|
var program = new Command();
|
|
4070
|
-
program.name("clishop").version("1.4.
|
|
4074
|
+
program.name("clishop").version("1.4.5").description(
|
|
4071
4075
|
chalk16.bold("CLISHOP") + ` \u2014 Order anything from your terminal.
|
|
4072
4076
|
|
|
4073
4077
|
Run 'clishop setup' to get started with a single payment link.
|