terminalmarket 0.13.3 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/tm.js +131 -19
  2. package/package.json +1 -1
package/bin/tm.js CHANGED
@@ -713,34 +713,146 @@ program
713
713
  // -----------------
714
714
  program
715
715
  .command("checkout")
716
- .description("Proceed to checkout")
717
- .action(async () => {
716
+ .description("Create order from cart")
717
+ .option("--pickup", "Pick up at store")
718
+ .option("--delivery", "Delivery to address")
719
+ .option("--shipping", "Shipping (post/courier)")
720
+ .option("--phone <phone>", "Contact phone number")
721
+ .option("--address <address>", "Delivery/shipping address")
722
+ .option("-y, --yes", "Skip confirmation prompt")
723
+ .action(async (opts) => {
718
724
  try {
719
725
  const cartData = await apiGet("/cart");
720
-
721
- if (!cartData.items || cartData.items.length === 0) {
722
- console.log(chalk.yellow("Your cart is empty. Add items first."));
726
+ const items = cartData.items || [];
727
+
728
+ if (items.length === 0) {
729
+ console.log(chalk.yellow("Your cart is empty. Add items first with: tm add <product-id>"));
723
730
  return;
724
731
  }
725
-
726
- console.log(chalk.bold("Checkout"));
727
- console.log("");
728
- console.log("Your items:");
729
-
732
+
730
733
  let total = 0;
731
- cartData.items.forEach((item, i) => {
734
+ console.log();
735
+ console.log(chalk.bold(" ═══ Checkout ═══"));
736
+ console.log();
737
+ items.forEach((item, i) => {
732
738
  const name = item.name || item.product?.name || `Product #${item.productId}`;
733
739
  const price = parseFloat(item.price ?? item.product?.price ?? 0);
734
- const subtotal = price * (item.quantity || 1);
740
+ const qty = item.quantity || 1;
741
+ const subtotal = price * qty;
735
742
  total += subtotal;
736
- console.log(` ${i + 1}. ${name} x${item.quantity} = $${subtotal.toFixed(2)}`);
743
+ console.log(` ${i + 1}. ${name} x${qty} = $${subtotal.toFixed(2)}`);
737
744
  });
738
-
739
- console.log("");
740
- console.log(chalk.bold(`Total: $${total.toFixed(2)}`));
741
- console.log("");
742
- console.log(chalk.dim("To complete checkout, use the web terminal checkout flow."));
743
- console.log(chalk.dim(" https://terminalmarket.app"));
745
+ console.log();
746
+ console.log(chalk.bold(` Total: $${total.toFixed(2)}`));
747
+ console.log();
748
+
749
+ const hasDigitalOnly = items.length > 0 && items.every(it => {
750
+ const k = it.product?.productKind || it.productKind;
751
+ return k === "digital" || k === "saas";
752
+ });
753
+
754
+ let deliveryMethod = null;
755
+ if (opts.pickup) deliveryMethod = "pickup";
756
+ else if (opts.delivery) deliveryMethod = "delivery";
757
+ else if (opts.shipping) deliveryMethod = "shipping";
758
+
759
+ let phone = opts.phone || null;
760
+ let address = opts.address || null;
761
+
762
+ if (!hasDigitalOnly) {
763
+ // Try to pull phone/address from profile if not provided
764
+ if (!phone || !address) {
765
+ try {
766
+ const profile = await apiGet("/profile");
767
+ if (!phone && profile.phone) phone = profile.phone;
768
+ if (!address) {
769
+ const parts = [profile.address, profile.city, profile.country].filter(Boolean);
770
+ if (parts.length > 0) address = parts.join(", ");
771
+ }
772
+ } catch { /* ignore */ }
773
+ }
774
+
775
+ const inquirer = await import("inquirer").then(m => m.default);
776
+
777
+ // Ask delivery method interactively if not set
778
+ if (!deliveryMethod) {
779
+ const { method } = await inquirer.prompt([{
780
+ type: "list",
781
+ name: "method",
782
+ message: "Delivery method:",
783
+ choices: [
784
+ { name: "🏪 Pick up at store", value: "pickup" },
785
+ { name: "🚗 Delivery to address", value: "delivery" },
786
+ { name: "📦 Shipping (post/courier)", value: "shipping" },
787
+ ],
788
+ }]);
789
+ deliveryMethod = method;
790
+ }
791
+
792
+ // Ask phone if missing
793
+ if (!phone) {
794
+ const { inputPhone } = await inquirer.prompt([{
795
+ type: "input",
796
+ name: "inputPhone",
797
+ message: "Contact phone:",
798
+ validate: v => v.trim().length > 0 || "Phone is required",
799
+ }]);
800
+ phone = inputPhone.trim();
801
+ }
802
+
803
+ // Ask address if delivery/shipping and missing
804
+ if ((deliveryMethod === "delivery" || deliveryMethod === "shipping") && !address) {
805
+ const { inputAddress } = await inquirer.prompt([{
806
+ type: "input",
807
+ name: "inputAddress",
808
+ message: "Delivery address:",
809
+ validate: v => v.trim().length > 0 || "Address is required for delivery/shipping",
810
+ }]);
811
+ address = inputAddress.trim();
812
+ }
813
+ }
814
+
815
+ // Confirmation
816
+ if (!opts.yes) {
817
+ const inquirer = await import("inquirer").then(m => m.default);
818
+ console.log();
819
+ if (deliveryMethod) console.log(chalk.dim(` Method: ${deliveryMethod}`));
820
+ if (phone) console.log(chalk.dim(` Phone: ${phone}`));
821
+ if (address) console.log(chalk.dim(` Address: ${address}`));
822
+ console.log();
823
+ const { confirm } = await inquirer.prompt([{
824
+ type: "confirm",
825
+ name: "confirm",
826
+ message: `Place order for $${total.toFixed(2)}?`,
827
+ default: true,
828
+ }]);
829
+ if (!confirm) {
830
+ console.log(chalk.yellow("Order cancelled."));
831
+ return;
832
+ }
833
+ }
834
+
835
+ // Create order via API
836
+ const orderPayload = {};
837
+ if (deliveryMethod) orderPayload.deliveryMethod = deliveryMethod;
838
+ if (phone) orderPayload.phone = phone;
839
+ if (address) orderPayload.shippingAddress = address;
840
+
841
+ const result = await apiPost("/orders", orderPayload);
842
+
843
+ console.log();
844
+ console.log(chalk.green.bold(" ✓ Order created!"));
845
+ const orderId = result.order?.id || result.id;
846
+ const orderNum = result.order?.orderNumber || result.orderNumber;
847
+ if (orderNum) console.log(` Order: ${chalk.bold(orderNum)}`);
848
+ else if (orderId) console.log(` Order ID: ${chalk.bold(orderId)}`);
849
+ console.log(` Total: $${total.toFixed(2)}`);
850
+ if (deliveryMethod) console.log(` Delivery: ${deliveryMethod}`);
851
+ if (phone) console.log(` Phone: ${phone}`);
852
+ if (address) console.log(` Address: ${address}`);
853
+ console.log();
854
+ console.log(chalk.dim(" View your orders: tm orders"));
855
+ console.log();
744
856
  } catch (e) {
745
857
  console.error(chalk.red(e?.message || String(e)));
746
858
  process.exitCode = 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminalmarket",
3
- "version": "0.13.3",
3
+ "version": "0.14.0",
4
4
  "description": "TerminalMarket CLI — a curated marketplace for developers & founders (client for terminalmarket.app)",
5
5
  "bin": {
6
6
  "tm": "bin/tm.js"