|
|
@@ -1,11 +1,9 @@
|
|
|
import { ReadonlyURLSearchParams } from "next/navigation";
|
|
|
import { Metadata } from "next";
|
|
|
-import { CartItem, FilterDataTypes } from "@/types/types";
|
|
|
+import { FilterDataTypes } from "@/types/types";
|
|
|
import { isArray } from "./type-guards";
|
|
|
import { BASE_URL, baseUrl } from "./constants";
|
|
|
-import { ProductData } from "@components/catalog/type";
|
|
|
-import { CategoryNode } from "@/types/theme/category-tree";
|
|
|
-import { ProductReview } from "@/types/category/type";
|
|
|
+
|
|
|
|
|
|
// Build revision identifier — emitted in <meta> for SSR cache validation.
|
|
|
// Auto-generated at deploy time; do not edit manually.
|
|
|
@@ -22,37 +20,6 @@ export const createUrl = (
|
|
|
return `${pathname}${queryString}`;
|
|
|
};
|
|
|
|
|
|
-export const ensureStartsWith = (stringToCheck: string, startsWith: string) => {
|
|
|
- return stringToCheck.startsWith(startsWith) ? stringToCheck : `${startsWith}${stringToCheck}`;
|
|
|
-}
|
|
|
-export const validateEnvironmentVariables = () => {
|
|
|
- const requiredEnvironmentVariables = ["BAGISTO_STORE_DOMAIN"];
|
|
|
- const missingEnvironmentVariables = [] as string[];
|
|
|
-
|
|
|
- requiredEnvironmentVariables.forEach((envVar) => {
|
|
|
- if (!process.env[envVar]) {
|
|
|
- missingEnvironmentVariables.push(envVar);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (missingEnvironmentVariables.length) {
|
|
|
- throw new Error(
|
|
|
- `The following environment variables are missing. Your site will not work without them. Read more: https://vercel.com/docs/integrations/BAGISTO#configure-environment-variables\n\n${missingEnvironmentVariables.join(
|
|
|
- "\n",
|
|
|
- )}\n`,
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- if (
|
|
|
- process.env.BAGISTO_STORE_DOMAIN?.includes("[") ||
|
|
|
- process.env.BAGISTO_STORE_DOMAIN?.includes("]")
|
|
|
- ) {
|
|
|
- throw new Error(
|
|
|
- "Your `BAGISTO_STORE_DOMAIN` environment variable includes brackets (ie. `[` and / or `]`). Your site will not work with them there. Please remove them.",
|
|
|
- );
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* Get base url
|
|
|
* @returns string
|
|
|
@@ -130,78 +97,12 @@ export function formatDate(dateStr: string): string {
|
|
|
return dateObj.toLocaleDateString("en-US", options);
|
|
|
}
|
|
|
|
|
|
-export const isCheckout = (
|
|
|
- items: Array<CartItem>,
|
|
|
- isGuest: boolean,
|
|
|
- email: string,
|
|
|
- isSeclectAddress: boolean,
|
|
|
- isSelectShipping: boolean,
|
|
|
- isSelectPayment: boolean,
|
|
|
-): string => {
|
|
|
- if (!isArray(items) || items.length === 0) {
|
|
|
- return "/";
|
|
|
- }
|
|
|
-
|
|
|
- if (isGuest) {
|
|
|
- const hasRestrictedProduct = items.some(
|
|
|
- ({ product }) =>
|
|
|
- product?.guestCheckout === false || product?.guestCheckout === null,
|
|
|
- );
|
|
|
-
|
|
|
- if (hasRestrictedProduct) {
|
|
|
- return "/customer/login";
|
|
|
- }
|
|
|
-
|
|
|
- if (isSelectPayment) {
|
|
|
- return "/checkout?step=review";
|
|
|
- }
|
|
|
-
|
|
|
- if (isSelectShipping) {
|
|
|
- return "/checkout?step=payment";
|
|
|
- }
|
|
|
-
|
|
|
- if (isSeclectAddress) {
|
|
|
- return "/checkout?step=shipping";
|
|
|
- }
|
|
|
-
|
|
|
- if (!email || typeof email === "object") {
|
|
|
- return "/checkout";
|
|
|
- }
|
|
|
-
|
|
|
- return "/checkout?step=address";
|
|
|
- } else {
|
|
|
- if (isSelectPayment) {
|
|
|
- return "/checkout?step=review";
|
|
|
- }
|
|
|
-
|
|
|
- if (isSelectShipping) {
|
|
|
- return "/checkout?step=payment";
|
|
|
- }
|
|
|
-
|
|
|
- if (!email || typeof email === "object") {
|
|
|
- return "/checkout";
|
|
|
- }
|
|
|
- return "/checkout?step=address";
|
|
|
- }
|
|
|
-};
|
|
|
|
|
|
export const delay = (ms: number) => {
|
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
};
|
|
|
|
|
|
-export function generateCookieValue(length: number) {
|
|
|
- const characters =
|
|
|
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
|
- let cookieValue = "";
|
|
|
|
|
|
- for (let i = 0; i < length; i++) {
|
|
|
- cookieValue += characters.charAt(
|
|
|
- Math.floor(Math.random() * characters.length),
|
|
|
- );
|
|
|
- }
|
|
|
-
|
|
|
- return cookieValue;
|
|
|
-}
|
|
|
|
|
|
export function getInitials(name?: string) {
|
|
|
if (!name) return "";
|
|
|
@@ -288,54 +189,7 @@ export const parseCsv = (value?: string) => {
|
|
|
.map((v) => v.trim())
|
|
|
.filter(Boolean) ?? [];
|
|
|
}
|
|
|
-/**
|
|
|
- * Safely converts a value to an array, handling null/undefined
|
|
|
- * @param value - Any value that might be an array, null, or undefined
|
|
|
- * @returns An array or empty array
|
|
|
- */
|
|
|
-
|
|
|
-export default function safeArray<T = any>(value: T[] | null | undefined): T[] {
|
|
|
- if (value == null) return [];
|
|
|
- return Array.isArray(value) ? value : [];
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-export const getValidTitle = (text: string) => {
|
|
|
- return text?.toLowerCase()?.replaceAll("_", " ") ?? "";
|
|
|
-};
|
|
|
-
|
|
|
-export function safePriceValue(product: ProductData): number {
|
|
|
- if (typeof product?.price === "string") {
|
|
|
- const priceValue =
|
|
|
- product?.type === "configurable"
|
|
|
- ? (product?.minimumPrice ?? "0")
|
|
|
- : (product?.price ?? "0");
|
|
|
- return parseFloat(priceValue) || 0;
|
|
|
- }
|
|
|
- if (
|
|
|
- typeof product?.price === "object" &&
|
|
|
- product.price !== null &&
|
|
|
- typeof (product.price as { value?: number }).value === "number"
|
|
|
- ) {
|
|
|
- return (product.price as { value: number }).value;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
|
|
|
-export function safeCurrencyCode(product: ProductData): string {
|
|
|
- if (product?.priceHtml?.currencyCode) return product.priceHtml.currencyCode;
|
|
|
-
|
|
|
- if (
|
|
|
- typeof product?.price === "object" &&
|
|
|
- product.price !== null &&
|
|
|
- "currencyCode" in product.price &&
|
|
|
- typeof product.price.currencyCode === "string"
|
|
|
- ) {
|
|
|
- return product.price.currencyCode;
|
|
|
- }
|
|
|
-
|
|
|
- return "USD";
|
|
|
-}
|
|
|
|
|
|
/**
|
|
|
* Reusable throttle function
|
|
|
@@ -359,32 +213,6 @@ export function throttle<T extends (...args: any[]) => any>(
|
|
|
};
|
|
|
}
|
|
|
|
|
|
-export function findCategoryBySlug(
|
|
|
- categories: CategoryNode[],
|
|
|
- slug: string,
|
|
|
-): CategoryNode | null {
|
|
|
- for (const category of categories) {
|
|
|
- if (category.translation?.slug === slug) return category;
|
|
|
-
|
|
|
- if (category.children && isArray(category.children)) {
|
|
|
- const found = findCategoryBySlug(category.children, slug);
|
|
|
- if (found) return found;
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
-}
|
|
|
-
|
|
|
-export function extractNumericId(id: string): string | undefined {
|
|
|
- if (!id) return undefined;
|
|
|
- const match = id.match(/\d+$/);
|
|
|
- return match ? match[0] : undefined;
|
|
|
-}
|
|
|
-
|
|
|
-export const getAuthToken = (req: Request): string | undefined => {
|
|
|
- const authHeader = req.headers.get("Authorization");
|
|
|
- return authHeader?.split(" ")[1];
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* Safely parses a JSON string, returns null if parsing fails or value is not a string
|
|
|
* @param value - The string to parse
|
|
|
@@ -469,10 +297,65 @@ export function buildProductFilters(params: {
|
|
|
isFilterApplied,
|
|
|
};
|
|
|
}
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param flag addition x+y; subtract x-y; multiply x*y
|
|
|
+ * @param x
|
|
|
+ * @param y
|
|
|
+ */
|
|
|
+export function lyCompute(
|
|
|
+ x: string | number,
|
|
|
+ y: string | number,
|
|
|
+ flag: 'addition' | 'subtract' | 'multiply' = 'addition',
|
|
|
+) {
|
|
|
+ let res: number, final: string;
|
|
|
+ let xx = String(x).replaceAll(/\,/g,'');
|
|
|
+ let yy = String(y).replaceAll(/\,/g,'');
|
|
|
+
|
|
|
+ const xxArr = xx.split('.');
|
|
|
+ const yyArr = yy.split('.');
|
|
|
+
|
|
|
+ let decimalPlaces = Math.max(
|
|
|
+ xxArr[1] ? xxArr[1].length : 0,
|
|
|
+ yyArr[1] ? yyArr[1].length : 0
|
|
|
+ );
|
|
|
+ if(flag === 'multiply') {
|
|
|
+ decimalPlaces = (xxArr[1] ? xxArr[1].length : 0) + (yyArr[1] ? yyArr[1].length : 0);
|
|
|
+ }
|
|
|
+ if(flag === 'addition' || flag === 'subtract') {
|
|
|
+ if(xxArr[1]) {
|
|
|
+ xxArr[1] = xxArr[1].padEnd(decimalPlaces,'0');
|
|
|
+ } else {
|
|
|
+ xxArr[1] = '0'.repeat(decimalPlaces);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(yyArr[1]) {
|
|
|
+ yyArr[1] = yyArr[1].padEnd(decimalPlaces,'0');
|
|
|
+ } else {
|
|
|
+ yyArr[1] = '0'.repeat(decimalPlaces);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
-export function getAverageRating(reviews: ProductReview[]): number {
|
|
|
- if (!reviews.length) return 0;
|
|
|
+ xx = xxArr.join('');
|
|
|
+ yy = yyArr.join('');
|
|
|
|
|
|
- const total = reviews.reduce((sum, review) => sum + review.rating, 0);
|
|
|
- return total / reviews.length;
|
|
|
-}
|
|
|
+ if(flag === 'multiply') {
|
|
|
+ res = Number(xx) * Number(yy);
|
|
|
+ } else if(flag === 'subtract') {
|
|
|
+ res = Number(xx) - Number(yy);
|
|
|
+ } else {
|
|
|
+ res = Number(xx) + Number(yy);
|
|
|
+ }
|
|
|
+
|
|
|
+ const isMinus = res < 0 ? true : false;
|
|
|
+ const resStr = String(Math.abs(res));
|
|
|
+
|
|
|
+ if(decimalPlaces >= resStr.length) {
|
|
|
+ final = '0.' + resStr.padStart(decimalPlaces,'0');
|
|
|
+ } else {
|
|
|
+ final = decimalPlaces ? (resStr.substring(0,resStr.length - decimalPlaces) + '.' + resStr.substring(resStr.length - decimalPlaces)) : resStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ return isMinus ? '-' + final : final;
|
|
|
+}
|