Merge fix/adr0006-import-handle-ascii-safe into main
Build and Push Medusa / Escaneo de Secretos (Gitleaks) (push) Successful in 40s
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 29m54s

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01SEsGCsCmxkyXi9XctNdrT1
This commit is contained in:
devopsandClaude Sonnet 5 committed 2026-09-06 03:43:55 +00:00
commit 0fb904b9ac
1 file changed
+23
@@ -53,6 +53,28 @@ type RowResult = {
error?: string; error?: string;
}; };
// Medusa genera el handle por defecto solo en minusculas + espacios a
// guiones, sin quitar tildes/enies -- confirmado en vivo: 3 productos
// importados con titulo acentuado (ej. "niñas", "Lógicos") quedaron con
// handle como "...niñas..." y daban 404 real al entrar por
// shop.cruzcloud.net (el tunel/ingress publico rompe rutas con UTF-8
// no-ASCII en el path, aunque el mismo request funciona perfecto pegandole
// directo al servicio dentro del cluster). Se genera el handle nosotros
// mismos, ASCII-only, en vez de dejarselo al default de Medusa. El sufijo
// corto evita colisiones entre titulos parecidos/repetidos sin necesidad
// de revisar unicidad antes de crear.
function slugify(title: string, uniquePart: string): string {
const base = title
.normalize("NFD")
.replace(/[̀-ͯ]/g, "")
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "")
.slice(0, 80)
.replace(/-+$/g, "");
return `${base || "producto"}-${uniquePart}`;
}
function extensionFromContentType(contentType: string | null, url: string): string { function extensionFromContentType(contentType: string | null, url: string): string {
if (contentType?.includes("png")) return "png"; if (contentType?.includes("png")) return "png";
if (contentType?.includes("webp")) return "webp"; if (contentType?.includes("webp")) return "webp";
@@ -201,6 +223,7 @@ export async function POST(req: MedusaRequest<{ csv: string }>, res: MedusaRespo
products: [ products: [
{ {
title, title,
handle: slugify(title, `${Date.now().toString(36)}${index}`),
description: row.descripcion || undefined, description: row.descripcion || undefined,
status: "published", status: "published",
thumbnail: uploadedFiles[0]?.url, thumbnail: uploadedFiles[0]?.url,