Skip to content

Agregar un pais

Jose Luiz Rodrigues edited this page Sep 10, 2026 · 2 revisions

Agregar un país

Sumar un país es tocar cinco lugares, en este orden. Saltear uno hace que el paquete compile y falle recién en tiempo de ejecución, así que conviene seguirlos tal cual.

En los ejemplos, xx es el código de dos letras en minúscula.

1. Los módulos del país

src/xx/
  index.ts        # re-exporta todos los submódulos
  [documento].ts  # uno o más
  currency.ts
  phone.ts
  zipcode.ts

Cada archivo implementa la interfaz correspondiente de src/types.ts. No se inventan contratos.

// src/xx/documento.ts
import { onlyDigits, safeStr } from '../utils.js'

export const mask = '###.###.###-#'

export function strip(value: string): string {
  return onlyDigits(safeStr(value))
}

export function format(value: string): string {
  const d = strip(value)
  if (!d) return ''
  // ...
}

export function validate(value: string): boolean {
  const d = strip(safeStr(value))
  if (d.length !== 10) return false
  // ...
}

safeStr es lo que garantiza la regla defensiva. Empezá siempre por ahí.

// src/xx/index.ts
export * as documento from './documento.js'
export * as currency from './currency.js'
export * as phone from './phone.js'
export * as zipcode from './zipcode.js'

Los imports internos llevan extensión .js aunque los archivos sean .ts. Lo exige el resolver de ESM de Node.

2. El export en la raíz

// src/index.ts
export * as xx from './xx/index.js'

3. El entry de tsup

// tsup.config.ts
entry: {
  // ...
  'xx/index': 'src/xx/index.ts',
}

4. El export de package.json

"./xx": {
  "types": "./dist/xx/index.d.ts",
  "import": "./dist/xx/index.js",
  "require": "./dist/xx/index.cjs"
}

Los pasos 3 y 4 van juntos siempre. Si agregás el entry y olvidás el export, el archivo se construye pero @zeluizr/palta/xx no resuelve. Si agregás el export y olvidás el entry, el subpath apunta a un archivo que no existe. Ese es el error más común.

5. Los tests

tests/xx/
  documento.test.ts
  currency.test.ts
  phone.test.ts
  zipcode.test.ts

tests/ es un espejo exacto de src/. Los tests importan directo de src/:

import { describe, it, expect } from 'vitest'
import * as documento from '../../src/xx/documento.js'

describe('xx.documento', () => {
  it('formatea', () => {
    expect(documento.format('9001234561')).toBe('900.123.456-1')
  })

  it('valida', () => {
    expect(documento.validate('900.123.456-1')).toBe(true)
    expect(documento.validate('900.123.456-2')).toBe(false)
  })

  it('no lanza con entradas vacías', () => {
    expect(documento.format('')).toBe('')
    expect(documento.validate(null as unknown as string)).toBe(false)
    expect(documento.strip(undefined as unknown as string)).toBe('')
  })
})

Cobertura mínima: 94% en líneas y statements, 98% en funciones, 90% en ramas.

Verificar

npm run lint
npm run test:coverage
npm run build

Y probá el subpath contra el build:

node -e "import('./dist/xx/index.js').then(m => console.log(Object.keys(m)))"

Opcional: sumarlo a detect()

detect() no cubre los 23 países y no hace falta que lo haga. Si el documento nuevo es razonablemente distinguible por largo o por forma, se puede agregar en src/detect.ts: importar validate y format del módulo y meter el chequeo en la rama del largo correspondiente.

El orden dentro de cada rama importa: gana el primero que valida. Antes de sumar un documento ahí, mirá Detección para entender qué se puede romper.

Checklist

  • src/xx/ con los módulos y su index.ts
  • export * as xx en src/index.ts
  • entry en tsup.config.ts
  • export en package.json
  • tests en tests/xx/ con los umbrales de cobertura en verde
  • npm run lint, npm run test:coverage y npm run build en verde
  • tabla de países actualizada en el README y en Países

Ver también: Contribuir, Algoritmos, Arquitectura.

Clone this wiki locally