@wallavi/vercel-build 0.1.6 → 0.1.7

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/dist/index.js +62 -68
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -774,24 +774,20 @@ var esquemaDeploymentPromocion = zod.z.object({
774
774
  aliases: zod.z.array(zod.z.string()).optional(),
775
775
  meta: zod.z.record(zod.z.unknown()).optional(),
776
776
  gitSource: zod.z.record(zod.z.unknown()).nullable().optional()
777
- }).passthrough().refine((d) => d.id !== void 0 || d.uid !== void 0, {
778
- message: "el deployment debe incluir id o uid"
779
- }).refine((d) => d.state !== void 0 || d.readyState !== void 0, {
780
- message: "el deployment debe incluir state o readyState"
781
- });
777
+ }).passthrough().refine((d) => Boolean(d.id || d.uid), "el deployment debe incluir id o uid").refine(
778
+ (d) => Boolean(d.state || d.readyState),
779
+ "el deployment debe incluir state o readyState"
780
+ );
782
781
  var esquemaListaDeploymentsPromocion = zod.z.object({ deployments: zod.z.array(esquemaDeploymentPromocion) }).passthrough();
783
782
  function limpiarIdOUrlDeploy(valor) {
784
- const s = valor.replace(REGEX_ANSI, "").trim().replace(/^https?:\/\//i, "").replace(/[/?#].*$/, "").replace(/[.,;]+$/, "").trim();
785
- return s || null;
783
+ return valor.replace(REGEX_ANSI, "").trim().replace(/^https?:\/\//i, "").replace(/[/?#].*$/, "").replace(/[.,;]+$/, "").trim() || null;
786
784
  }
787
785
  function extraerIdOUrlDeploy(salida, error = "") {
788
786
  const stdout = salida.replace(REGEX_ANSI, "");
789
787
  const texto = `${error}
790
788
  ${salida}`.replace(REGEX_ANSI, "");
791
- const urlsStdout = Array.from(
792
- stdout.matchAll(/^\s*(https?:\/\/[^\s\]"')>]+)/gim),
793
- (m) => m[1]
794
- );
789
+ const reLinea = /^\s*(https?:\/\/[^\s\]"')>]+)/gim;
790
+ const urlsStdout = Array.from(stdout.matchAll(reLinea), (m) => m[1]);
795
791
  const prod = /\bProduction\s*:\s*(https?:\/\/[^\s\]"')>]+)/i.exec(texto)?.[1];
796
792
  const alias = /\bAlias(?:ed)?\s*:\s*(https?:\/\/[^\s\]"')>]+)/i.exec(
797
793
  texto
@@ -803,23 +799,21 @@ ${salida}`.replace(REGEX_ANSI, "");
803
799
  return /\b(dpl_[a-zA-Z0-9]+)\b/.exec(texto)?.[1] ?? null;
804
800
  }
805
801
  function normalizarUrlHttps(u) {
806
- const s = u.trim().replace(/[.,;]+$/, "").replace(/\/+$/, "");
802
+ const s = u.trim().replace(/[.,;/]+$/, "");
807
803
  return /^https?:\/\//i.test(s) ? s : `https://${s}`;
808
804
  }
809
805
  function esDominioVercelApp(u) {
810
806
  const h = (limpiarIdOUrlDeploy(u) ?? "").toLowerCase();
811
807
  return h === "vercel.app" || h.endsWith(".vercel.app");
812
808
  }
809
+ function listaAliases(d) {
810
+ const crudos = Array.isArray(d.alias) ? d.alias : d.alias ? [d.alias] : [];
811
+ return [...crudos, ...d.aliases ?? []].map((c) => c.trim()).filter(Boolean);
812
+ }
813
813
  function extraerAliasProduccion(d) {
814
- const crudos = [
815
- ...Array.isArray(d.alias) ? d.alias : d.alias ? [d.alias] : [],
816
- ...d.aliases ?? []
817
- ].map((c) => c.trim()).filter(Boolean);
818
- if (crudos.length === 0)
819
- return d.url && !esDominioVercelApp(d.url) ? normalizarUrlHttps(d.url) : null;
820
- return normalizarUrlHttps(
821
- crudos.find((c) => !esDominioVercelApp(c)) ?? crudos[0]
822
- );
814
+ const c = listaAliases(d);
815
+ const u = c.find((x) => !esDominioVercelApp(x)) ?? c[0] ?? (d.url && !esDominioVercelApp(d.url) ? d.url : null);
816
+ return u ? normalizarUrlHttps(u) : null;
823
817
  }
824
818
  function obtenerShaCommit(opc, ej) {
825
819
  const explicito = opc.sha?.trim() || opc.env?.VERCEL_GIT_COMMIT_SHA?.trim();
@@ -827,10 +821,8 @@ function obtenerShaCommit(opc, ej) {
827
821
  for (const dir of [opc.carpeta, opc.cwd]) {
828
822
  if (!dir) continue;
829
823
  const cwd = ubicarEnRepo(dir, ej)?.raiz ?? dir;
830
- const r = ej("git", ["rev-parse", "HEAD"], {
831
- cwd,
832
- ...opc.env ? { env: opc.env } : {}
833
- });
824
+ const opcGit = { cwd, ...opc.env ? { env: opc.env } : {} };
825
+ const r = ej("git", ["rev-parse", "HEAD"], opcGit);
834
826
  if (r.codigo === 0 && r.salida.trim() !== "") return r.salida.trim();
835
827
  }
836
828
  return null;
@@ -847,8 +839,9 @@ function llamarApiVercel(rutaQuery, ctx, metodo = "GET") {
847
839
  const r = ctx.solicitar(`${ctx.baseUrl}${rutaQuery}`, auth, metodo);
848
840
  return r.estado >= 200 && r.estado < 300 ? { ok: true, cuerpo: r.cuerpo } : err(`HTTP ${r.estado} en ${metodo} ${rutaQuery}`);
849
841
  } catch (e) {
850
- const msg = e instanceof Error ? e.message : String(e);
851
- return err(`fallo de red en ${metodo} ${rutaQuery} (${msg})`);
842
+ return err(
843
+ `fallo de red en ${metodo} ${rutaQuery} (${e.message ?? e})`
844
+ );
852
845
  }
853
846
  }
854
847
  function obtenerShaDeployment(d) {
@@ -863,16 +856,14 @@ function obtenerShaDeployment(d) {
863
856
  }
864
857
  function validarIdentidadDeployment(d, ctx, fijar = false) {
865
858
  const id = d.id ?? d.uid;
866
- if (d.projectId !== ctx.projectId) {
859
+ if (d.projectId !== ctx.projectId)
867
860
  return err(
868
861
  `el deploy ${id} no confirma projectId=${JSON.stringify(d.projectId) ?? "ausente"} (esperado ${ctx.projectId})`
869
862
  );
870
- }
871
- if (d.target !== "production") {
863
+ if (d.target !== "production")
872
864
  return err(
873
865
  `el deploy ${id} no es de producci\xF3n (target=${JSON.stringify(d.target) ?? "ausente"}; esperado production)`
874
866
  );
875
- }
876
867
  const sha = obtenerShaDeployment(d);
877
868
  return sha && sha === ctx.sha ? { ok: true, valor: d, id, fijar } : err(
878
869
  `el deploy ${id} corresponde al SHA ${sha || "desconocido"} y no a ${ctx.sha}`
@@ -882,9 +873,8 @@ function pedirDeploymentsV6(ruta, ctx) {
882
873
  const resp = llamarApiVercel(ruta, ctx, "GET");
883
874
  if (!resp.ok) return resp;
884
875
  try {
885
- const r = esquemaListaDeploymentsPromocion.safeParse(
886
- JSON.parse(resp.cuerpo)
887
- );
876
+ const json = JSON.parse(resp.cuerpo);
877
+ const r = esquemaListaDeploymentsPromocion.safeParse(json);
888
878
  return r.success ? { ok: true, deployments: r.data.deployments } : err(`no se encontr\xF3 deployment de producci\xF3n para el SHA ${ctx.sha}`);
889
879
  } catch (e) {
890
880
  return err(`JSON inv\xE1lido en GET ${ruta} (${e.message})`);
@@ -901,20 +891,38 @@ function consultarDeploymentV13(idOrUrl, ctx) {
901
891
  return err(`JSON inv\xE1lido en GET ${ruta} (${e.message})`);
902
892
  }
903
893
  }
894
+ function hidratarCandidatoV6(d, ctx) {
895
+ const base = validarIdentidadDeployment(d, ctx, true);
896
+ const sha = obtenerShaDeployment(d);
897
+ if (sha && sha !== ctx.sha) return base;
898
+ const enReady = (d.readyState ?? d.state) === "READY";
899
+ if (base.ok && (!enReady || d.readySubstate && listaAliases(d).length > 0))
900
+ return base;
901
+ const detalle = consultarDeploymentV13(d.id ?? d.uid, ctx);
902
+ if (detalle.ok) {
903
+ const v = detalle.valor;
904
+ const valor = { ...d, ...v, url: v.url ?? d.url };
905
+ valor.alias = v.alias ?? d.alias;
906
+ valor.aliases = v.aliases ?? d.aliases;
907
+ valor.readySubstate = v.readySubstate ?? d.readySubstate;
908
+ return { ok: true, id: detalle.id, fijar: true, valor };
909
+ }
910
+ return detalle.motivo.startsWith("el deploy ") ? detalle : base;
911
+ }
904
912
  function resolverDeployment(idOrUrl, ctx) {
905
913
  const qBase = `${ctx.qTeam}&projectId=${encodeURIComponent(ctx.projectId)}&target=production`;
906
914
  const respaldoV6 = () => {
907
915
  const r = pedirDeploymentsV6(`/v6/deployments?${qBase}`, ctx);
908
916
  if (!r.ok) return r;
909
917
  const d = r.deployments.find((x) => obtenerShaDeployment(x) === ctx.sha);
910
- return d ? validarIdentidadDeployment(d, ctx, true) : err(`no se encontr\xF3 deployment de producci\xF3n para el SHA ${ctx.sha}`);
918
+ return d ? hidratarCandidatoV6(d, ctx) : err(`no se encontr\xF3 deployment de producci\xF3n para el SHA ${ctx.sha}`);
911
919
  };
912
920
  if (idOrUrl) {
913
921
  const c = consultarDeploymentV13(idOrUrl, ctx);
914
- if (c.ok || idOrUrl.startsWith("dpl_") || !c.motivo.includes("corresponde al SHA"))
915
- return c;
922
+ if (c.ok || idOrUrl.startsWith("dpl_")) return c;
916
923
  const respaldo = respaldoV6();
917
- return respaldo.ok ? respaldo : c;
924
+ if (respaldo.ok) return respaldo;
925
+ return c.motivo.startsWith("el deploy ") || !respaldo.motivo.startsWith("el deploy ") ? c : respaldo;
918
926
  }
919
927
  const lista = pedirDeploymentsV6(
920
928
  `/v6/deployments?${qBase}&sha=${encodeURIComponent(ctx.sha)}`,
@@ -923,21 +931,19 @@ function resolverDeployment(idOrUrl, ctx) {
923
931
  if (!lista.ok) return lista;
924
932
  if (lista.deployments.length === 0) return respaldoV6();
925
933
  const actual = lista.deployments.find((d) => obtenerShaDeployment(d) === ctx.sha) ?? lista.deployments[0];
926
- return validarIdentidadDeployment(actual, ctx, true);
934
+ return hidratarCandidatoV6(actual, ctx);
927
935
  }
928
936
  function esperarYPromoverDeploy(opc) {
929
- const {
930
- ejecutar: ej = ejecutar,
931
- solicitar = solicitarVercel,
932
- dormir = dormirSincrono,
933
- intervaloMs = INTERVALO_POLL_DEPLOY_MS,
934
- timeoutMs = TIMEOUT_POLL_DEPLOY_MS,
935
- maxIntentos
936
- } = opc;
937
- const token = opc.token?.trim() || opc.env?.VERCEL_TOKEN?.trim() || "";
938
- const teamId = opc.teamId?.trim() || opc.env?.VERCEL_ORG_ID?.trim() || "";
939
- const projectId = opc.projectId?.trim() || opc.env?.VERCEL_PROJECT_ID?.trim() || "";
940
- const baseUrl = (opc.baseUrl ?? opc.env?.VERCEL_API_URL)?.trim() || API_VERCEL_URL;
937
+ const ej = opc.ejecutar ?? ejecutar;
938
+ const solicitar = opc.solicitar ?? solicitarVercel;
939
+ const dormir = opc.dormir ?? dormirSincrono;
940
+ const intervaloMs = opc.intervaloMs ?? INTERVALO_POLL_DEPLOY_MS;
941
+ const timeoutMs = opc.timeoutMs ?? TIMEOUT_POLL_DEPLOY_MS;
942
+ const leer = (a, b) => a?.trim() || b?.trim() || "";
943
+ const token = leer(opc.token, opc.env?.VERCEL_TOKEN);
944
+ const teamId = leer(opc.teamId, opc.env?.VERCEL_ORG_ID);
945
+ const projectId = leer(opc.projectId, opc.env?.VERCEL_PROJECT_ID);
946
+ const baseUrl = leer(opc.baseUrl, opc.env?.VERCEL_API_URL) || API_VERCEL_URL;
941
947
  if (!token || !teamId || !projectId)
942
948
  return fallo("faltan credenciales de Vercel para promover el deploy");
943
949
  const sha = obtenerShaCommit(opc, ej);
@@ -948,17 +954,8 @@ function esperarYPromoverDeploy(opc) {
948
954
  const qTeam = `teamId=${encodeURIComponent(teamId)}`;
949
955
  const ctx = { qTeam, projectId, sha, token, solicitar, baseUrl };
950
956
  let idOrUrl = opc.urlDeploy != null ? limpiarIdOUrlDeploy(opc.urlDeploy) : extraerIdOUrlDeploy(opc.salidaDeploy ?? "", opc.errorDeploy ?? "");
951
- let transcurridoMs = 0;
952
- let intentos = 0;
953
- let deployListo = null;
954
- let deploymentId = "";
955
- const esperar = () => {
956
- if (maxIntentos !== void 0 && intentos >= maxIntentos || transcurridoMs + intervaloMs > timeoutMs)
957
- return false;
958
- dormir(intervaloMs);
959
- transcurridoMs += intervaloMs;
960
- return true;
961
- };
957
+ let transcurridoMs = 0, intentos = 0, deployListo = null, deploymentId = "";
958
+ const esperar = () => (opc.maxIntentos === void 0 || intentos < opc.maxIntentos) && transcurridoMs + intervaloMs <= timeoutMs && (dormir(intervaloMs), transcurridoMs += intervaloMs, true);
962
959
  while (deployListo === null) {
963
960
  intentos++;
964
961
  const r = resolverDeployment(idOrUrl, ctx);
@@ -969,11 +966,8 @@ function esperarYPromoverDeploy(opc) {
969
966
  const estado = actual.readyState ?? actual.state;
970
967
  if (estado === "ERROR" || estado === "CANCELED")
971
968
  return fallo(`el deploy ${deploymentId} termin\xF3 en estado ${estado}`);
972
- if (estado === "READY") {
973
- deployListo = actual;
974
- break;
975
- }
976
- if (!esperar())
969
+ if (estado === "READY") deployListo = actual;
970
+ else if (!esperar())
977
971
  return fallo(
978
972
  `timeout esperando a que el deploy ${deploymentId} llegue a READY (estado: ${estado})`
979
973
  );
@@ -1223,7 +1217,7 @@ function ejecutarDesplegar(opciones) {
1223
1217
  urlDeployPromovido = promocion.url;
1224
1218
  deploymentId = promocion.deploymentId;
1225
1219
  }
1226
- const urlSalud = opciones.urlSalud?.trim() || opciones.env.VERCEL_HEALTHCHECK_URL?.trim() || aliasPromovido || extraerUrlSalud(ultimoDeploy.salida, ultimoDeploy.error) || urlDeployPromovido;
1220
+ const urlSalud = opciones.urlSalud?.trim() || opciones.env.VERCEL_HEALTHCHECK_URL?.trim() || aliasPromovido || urlDeployPromovido || extraerUrlSalud(ultimoDeploy.salida, ultimoDeploy.error);
1227
1221
  if (!urlSalud) {
1228
1222
  opciones.error(
1229
1223
  redactarCredenciales(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallavi/vercel-build",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
5
  "description": "Detección de cambios y despliegue compartidos para los proyectos de Vercel del monorepo",
6
6
  "license": "MIT",