Compare commits
1 Commits
bae85033e0
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9a7c7e942 |
@@ -1,6 +1,7 @@
|
|||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import { getDecryptedTenantEcommerceConfig } from "../db/repo.js";
|
import { getDecryptedTenantEcommerceConfig } from "../db/repo.js";
|
||||||
import { debug } from "../../shared/debug.js";
|
import { debug } from "../../shared/debug.js";
|
||||||
|
import { buildWooApiBase } from "../../shared/wooApiBase.js";
|
||||||
|
|
||||||
// --- Simple in-memory lock to serialize work per key (e.g. wa_chat_id) ---
|
// --- Simple in-memory lock to serialize work per key (e.g. wa_chat_id) ---
|
||||||
const locks = new Map();
|
const locks = new Map();
|
||||||
@@ -172,7 +173,7 @@ export async function createWooCustomer({ tenantId, wa_chat_id, phone, name }) {
|
|||||||
throw new Error("consumer_secret not set");
|
throw new Error("consumer_secret not set");
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const base = `${cfg.base_url.replace(/\/+$/, "")}/wp-json/${cfg.api_version || "wc/v3"}`;
|
const base = buildWooApiBase(cfg.base_url, cfg.api_version);
|
||||||
const email = `${phone || wa_chat_id}@no-email.local`;
|
const email = `${phone || wa_chat_id}@no-email.local`;
|
||||||
const username = wa_chat_id;
|
const username = wa_chat_id;
|
||||||
const timeout = Math.max(cfg.timeout_ms ?? 20000, 20000);
|
const timeout = Math.max(cfg.timeout_ms ?? 20000, 20000);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { getDecryptedTenantEcommerceConfig } from "../2-identity/db/repo.js";
|
|||||||
import { debug as dbg } from "../shared/debug.js";
|
import { debug as dbg } from "../shared/debug.js";
|
||||||
import { getSnapshotPriceByWooId, getSnapshotItemsByIds } from "../shared/wooSnapshot.js";
|
import { getSnapshotPriceByWooId, getSnapshotItemsByIds } from "../shared/wooSnapshot.js";
|
||||||
import { normalizeUnitToken } from "../shared/sellUnitPolicy.js";
|
import { normalizeUnitToken } from "../shared/sellUnitPolicy.js";
|
||||||
|
import { buildWooApiBase } from "../shared/wooApiBase.js";
|
||||||
import * as ordersRepo from "./ordersRepo.js";
|
import * as ordersRepo from "./ordersRepo.js";
|
||||||
|
|
||||||
// --- Simple in-memory lock to serialize work per key ---
|
// --- Simple in-memory lock to serialize work per key ---
|
||||||
@@ -90,8 +91,7 @@ async function getWooClient({ tenantId }) {
|
|||||||
(() => {
|
(() => {
|
||||||
throw new Error("consumer_secret not set");
|
throw new Error("consumer_secret not set");
|
||||||
})();
|
})();
|
||||||
const apiVersion = cfg.api_version || "wc/v3";
|
const base = buildWooApiBase(cfg.base_url, cfg.api_version);
|
||||||
const base = `${cfg.base_url.replace(/\/+$/, "")}/wp-json/${apiVersion}`;
|
|
||||||
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString("base64");
|
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString("base64");
|
||||||
return {
|
return {
|
||||||
base,
|
base,
|
||||||
|
|||||||
13
src/modules/shared/wooApiBase.js
Normal file
13
src/modules/shared/wooApiBase.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* Construye la URL base de la API REST de WooCommerce de forma idempotente.
|
||||||
|
*
|
||||||
|
* Acepta tanto el formato "limpio" (https://store.com) como el formato
|
||||||
|
* completo (https://store.com/wp-json/wc/v3) que muchas docs/operadores
|
||||||
|
* usan al copiar la URL. Si ya viene con /wp-json/, se respeta tal cual.
|
||||||
|
*/
|
||||||
|
export function buildWooApiBase(baseUrl, apiVersion = "wc/v3") {
|
||||||
|
const cleanBase = String(baseUrl || "").replace(/\/+$/, "");
|
||||||
|
const cleanVersion = String(apiVersion || "wc/v3").replace(/^\/+|\/+$/g, "");
|
||||||
|
if (cleanBase.includes("/wp-json/")) return cleanBase;
|
||||||
|
return `${cleanBase}/wp-json/${cleanVersion}`;
|
||||||
|
}
|
||||||
25
src/modules/shared/wooApiBase.test.js
Normal file
25
src/modules/shared/wooApiBase.test.js
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { buildWooApiBase } from "./wooApiBase.js";
|
||||||
|
|
||||||
|
describe("buildWooApiBase", () => {
|
||||||
|
it("agrega /wp-json/wc/v3 al base limpio", () => {
|
||||||
|
expect(buildWooApiBase("https://x.com", "wc/v3")).toBe("https://x.com/wp-json/wc/v3");
|
||||||
|
});
|
||||||
|
it("normaliza trailing slash del base", () => {
|
||||||
|
expect(buildWooApiBase("https://x.com/", "wc/v3")).toBe("https://x.com/wp-json/wc/v3");
|
||||||
|
expect(buildWooApiBase("https://x.com///", "wc/v3")).toBe("https://x.com/wp-json/wc/v3");
|
||||||
|
});
|
||||||
|
it("idempotente: respeta base que ya incluye /wp-json/", () => {
|
||||||
|
expect(buildWooApiBase("https://x.com/wp-json/wc/v3", "wc/v3")).toBe("https://x.com/wp-json/wc/v3");
|
||||||
|
expect(buildWooApiBase("https://x.com/wp-json/wc/v3/", "wc/v3")).toBe("https://x.com/wp-json/wc/v3");
|
||||||
|
});
|
||||||
|
it("respeta versión distinta si ya viene en la URL", () => {
|
||||||
|
expect(buildWooApiBase("https://x.com/wp-json/wc/v2", "wc/v3")).toBe("https://x.com/wp-json/wc/v2");
|
||||||
|
});
|
||||||
|
it("usa wc/v3 por default si no se pasa versión", () => {
|
||||||
|
expect(buildWooApiBase("https://x.com")).toBe("https://x.com/wp-json/wc/v3");
|
||||||
|
});
|
||||||
|
it("no rompe con base null/empty", () => {
|
||||||
|
expect(buildWooApiBase(null)).toBe("/wp-json/wc/v3");
|
||||||
|
expect(buildWooApiBase("")).toBe("/wp-json/wc/v3");
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -2,6 +2,7 @@ import { pool } from "./db/pool.js";
|
|||||||
import { getDecryptedTenantEcommerceConfig } from "../2-identity/db/repo.js";
|
import { getDecryptedTenantEcommerceConfig } from "../2-identity/db/repo.js";
|
||||||
import { debug as dbg } from "./debug.js";
|
import { debug as dbg } from "./debug.js";
|
||||||
import { computeAllowedOrderUnits } from "./sellUnitPolicy.js";
|
import { computeAllowedOrderUnits } from "./sellUnitPolicy.js";
|
||||||
|
import { buildWooApiBase } from "./wooApiBase.js";
|
||||||
|
|
||||||
async function fetchWoo({ url, method = "GET", body = null, timeout = 20000, headers = {} }) {
|
async function fetchWoo({ url, method = "GET", body = null, timeout = 20000, headers = {} }) {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
@@ -58,8 +59,7 @@ async function getWooClient({ tenantId }) {
|
|||||||
(() => {
|
(() => {
|
||||||
throw new Error("consumer_secret not set");
|
throw new Error("consumer_secret not set");
|
||||||
})();
|
})();
|
||||||
const apiVersion = cfg.api_version || "wc/v3";
|
const base = buildWooApiBase(cfg.base_url, cfg.api_version);
|
||||||
const base = `${cfg.base_url.replace(/\/+$/, "")}/wp-json/${apiVersion}`;
|
|
||||||
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString("base64");
|
const auth = Buffer.from(`${consumerKey}:${consumerSecret}`).toString("base64");
|
||||||
return {
|
return {
|
||||||
base,
|
base,
|
||||||
|
|||||||
Reference in New Issue
Block a user