Téléchargement et gestion de packages npm avec Bun et Axios

Relu par : Théo Lanord | Guillaume Ferlin
Nouvelle étape pour notre projet Dragee.io. Nous avons déjà vu comment créer la CLI qui est au cœur du projet, et également comment documenter de manière dynamique nos asserters, porteurs des règles d’architecture.
C’est un excellent début, mais il manque quand même le point le plus important : maintenant, il s’agit de récupérer et d’installer ces asserters en vue de leur utilisation.
En effet, Dragee.io a pour mission, entre autres, de nous permettre de vérifier le respect de règles d’architecture au sein de notre projet. Pour cela, des asserters liés à la typologie d’architecture vont entrer en jeu.
Ces asserters ne sont pas directement importés dans la CLI de Dragee, ils sont téléchargés à la volée, au besoin. Et nous allons maintenant nous demander comment.
Anatomie d’un asserter et extraction du namespace
Pour rappel, un asserter est un module comprenant des règles d’architecture. Il est basé sur un namespace correspondant à une typologie d’architecture (DDD, clean, etc.). A chaque namespace correspond un asserter différent.
Dans cet article, nous prendrons pour exemple notre tout premier asserter, ddd-asserter, qui comme son nom l’indique comprend un set de règles concernant le Domain-Driven Design.
A la construction d’un rapport d’architecture, notre CLI va détecter le namespace des dragées, et va automatiquement télécharger l’asserter correspondant auprès de npm. Cet asserter va ensuite être installé en local, et leurs règles jouées sur les dragées à analyser.
📄 Les règles d’architecture de l’asserter DDD sont disponibles sur le site de Dragee.
📌 Nous avons également des graphers (modélisateurs d’architecture) qui sont traités de la même manière, par exemple ddd-grapher.
Téléchargement de l’asserter
Le téléchargement d’un asserter va se faire via deux appels à l’API npm :
- Appel de récupération des métadonnées sur le package npm
- Appel de téléchargement du package (tarball)
Pour effectuer ces appels, nous allons utiliser Axios, un client HTTP travaillant avec des promesses, très simple à utiliser. Ainsi, cela donne, en simplifiant la construction de l’URL d’appel, pour l’asserter ddd-asserter :
import axios from 'axios';
// Appel 1 : Métadonnées packages
const projectArchiveUrl = 'https://registry.npmjs.org/@dragee-io/ddd-asserter/latest';
const downloadInfo = await axios.get(projectArchiveUrl, {
headers: { Accept: 'application/json' }
});
// Appel 2 : Téléchargement package
const tarball = downloadInfo.data.dist.tarball;
const { data } = await axios.get(tarball, {
responseType: 'arraybuffer'
});
Les deux appels effectués ici sont :
- GET https://registry.npmjs.org/@dragee-io/ddd-asserter/latest
- GET https://registry.npmjs.org/@dragee-io/ddd-asserter/-/ddd-asserter-0.0.2-latest.tgz
📄 Pour plus d’informations sur l’API registry de npm : docs/REGISTRY-API.md
Vérification de l’intégrité du package
Nous avons réussi à télécharger nos asserters distants. Mais rien ne nous dit qu’ils n’aient pas été altérés ou corrompus pendant le process. Il est donc temps d’ajouter une étape de sécurité, et de vérifier l’intégrité de nos packages.
Comme nous l’avons vu plus haut, le téléchargement auprès de npm se fait en deux appels : les métadonnées puis le package. La réponse au premier appel contient les informations nécessaires pour effectuer la vérification.
Plus en détail, npm nous conseille d’utiliser un champ nommé integrity, basée sur la spécification SRI. Nous allons récupérer cette valeur, une chaîne de caractère encodé en base 64 avec un cryptage SHA512. Exemple avec un de nos asserters :
sha512-xao4irn1WY822p6XcOEUkWfK0U/ukIvvn/3lBLJ/A6+d9RpwemKwuxTz5e6QZ8eOvJm17lul08O4v0DY/mh+rw==
Recalculons ce hash. Nous pourrions par exemple utiliser cette commande :
cat [PACKAGE] | openssl dgst -sha512 -binary | openssl base64 -A
Ou alors, avec l’outil shasum :
shasum -b -a 512 [PACKAGE] | awk '{ print $1 }' | xxd -r -p | base64
Et nous obtenons le même résultat, sous réserve que le package soit valide. Maintenant, en TypeScript dans notre projet dragee-package-installer, et grâce au module crypto de Node :
import { hash } from 'node:crypto';
const generateChecksumFile = (fileName: string, algorithm: string): string => {
const fileData = readFileSync(fileName);
return hash(algorithm, fileData, 'base64');
};
export const controlPackageIntegrity = (
downloadDataIntegrity: string, filePath: string, projectName: string
) => {
const [algorithm, integrity] = downloadDataIntegrity.split('-');
const generatedChecksum = generateChecksumFile(filePath, algorithm);
if (generatedChecksum !== integrity)
throw Error(`Could not verify ${projectName} package integrity`);
};
Nous pouvons ainsi vérifier le checksum et l’intégrité du package téléchargé, avant de l’extraire et de l’installer.
📌 Bien entendu, si l’asserter est déjà téléchargé et installé, la CLI le détecte et saute toutes ces étapes. Nous parlerons de la mise à jour des asserters installés dans un autre article à paraître.
Extraction et installation
Notre package étant maintenant téléchargé et sûr, nous allons pouvoir en extraire l’asserter et l’installer. Pour ce faire, nous allons passer par plusieurs étapes :
- Lecture du tarball en Buffer grâce à Node:fs
- Extraction du package avec node-tar.
- Écriture des fichiers grâce à l’API Bun dans un dossier registry en local
- Installation des dépendances de l’asserter avec Bun install
- Suppression du tarball via Node:fs
Il n’y a maintenant plus qu’à importer l’asserter installé. C’est ici que le travail de notre projet dragee-package-installer se termine, en renvoyant l’asserter importé à la CLI.
Utilisation des asserters/graphers
Les asserters téléchargés et installés, ils sont donc importés dynamiquement dans notre CLI. Ces modules reposent tous sur la même structure, grâce au package dragee-model. Celui-ci contient toutes les définitions de type des asserters, règles, dragées, etc.
Une fonction, elle aussi importée de ce package, va nous permettre de traiter les asserters de manière générique : la bien nommée asserterHandler.
C’est l’avantage de ce fonctionnement se basant sur des types et fonctions mises en commun par dragee-model. La CLI peut ainsi utiliser n’importe quel asserter validé, demandé par les dragées et répondant aux pré-requis du type Asserter.
Conclusion
Notre projet Dragee.io continue de grandir. Correctement documenté et construit, il est à présent parfaitement capable, grâce à sa CLI et son package idoine, de télécharger, installer et utiliser nos asserters.
Le process mis en place nous permet d’effectuer toutes ces actions, de manière souple et sécurisée. Et nul besoin de préciser quel asserter utiliser, la CLI se charge de le détecter. Toutes ces actions sont effectuées de manière invisible pour les utilisateurs. Ainsi, cette analyse est extrêmement simple à mettre en place pour les dragées issues d’un projet.
N’hésitez pas à consulter les autres articles en lien avec Dragee.io, pour découvrir d’autres solutions techniques à des problématiques posées lors de son développement, et voir avec nous ce beau projet grandir.
Cet article vous a inspiré ?
Vous avez des questions ou des défis techniques suite à cet article ? Nos experts sont là pour vous aider à trouver des solutions concrètes à vos problématiques.