npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@amsom-habitat/mailer-sender

v1.0.1

Published

Connecteur vers l'API Mail interne : envoi par template ou en corps libre, avec garde-fou anti-spam hors production (portage Node du package PHP amsom-habitat/mailer-sender).

Readme

@amsom-habitat/mailer-sender

Connecteur vers l'API Mail interne : envoi par template nommé ou en corps libre, garde-fou anti-spam hors production, erreurs typées.

Portage Node du package Composer amsom-habitat/mailer-sender. Là où la version PHP s'appuyait sur MailerInterface/Twig de Symfony, cette version se contente d'appeler l'API Mail en HTTP : aucune dépendance runtime, fetch natif (Node ≥ 18).

Installation

npm install @amsom-habitat/mailer-sender

@nestjs/common est une peerDependency optionnelle, requise seulement pour le sous-export /nest.

Configuration

| Option | Type | Défaut | Rôle | |---|---|---|---| | baseUrl | string | — | base URL de l'API Mail, sans slash final (obligatoire) | | env | string | undefined | tout ce qui n'est pas 'prod' active le garde-fou | | devRecipient | string | [email protected] | destinataire de repli hors production | | fetch | typeof fetch | globalThis.fetch | implémentation à utiliser (tests, proxy, instrumentation) | | logger | { warn(msg) } | aucun | journal des réponses en erreur |

Garde-fou anti-spam

Hors production, tous les mails partent vers devRecipient — jamais vers le vrai destinataire. La règle est dans le package précisément pour ne pas être réécrite (ni oubliée) dans chaque application :

new MailerSender({ baseUrl, env: 'prod' }).resolveRecipient('[email protected]')  // [email protected]
new MailerSender({ baseUrl, env: 'dev'  }).resolveRecipient('[email protected]')  // [email protected]

Un devRecipient défini mais vide retombe sur le défaut, plutôt que d'envoyer à une adresse vide.

Utilisation

Node « nu »

import { MailerSender } from '@amsom-habitat/mailer-sender'

const mailer = new MailerSender({
  baseUrl: process.env.API_MAIL_URL!,
  env: process.env.MAIL_ENV,
  devRecipient: process.env.MAIL_DEV_RECIPIENT,
  logger: console,
})

// 1. template nommé — POST {baseUrl}/send_prelevement_auto
await mailer.send('send_prelevement_auto', {
  emailDestinataire: '[email protected]',
  subject: 'Votre prélèvement automatique',
  body: { nom: 'DUPONT', montant: '345,20 €' },
  cc: '[email protected]',
})

// 2. corps libre — POST {baseUrl}/send_custom
await mailer.sendCustom({
  emailDestinataire: '[email protected]',
  subject: 'Suivi de votre demande',
  body: { message: '<p>Votre demande a bien été enregistrée.</p>' },
  templateConfig: { logo: 'logoAmsomEtMoi' },
})

NestJS

// app.module.ts
import { MailerModule } from '@amsom-habitat/mailer-sender/nest'

@Module({
  imports: [
    MailerModule.forRootAsync({
      isGlobal: true,
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        baseUrl: config.getOrThrow('API_MAIL_URL'),
        env: config.get('MAIL_ENV'),
        devRecipient: config.get('MAIL_DEV_RECIPIENT'),
      }),
    }),
  ],
})
export class AppModule {}
import { MailService } from '@amsom-habitat/mailer-sender/nest'

@Injectable()
export class SollicitationService {
  constructor(private readonly mail: MailService) {}

  notifier(email: string, message: string) {
    return this.mail.sendCustom({
      emailDestinataire: email,
      subject: 'Votre sollicitation',
      body: { message },
    })
  }
}

Payload envoyé

Les deux méthodes construisent le corps attendu par l'API Mail, avec les noms de champs de celle-ci (sujet, attachement…). Les champs absents sont explicitement à null, comme le faisait la version PHP.

sendCustom ajoute le bloc de mise en forme, dont les défauts maison : logo: 'logoAmsomEtMoi', bonjour: true, showFooter: true, showRemerciement: true. templateConfig permet de surcharger n'importe lequel de ces réglages ; les autres gardent leur défaut.

Erreurs

| Cas | Erreur | status | |---|---|---| | API injoignable (échec réseau) | HttpClientError | 503 | | Réponse non-2xx | HttpClientError | statut amont |

Le corps d'erreur renvoyé par l'API Mail est journalisé, jamais exposé : certaines API maison renvoient une trace complète qu'il ne faut pas laisser fuiter vers un client.

Côté NestJS, MailService traduit ces erreurs en exceptions Nest (httpClientErrorToHttpException : 503 → ServiceUnavailableException, sinon HttpException du statut amont). L'option mapError permet de fournir sa propre traduction.

API publique

@amsom-habitat/mailer-sender

| Export | Rôle | |---|---| | MailerSender | send(template, params), sendCustom(params), resolveRecipient(email) | | HttpClientError | erreur d'appel (status, label, body) | | fetchOk(url, init, label, deps?) | helper HTTP réutilisable pour d'autres clients d'API internes | | MailerSenderOptions, MailResult, SendMailParams, SendMailCustomParams, TemplateConfig | types |

@amsom-habitat/mailer-sender/nest

| Export | Rôle | |---|---| | MailerModule.forRoot(options) / forRootAsync(options) | module fournissant MailService | | MailService | version injectable, erreurs traduites en exceptions Nest | | httpClientErrorToHttpException(err) | traduction par défaut | | MAILER_MODULE_OPTIONS | jeton d'injection des options |

Développement

npm install
npm run build   # tsc → dist/ (CommonJS + .d.ts)
npm run lint
npm test        # jest

Le package est publié en CommonJS : les API NestJS maison sont en CJS, un paquet ESM-only n'y serait pas importable. La carte exports du package.json laisse la place à un build ESM ultérieur.

Versionnage

SemVer, une entrée par version dans changelog.md (## VX.Y.Z - JJ/MM/AAAA). check-version.sh refuse une publication dont la version n'est pas décrite dans le changelog, ou qui porte un suffixe de pré-release.

make publish        # main : lint + build + test + check-version + tag git + npm publish
make alpha_publish  # dev  : publication d'une beta