clishop 1.4.4 → 1.4.6
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 -66
- 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";
|
|
@@ -857,7 +856,7 @@ async function runSetupWizard(emailArg) {
|
|
|
857
856
|
console.log();
|
|
858
857
|
console.log(chalk4.bold.cyan(" W E L C O M E T O C L I S H O P"));
|
|
859
858
|
console.log(chalk4.dim(" Order anything from your terminal."));
|
|
860
|
-
console.log(chalk4.dim(` Build: ${"2026-04-
|
|
859
|
+
console.log(chalk4.dim(` Build: ${"2026-04-04T18:13:33.709Z"}`));
|
|
861
860
|
console.log();
|
|
862
861
|
divider(chalk4.cyan);
|
|
863
862
|
console.log();
|
|
@@ -888,7 +887,7 @@ async function runSetupWizard(emailArg) {
|
|
|
888
887
|
]);
|
|
889
888
|
email = answers.email;
|
|
890
889
|
}
|
|
891
|
-
|
|
890
|
+
console.log(chalk4.dim(" Creating your account and payment link..."));
|
|
892
891
|
let setupUrl;
|
|
893
892
|
let deviceCode;
|
|
894
893
|
try {
|
|
@@ -896,10 +895,9 @@ async function runSetupWizard(emailArg) {
|
|
|
896
895
|
const res = await axios.post(`${baseUrl2}/auth/setup-link`, { email });
|
|
897
896
|
setupUrl = res.data.setupUrl;
|
|
898
897
|
deviceCode = res.data.deviceCode;
|
|
899
|
-
spinner.stop();
|
|
900
898
|
} catch (error) {
|
|
901
899
|
const msg = error?.response?.data?.message || error.message;
|
|
902
|
-
|
|
900
|
+
console.log(chalk4.red(` \u2717 Setup failed: ${msg}`));
|
|
903
901
|
console.log();
|
|
904
902
|
console.log(chalk4.dim(" You can try again with: ") + chalk4.white("clishop setup"));
|
|
905
903
|
console.log();
|
|
@@ -973,13 +971,12 @@ async function runSetupWizard(emailArg) {
|
|
|
973
971
|
console.log();
|
|
974
972
|
}
|
|
975
973
|
async function runPaymentLinkFlow(config) {
|
|
976
|
-
|
|
974
|
+
console.log(chalk4.dim(" Requesting secure payment setup link..."));
|
|
977
975
|
try {
|
|
978
976
|
const api = getApiClient();
|
|
979
977
|
const agent = getActiveAgent();
|
|
980
978
|
await ensureAgentOnBackend(agent.name);
|
|
981
979
|
const res = await api.post("/payment-methods/setup", { agent: agent.name });
|
|
982
|
-
spinner.stop();
|
|
983
980
|
const { setupUrl } = res.data;
|
|
984
981
|
printSetupLink("Open this link to link your payment method:", setupUrl);
|
|
985
982
|
const opened = await openBrowser(setupUrl);
|
|
@@ -990,19 +987,19 @@ async function runPaymentLinkFlow(config) {
|
|
|
990
987
|
await inquirer3.prompt([
|
|
991
988
|
{ type: "input", name: "done", message: "Press Enter after completing payment setup in your browser..." }
|
|
992
989
|
]);
|
|
993
|
-
|
|
990
|
+
console.log(chalk4.dim(" Checking for your payment method..."));
|
|
994
991
|
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
995
992
|
const methods = pmRes.data.paymentMethods || [];
|
|
996
993
|
if (methods.length > 0) {
|
|
997
994
|
const latest = methods[methods.length - 1];
|
|
998
995
|
updateAgent(agent.name, { defaultPaymentMethodId: latest.id });
|
|
999
|
-
|
|
996
|
+
console.log(chalk4.green(` \u2713 Payment method "${latest.label}" linked and set as default.`));
|
|
1000
997
|
config.set("setupCompleted", true);
|
|
1001
998
|
} else {
|
|
1002
|
-
|
|
999
|
+
console.log(chalk4.yellow(" \u26A0 No payment method found yet. Run ") + chalk4.white("clishop setup") + chalk4.yellow(" to try again."));
|
|
1003
1000
|
}
|
|
1004
1001
|
} catch (error) {
|
|
1005
|
-
|
|
1002
|
+
console.log(chalk4.red(` \u2717 Could not get setup link: ${error?.response?.data?.message || error.message}`));
|
|
1006
1003
|
}
|
|
1007
1004
|
console.log();
|
|
1008
1005
|
}
|
|
@@ -1014,7 +1011,7 @@ function registerPaymentCommands(program2) {
|
|
|
1014
1011
|
try {
|
|
1015
1012
|
const agent = getActiveAgent();
|
|
1016
1013
|
await ensureAgentOnBackend(agent.name);
|
|
1017
|
-
const spinner =
|
|
1014
|
+
const spinner = ora3("Fetching payment methods...").start();
|
|
1018
1015
|
const api = getApiClient();
|
|
1019
1016
|
const res = await api.get("/payment-methods", {
|
|
1020
1017
|
params: { agent: agent.name }
|
|
@@ -1042,7 +1039,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1042
1039
|
try {
|
|
1043
1040
|
const agent = getActiveAgent();
|
|
1044
1041
|
await ensureAgentOnBackend(agent.name);
|
|
1045
|
-
const spinner =
|
|
1042
|
+
const spinner = ora3("Requesting secure payment setup link...").start();
|
|
1046
1043
|
const api = getApiClient();
|
|
1047
1044
|
const res = await api.post("/payment-methods/setup", {
|
|
1048
1045
|
agent: agent.name
|
|
@@ -1059,7 +1056,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1059
1056
|
await inquirer10.prompt([
|
|
1060
1057
|
{ type: "input", name: "done", message: "Press Enter when done..." }
|
|
1061
1058
|
]);
|
|
1062
|
-
const checkSpinner =
|
|
1059
|
+
const checkSpinner = ora3("Checking for your payment method...").start();
|
|
1063
1060
|
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
1064
1061
|
const methods = pmRes.data.paymentMethods || [];
|
|
1065
1062
|
if (methods.length > 0) {
|
|
@@ -1079,7 +1076,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1079
1076
|
});
|
|
1080
1077
|
payment.command("remove <id>").alias("rm").description("Remove a payment method").action(async (id) => {
|
|
1081
1078
|
try {
|
|
1082
|
-
const spinner =
|
|
1079
|
+
const spinner = ora3("Removing payment method...").start();
|
|
1083
1080
|
const api = getApiClient();
|
|
1084
1081
|
await api.delete(`/payment-methods/${id}`);
|
|
1085
1082
|
spinner.succeed(chalk5.green("Payment method removed."));
|
|
@@ -1101,7 +1098,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1101
1098
|
|
|
1102
1099
|
// src/commands/search.ts
|
|
1103
1100
|
import chalk6 from "chalk";
|
|
1104
|
-
import
|
|
1101
|
+
import ora4 from "ora";
|
|
1105
1102
|
import inquirer4 from "inquirer";
|
|
1106
1103
|
function formatPrice(cents, currency) {
|
|
1107
1104
|
return new Intl.NumberFormat("en-US", {
|
|
@@ -1494,7 +1491,7 @@ function renderProductInfo(result, index, totalResults, formatPriceFn) {
|
|
|
1494
1491
|
function registerSearchCommands(program2) {
|
|
1495
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) => {
|
|
1496
1493
|
try {
|
|
1497
|
-
const spinner =
|
|
1494
|
+
const spinner = ora4(`Searching for "${query}"...`).start();
|
|
1498
1495
|
const api = getApiClient();
|
|
1499
1496
|
let maxDeliveryDays = opts.maxDeliveryDays;
|
|
1500
1497
|
if (!maxDeliveryDays && opts.deliverBy) {
|
|
@@ -1912,7 +1909,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
1912
1909
|
(id) => allProducts.find((p) => p.id === id && !p.isExtended)
|
|
1913
1910
|
);
|
|
1914
1911
|
if (extendedIds.length > 0) {
|
|
1915
|
-
const infoSpinner =
|
|
1912
|
+
const infoSpinner = ora4(`Requesting detailed info for ${extendedIds.length} product(s) from their stores...`).start();
|
|
1916
1913
|
try {
|
|
1917
1914
|
const infoRes = await api.post("/products/info", {
|
|
1918
1915
|
productIds: extendedIds
|
|
@@ -1939,7 +1936,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
1939
1936
|
}
|
|
1940
1937
|
if (localIds.length > 0) {
|
|
1941
1938
|
for (const localId of localIds) {
|
|
1942
|
-
const detailSpinner =
|
|
1939
|
+
const detailSpinner = ora4(`Fetching details for ${localId}...`).start();
|
|
1943
1940
|
try {
|
|
1944
1941
|
const detailRes = await api.get(`/products/${localId}`);
|
|
1945
1942
|
detailSpinner.stop();
|
|
@@ -2015,7 +2012,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
2015
2012
|
});
|
|
2016
2013
|
program2.command("product <id>").description("View detailed product information").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
2017
2014
|
try {
|
|
2018
|
-
const spinner =
|
|
2015
|
+
const spinner = ora4("Fetching product details...").start();
|
|
2019
2016
|
const api = getApiClient();
|
|
2020
2017
|
const res = await api.get(`/products/${id}`);
|
|
2021
2018
|
spinner.stop();
|
|
@@ -2097,7 +2094,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
2097
2094
|
ids.push(input);
|
|
2098
2095
|
}
|
|
2099
2096
|
}
|
|
2100
|
-
const spinner =
|
|
2097
|
+
const spinner = ora4(`Requesting detailed info for ${ids.length} product(s)...`).start();
|
|
2101
2098
|
const api = getApiClient();
|
|
2102
2099
|
const res = await api.post("/products/info", {
|
|
2103
2100
|
productIds: ids
|
|
@@ -2130,7 +2127,7 @@ Product Information \u2014 ${total} result(s)
|
|
|
2130
2127
|
|
|
2131
2128
|
// src/commands/order.ts
|
|
2132
2129
|
import chalk7 from "chalk";
|
|
2133
|
-
import
|
|
2130
|
+
import ora5 from "ora";
|
|
2134
2131
|
import inquirer5 from "inquirer";
|
|
2135
2132
|
function formatPrice2(cents, currency) {
|
|
2136
2133
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
@@ -2145,6 +2142,25 @@ var STATUS_COLORS = {
|
|
|
2145
2142
|
delivered: chalk7.green,
|
|
2146
2143
|
cancelled: chalk7.red
|
|
2147
2144
|
};
|
|
2145
|
+
function printMissingAddressGuidance() {
|
|
2146
|
+
console.error();
|
|
2147
|
+
console.error(chalk7.red("\u2717 No delivery address is set for this agent."));
|
|
2148
|
+
console.error();
|
|
2149
|
+
console.error(chalk7.dim(" To buy something, you need a delivery address first."));
|
|
2150
|
+
console.error(chalk7.dim(" Ask your human for the delivery address, or if you already know their home address,"));
|
|
2151
|
+
console.error(chalk7.dim(" suggest it yourself in full and ask them to confirm that it is correct."));
|
|
2152
|
+
console.error();
|
|
2153
|
+
console.error(chalk7.bold(" Suggested format:"));
|
|
2154
|
+
console.error(chalk7.white(" First + Last Name"));
|
|
2155
|
+
console.error(chalk7.white(" Street + number"));
|
|
2156
|
+
console.error(chalk7.white(" City + ZIP code"));
|
|
2157
|
+
console.error(chalk7.white(" Country"));
|
|
2158
|
+
console.error(chalk7.white(" Phone number"));
|
|
2159
|
+
console.error();
|
|
2160
|
+
console.error(chalk7.dim(" Once confirmed, save it as the Home address with:"));
|
|
2161
|
+
console.error(chalk7.white(" clishop address add"));
|
|
2162
|
+
console.error();
|
|
2163
|
+
}
|
|
2148
2164
|
function registerOrderCommands(program2) {
|
|
2149
2165
|
const order = program2.command("order").description("Place and manage orders");
|
|
2150
2166
|
program2.command("buy <productIdOrNumber>").description("Quick-buy a product (use product ID or search result number like 1, 2, 3)").option("-q, --quantity <qty>", "Quantity", parseInt, 1).option("--address <id>", "Shipping address ID (uses agent default if omitted)").option("--payment <id>", "Payment method ID (uses agent default if omitted)").option("-y, --yes", "Skip confirmation prompt").action(async (productIdOrNumber, opts) => {
|
|
@@ -2185,7 +2201,7 @@ function registerOrderCommands(program2) {
|
|
|
2185
2201
|
}
|
|
2186
2202
|
}
|
|
2187
2203
|
if (!addressId) {
|
|
2188
|
-
|
|
2204
|
+
printMissingAddressGuidance();
|
|
2189
2205
|
process.exitCode = 1;
|
|
2190
2206
|
return;
|
|
2191
2207
|
}
|
|
@@ -2195,7 +2211,7 @@ function registerOrderCommands(program2) {
|
|
|
2195
2211
|
return;
|
|
2196
2212
|
}
|
|
2197
2213
|
const api = getApiClient();
|
|
2198
|
-
const prodSpinner =
|
|
2214
|
+
const prodSpinner = ora5("Fetching product info...").start();
|
|
2199
2215
|
let product;
|
|
2200
2216
|
let isExtended = false;
|
|
2201
2217
|
try {
|
|
@@ -2264,7 +2280,7 @@ function registerOrderCommands(program2) {
|
|
|
2264
2280
|
return;
|
|
2265
2281
|
}
|
|
2266
2282
|
}
|
|
2267
|
-
const spinner =
|
|
2283
|
+
const spinner = ora5("Placing order...").start();
|
|
2268
2284
|
const res = await api.post("/orders", {
|
|
2269
2285
|
agent: agent.name,
|
|
2270
2286
|
items: [{ productId, quantity: opts.quantity }],
|
|
@@ -2288,7 +2304,7 @@ function registerOrderCommands(program2) {
|
|
|
2288
2304
|
});
|
|
2289
2305
|
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) => {
|
|
2290
2306
|
try {
|
|
2291
|
-
const spinner =
|
|
2307
|
+
const spinner = ora5("Fetching orders...").start();
|
|
2292
2308
|
const api = getApiClient();
|
|
2293
2309
|
const res = await api.get("/orders", {
|
|
2294
2310
|
params: {
|
|
@@ -2324,7 +2340,7 @@ function registerOrderCommands(program2) {
|
|
|
2324
2340
|
});
|
|
2325
2341
|
order.command("show <id>").description("Show order details").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
2326
2342
|
try {
|
|
2327
|
-
const spinner =
|
|
2343
|
+
const spinner = ora5("Fetching order...").start();
|
|
2328
2344
|
const api = getApiClient();
|
|
2329
2345
|
const res = await api.get(`/orders/${id}`);
|
|
2330
2346
|
spinner.stop();
|
|
@@ -2407,7 +2423,7 @@ function registerOrderCommands(program2) {
|
|
|
2407
2423
|
}
|
|
2408
2424
|
]);
|
|
2409
2425
|
if (!confirm) return;
|
|
2410
|
-
const spinner =
|
|
2426
|
+
const spinner = ora5("Cancelling order...").start();
|
|
2411
2427
|
const api = getApiClient();
|
|
2412
2428
|
await api.post(`/orders/${id}/cancel`);
|
|
2413
2429
|
spinner.succeed(chalk7.green("Order cancelled."));
|
|
@@ -2419,7 +2435,7 @@ function registerOrderCommands(program2) {
|
|
|
2419
2435
|
|
|
2420
2436
|
// src/commands/review.ts
|
|
2421
2437
|
import chalk8 from "chalk";
|
|
2422
|
-
import
|
|
2438
|
+
import ora6 from "ora";
|
|
2423
2439
|
import inquirer6 from "inquirer";
|
|
2424
2440
|
function renderStars2(rating) {
|
|
2425
2441
|
const filled = Math.round(rating);
|
|
@@ -2448,7 +2464,7 @@ function registerReviewCommands(program2) {
|
|
|
2448
2464
|
review.command("order <orderId>").description("Review items and store from an order").action(async (orderId) => {
|
|
2449
2465
|
try {
|
|
2450
2466
|
const api = getApiClient();
|
|
2451
|
-
const spinner =
|
|
2467
|
+
const spinner = ora6("Fetching order details...").start();
|
|
2452
2468
|
let reviewable;
|
|
2453
2469
|
try {
|
|
2454
2470
|
const res = await api.get(`/orders/${orderId}/reviewable`);
|
|
@@ -2553,7 +2569,7 @@ function registerReviewCommands(program2) {
|
|
|
2553
2569
|
console.log(chalk8.yellow("\nNo reviews submitted.\n"));
|
|
2554
2570
|
return;
|
|
2555
2571
|
}
|
|
2556
|
-
const submitSpinner =
|
|
2572
|
+
const submitSpinner = ora6("Submitting reviews...").start();
|
|
2557
2573
|
try {
|
|
2558
2574
|
const res = await api.post(`/orders/${orderId}/reviews`, {
|
|
2559
2575
|
itemReviews,
|
|
@@ -2596,7 +2612,7 @@ function registerReviewCommands(program2) {
|
|
|
2596
2612
|
message: "Review body (opens your editor):"
|
|
2597
2613
|
}
|
|
2598
2614
|
]);
|
|
2599
|
-
const spinner =
|
|
2615
|
+
const spinner = ora6("Submitting review...").start();
|
|
2600
2616
|
const api = getApiClient();
|
|
2601
2617
|
const res = await api.post(`/products/${productId}/reviews`, {
|
|
2602
2618
|
rating: answers.rating,
|
|
@@ -2629,7 +2645,7 @@ function registerReviewCommands(program2) {
|
|
|
2629
2645
|
message: "Review body (opens your editor):"
|
|
2630
2646
|
}
|
|
2631
2647
|
]);
|
|
2632
|
-
const spinner =
|
|
2648
|
+
const spinner = ora6("Submitting store review...").start();
|
|
2633
2649
|
const api = getApiClient();
|
|
2634
2650
|
const res = await api.post(`/stores/${storeId}/reviews`, {
|
|
2635
2651
|
rating: answers.rating,
|
|
@@ -2648,7 +2664,7 @@ function registerReviewCommands(program2) {
|
|
|
2648
2664
|
});
|
|
2649
2665
|
review.command("list").alias("ls").description("List your reviews").option("--json", "Output raw JSON").action(async (opts) => {
|
|
2650
2666
|
try {
|
|
2651
|
-
const spinner =
|
|
2667
|
+
const spinner = ora6("Fetching reviews...").start();
|
|
2652
2668
|
const api = getApiClient();
|
|
2653
2669
|
const res = await api.get("/reviews/mine");
|
|
2654
2670
|
spinner.stop();
|
|
@@ -2687,7 +2703,7 @@ function registerReviewCommands(program2) {
|
|
|
2687
2703
|
});
|
|
2688
2704
|
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) => {
|
|
2689
2705
|
try {
|
|
2690
|
-
const spinner =
|
|
2706
|
+
const spinner = ora6("Fetching rating...").start();
|
|
2691
2707
|
const api = getApiClient();
|
|
2692
2708
|
const endpoint = opts.store ? `/stores/${id}/rating` : `/products/${id}/rating`;
|
|
2693
2709
|
const res = await api.get(endpoint);
|
|
@@ -2726,7 +2742,7 @@ function registerReviewCommands(program2) {
|
|
|
2726
2742
|
}
|
|
2727
2743
|
]);
|
|
2728
2744
|
if (!confirm) return;
|
|
2729
|
-
const spinner =
|
|
2745
|
+
const spinner = ora6("Deleting review...").start();
|
|
2730
2746
|
const api = getApiClient();
|
|
2731
2747
|
const endpoint = opts.store ? `/store-reviews/${reviewId}` : `/reviews/${reviewId}`;
|
|
2732
2748
|
await api.delete(endpoint);
|
|
@@ -2773,7 +2789,7 @@ function registerConfigCommands(program2) {
|
|
|
2773
2789
|
|
|
2774
2790
|
// src/commands/store.ts
|
|
2775
2791
|
import chalk10 from "chalk";
|
|
2776
|
-
import
|
|
2792
|
+
import ora7 from "ora";
|
|
2777
2793
|
function formatPrice3(cents, currency) {
|
|
2778
2794
|
return new Intl.NumberFormat("en-US", {
|
|
2779
2795
|
style: "currency",
|
|
@@ -2796,7 +2812,7 @@ function registerStoreCommands(program2) {
|
|
|
2796
2812
|
const store = program2.command("store").description("Browse stores and their catalogs");
|
|
2797
2813
|
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) => {
|
|
2798
2814
|
try {
|
|
2799
|
-
const spinner =
|
|
2815
|
+
const spinner = ora7("Fetching stores...").start();
|
|
2800
2816
|
const api = getApiClient();
|
|
2801
2817
|
const res = await api.get("/stores", {
|
|
2802
2818
|
params: {
|
|
@@ -2847,7 +2863,7 @@ Stores \u2014 ${total} found (page ${page})
|
|
|
2847
2863
|
});
|
|
2848
2864
|
store.command("info <store>").description("View store details (by name, slug, or ID)").option("--json", "Output raw JSON").action(async (storeId, opts) => {
|
|
2849
2865
|
try {
|
|
2850
|
-
const spinner =
|
|
2866
|
+
const spinner = ora7("Fetching store info...").start();
|
|
2851
2867
|
const api = getApiClient();
|
|
2852
2868
|
const res = await api.get(`/stores/${encodeURIComponent(storeId)}`);
|
|
2853
2869
|
spinner.stop();
|
|
@@ -2881,7 +2897,7 @@ Stores \u2014 ${total} found (page ${page})
|
|
|
2881
2897
|
});
|
|
2882
2898
|
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) => {
|
|
2883
2899
|
try {
|
|
2884
|
-
const spinner =
|
|
2900
|
+
const spinner = ora7(`Fetching catalog for "${storeId}"...`).start();
|
|
2885
2901
|
const api = getApiClient();
|
|
2886
2902
|
const res = await api.get(`/stores/${encodeURIComponent(storeId)}/catalog`, {
|
|
2887
2903
|
params: {
|
|
@@ -2951,7 +2967,7 @@ ${storeInfo.name}${badge}${storeRating} \u2014 ${total} products (page ${page})
|
|
|
2951
2967
|
|
|
2952
2968
|
// src/commands/status.ts
|
|
2953
2969
|
import chalk11 from "chalk";
|
|
2954
|
-
import
|
|
2970
|
+
import ora8 from "ora";
|
|
2955
2971
|
function registerStatusCommand(program2) {
|
|
2956
2972
|
program2.command("status").description("Show full account overview \u2014 user, agents, addresses, payment methods").option("--json", "Output raw JSON").action(async (opts) => {
|
|
2957
2973
|
try {
|
|
@@ -2959,7 +2975,7 @@ function registerStatusCommand(program2) {
|
|
|
2959
2975
|
console.log(chalk11.yellow("\nNot set up yet. Run: clishop setup\n"));
|
|
2960
2976
|
return;
|
|
2961
2977
|
}
|
|
2962
|
-
const spinner =
|
|
2978
|
+
const spinner = ora8("Fetching account overview...").start();
|
|
2963
2979
|
const api = getApiClient();
|
|
2964
2980
|
const cfg = getConfig();
|
|
2965
2981
|
const activeAgentName = cfg.get("activeAgent") || "default";
|
|
@@ -3051,7 +3067,7 @@ function registerStatusCommand(program2) {
|
|
|
3051
3067
|
|
|
3052
3068
|
// src/commands/advertise.ts
|
|
3053
3069
|
import chalk12 from "chalk";
|
|
3054
|
-
import
|
|
3070
|
+
import ora9 from "ora";
|
|
3055
3071
|
import inquirer7 from "inquirer";
|
|
3056
3072
|
function formatPrice4(cents, currency) {
|
|
3057
3073
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
@@ -3197,7 +3213,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3197
3213
|
]);
|
|
3198
3214
|
const api = getApiClient();
|
|
3199
3215
|
let addressId;
|
|
3200
|
-
const addrSpinner =
|
|
3216
|
+
const addrSpinner = ora9("Fetching your addresses...").start();
|
|
3201
3217
|
try {
|
|
3202
3218
|
const addrRes = await api.get("/addresses", { params: { agent: agent.name } });
|
|
3203
3219
|
addrSpinner.stop();
|
|
@@ -3233,7 +3249,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3233
3249
|
console.log(chalk12.dim(" Could not fetch addresses. Skipping delivery location."));
|
|
3234
3250
|
}
|
|
3235
3251
|
let paymentMethods;
|
|
3236
|
-
const paySpinner =
|
|
3252
|
+
const paySpinner = ora9("Fetching your payment methods...").start();
|
|
3237
3253
|
try {
|
|
3238
3254
|
const payRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
3239
3255
|
paySpinner.stop();
|
|
@@ -3303,7 +3319,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3303
3319
|
body.minReturnDays = days;
|
|
3304
3320
|
}
|
|
3305
3321
|
}
|
|
3306
|
-
const spinner =
|
|
3322
|
+
const spinner = ora9("Publishing your request...").start();
|
|
3307
3323
|
const res = await api.post("/advertise", body);
|
|
3308
3324
|
spinner.succeed(chalk12.green(`Request published! ID: ${chalk12.bold(res.data.advertise.id)}`));
|
|
3309
3325
|
console.log(chalk12.dim("\n Vendors can now see your request and submit bids."));
|
|
@@ -3352,7 +3368,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3352
3368
|
if (opts.minReturnDays) {
|
|
3353
3369
|
body.minReturnDays = opts.minReturnDays;
|
|
3354
3370
|
}
|
|
3355
|
-
const spinner =
|
|
3371
|
+
const spinner = ora9("Publishing your request...").start();
|
|
3356
3372
|
const api = getApiClient();
|
|
3357
3373
|
const res = await api.post("/advertise", body);
|
|
3358
3374
|
spinner.succeed(chalk12.green(`Request published! ID: ${chalk12.bold(res.data.advertise.id)}`));
|
|
@@ -3362,7 +3378,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3362
3378
|
});
|
|
3363
3379
|
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) => {
|
|
3364
3380
|
try {
|
|
3365
|
-
const spinner =
|
|
3381
|
+
const spinner = ora9("Fetching your requests...").start();
|
|
3366
3382
|
const api = getApiClient();
|
|
3367
3383
|
const res = await api.get("/advertise", {
|
|
3368
3384
|
params: { status: opts.status, page: opts.page }
|
|
@@ -3412,7 +3428,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3412
3428
|
});
|
|
3413
3429
|
advertise.command("show <id>").description("View an advertised request and its bids").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
3414
3430
|
try {
|
|
3415
|
-
const spinner =
|
|
3431
|
+
const spinner = ora9("Fetching request...").start();
|
|
3416
3432
|
const api = getApiClient();
|
|
3417
3433
|
const res = await api.get(`/advertise/${id}`);
|
|
3418
3434
|
spinner.stop();
|
|
@@ -3497,7 +3513,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3497
3513
|
advertise.command("accept <advertiseId> <bidId>").description("Accept a vendor's bid on your request").action(async (advertiseId, bidId) => {
|
|
3498
3514
|
try {
|
|
3499
3515
|
const api = getApiClient();
|
|
3500
|
-
const detailSpinner =
|
|
3516
|
+
const detailSpinner = ora9("Fetching bid details...").start();
|
|
3501
3517
|
const detailRes = await api.get(`/advertise/${advertiseId}`);
|
|
3502
3518
|
detailSpinner.stop();
|
|
3503
3519
|
const ad = detailRes.data.advertise;
|
|
@@ -3527,7 +3543,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3527
3543
|
console.log(chalk12.yellow("Cancelled."));
|
|
3528
3544
|
return;
|
|
3529
3545
|
}
|
|
3530
|
-
const spinner =
|
|
3546
|
+
const spinner = ora9("Accepting bid...").start();
|
|
3531
3547
|
await api.post(`/advertise/${advertiseId}/bids/${bidId}/accept`);
|
|
3532
3548
|
spinner.succeed(chalk12.green("Bid accepted! The vendor will now fulfill your request."));
|
|
3533
3549
|
} catch (error) {
|
|
@@ -3545,7 +3561,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3545
3561
|
}
|
|
3546
3562
|
]);
|
|
3547
3563
|
if (!confirm) return;
|
|
3548
|
-
const spinner =
|
|
3564
|
+
const spinner = ora9("Rejecting bid...").start();
|
|
3549
3565
|
const api = getApiClient();
|
|
3550
3566
|
await api.post(`/advertise/${advertiseId}/bids/${bidId}/reject`);
|
|
3551
3567
|
spinner.succeed(chalk12.green("Bid rejected."));
|
|
@@ -3564,7 +3580,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3564
3580
|
}
|
|
3565
3581
|
]);
|
|
3566
3582
|
if (!confirm) return;
|
|
3567
|
-
const spinner =
|
|
3583
|
+
const spinner = ora9("Cancelling request...").start();
|
|
3568
3584
|
const api = getApiClient();
|
|
3569
3585
|
await api.post(`/advertise/${id}/cancel`);
|
|
3570
3586
|
spinner.succeed(chalk12.green("Request cancelled."));
|
|
@@ -3576,7 +3592,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3576
3592
|
|
|
3577
3593
|
// src/commands/support.ts
|
|
3578
3594
|
import chalk13 from "chalk";
|
|
3579
|
-
import
|
|
3595
|
+
import ora10 from "ora";
|
|
3580
3596
|
import inquirer8 from "inquirer";
|
|
3581
3597
|
var CATEGORY_CHOICES = [
|
|
3582
3598
|
{ name: "General question", value: "general" },
|
|
@@ -3641,7 +3657,7 @@ function registerSupportCommands(program2) {
|
|
|
3641
3657
|
console.error(chalk13.red("\n\u2717 Message is required.\n"));
|
|
3642
3658
|
return;
|
|
3643
3659
|
}
|
|
3644
|
-
const spinner =
|
|
3660
|
+
const spinner = ora10("Creating support ticket...").start();
|
|
3645
3661
|
const api = getApiClient();
|
|
3646
3662
|
const res = await api.post("/support", {
|
|
3647
3663
|
orderId,
|
|
@@ -3668,7 +3684,7 @@ function registerSupportCommands(program2) {
|
|
|
3668
3684
|
});
|
|
3669
3685
|
support.command("list").alias("ls").description("List your support tickets").option("--status <status>", "Filter by status").option("--json", "Output raw JSON").action(async (opts) => {
|
|
3670
3686
|
try {
|
|
3671
|
-
const spinner =
|
|
3687
|
+
const spinner = ora10("Fetching tickets...").start();
|
|
3672
3688
|
const api = getApiClient();
|
|
3673
3689
|
const res = await api.get("/support", {
|
|
3674
3690
|
params: { status: opts.status }
|
|
@@ -3705,7 +3721,7 @@ function registerSupportCommands(program2) {
|
|
|
3705
3721
|
});
|
|
3706
3722
|
support.command("show <ticketId>").description("View a support ticket and its messages").option("--json", "Output raw JSON").action(async (ticketId, opts) => {
|
|
3707
3723
|
try {
|
|
3708
|
-
const spinner =
|
|
3724
|
+
const spinner = ora10("Fetching ticket...").start();
|
|
3709
3725
|
const api = getApiClient();
|
|
3710
3726
|
const res = await api.get(`/support/${ticketId}`);
|
|
3711
3727
|
spinner.stop();
|
|
@@ -3753,7 +3769,7 @@ function registerSupportCommands(program2) {
|
|
|
3753
3769
|
console.error(chalk13.red("\n\u2717 Message is required.\n"));
|
|
3754
3770
|
return;
|
|
3755
3771
|
}
|
|
3756
|
-
const spinner =
|
|
3772
|
+
const spinner = ora10("Sending reply...").start();
|
|
3757
3773
|
const api = getApiClient();
|
|
3758
3774
|
const res = await api.post(`/support/${ticketId}/reply`, {
|
|
3759
3775
|
message: message.trim()
|
|
@@ -3776,7 +3792,7 @@ function registerSupportCommands(program2) {
|
|
|
3776
3792
|
}
|
|
3777
3793
|
]);
|
|
3778
3794
|
if (!confirm) return;
|
|
3779
|
-
const spinner =
|
|
3795
|
+
const spinner = ora10("Closing ticket...").start();
|
|
3780
3796
|
const api = getApiClient();
|
|
3781
3797
|
await api.patch(`/support/${ticketId}/status`, { status: "closed" });
|
|
3782
3798
|
spinner.succeed(chalk13.green("Ticket closed."));
|
|
@@ -3788,7 +3804,7 @@ function registerSupportCommands(program2) {
|
|
|
3788
3804
|
|
|
3789
3805
|
// src/commands/feedback.ts
|
|
3790
3806
|
import chalk14 from "chalk";
|
|
3791
|
-
import
|
|
3807
|
+
import ora11 from "ora";
|
|
3792
3808
|
import inquirer9 from "inquirer";
|
|
3793
3809
|
var STATUS_COLORS4 = {
|
|
3794
3810
|
open: chalk14.green,
|
|
@@ -3863,7 +3879,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3863
3879
|
console.error(chalk14.red("\n\u2717 Steps to reproduce are required.\n"));
|
|
3864
3880
|
return;
|
|
3865
3881
|
}
|
|
3866
|
-
const spinner =
|
|
3882
|
+
const spinner = ora11("Submitting bug report...").start();
|
|
3867
3883
|
const api = getApiClient();
|
|
3868
3884
|
const res = await api.post("/feedback", {
|
|
3869
3885
|
type: "bug",
|
|
@@ -3914,7 +3930,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3914
3930
|
console.error(chalk14.red("\n\u2717 Description is required.\n"));
|
|
3915
3931
|
return;
|
|
3916
3932
|
}
|
|
3917
|
-
const spinner =
|
|
3933
|
+
const spinner = ora11("Submitting suggestion...").start();
|
|
3918
3934
|
const api = getApiClient();
|
|
3919
3935
|
const res = await api.post("/feedback", {
|
|
3920
3936
|
type: "suggestion",
|
|
@@ -3937,7 +3953,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3937
3953
|
});
|
|
3938
3954
|
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) => {
|
|
3939
3955
|
try {
|
|
3940
|
-
const spinner =
|
|
3956
|
+
const spinner = ora11("Fetching feedback...").start();
|
|
3941
3957
|
const api = getApiClient();
|
|
3942
3958
|
const res = await api.get("/feedback", {
|
|
3943
3959
|
params: {
|
|
@@ -3976,7 +3992,7 @@ function registerFeedbackCommands(program2) {
|
|
|
3976
3992
|
});
|
|
3977
3993
|
feedback.command("show <id>").description("View a bug report or suggestion").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
3978
3994
|
try {
|
|
3979
|
-
const spinner =
|
|
3995
|
+
const spinner = ora11("Fetching feedback...").start();
|
|
3980
3996
|
const api = getApiClient();
|
|
3981
3997
|
const res = await api.get(`/feedback/${id}`);
|
|
3982
3998
|
spinner.stop();
|
|
@@ -4074,7 +4090,7 @@ function registerDoctorCommand(program2) {
|
|
|
4074
4090
|
|
|
4075
4091
|
// src/index.ts
|
|
4076
4092
|
var program = new Command();
|
|
4077
|
-
program.name("clishop").version("1.4.
|
|
4093
|
+
program.name("clishop").version("1.4.6").description(
|
|
4078
4094
|
chalk16.bold("CLISHOP") + ` \u2014 Order anything from your terminal.
|
|
4079
4095
|
|
|
4080
4096
|
Run 'clishop setup' to get started with a single payment link.
|