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

@mostajs/teams

v0.1.0

Published

Annuaire d'organisation transverse : équipes, appartenances (rôle DANS l'équipe) et affectation d'une équipe à une cible générique {type,id} (rôle SUR la cible). Cœur headless, persistance injectée, aligné SCIM 2.0 Group. N'accorde aucun droit — l'autoris

Downloads

172

Readme

@mostajs/teams — l'annuaire d'organisation

Auteur : Dr Hamid MADANI [email protected] · Licence AGPL-3.0-or-later · N1, zéro dépendance

Équipes, appartenances (le rôle dans l'équipe) et affectations d'une équipe à une cible générique {type, id} (le rôle sur la cible). Cœur headless, aucune I/O : la persistance est injectée. Il répond à « qui travaille sur quoi », et à rien d'autre.

L'invariant fondateur — il n'accorde aucun droit

Aucun can(), aucune importation de @mostajs/rbac, aucun type de cible connu d'avance. Il livre scopesOf(userId) ; c'est l'application qui construit le pont vers son moteur d'autorisation et qui décide. Fondement : RFC 7643 §4.2 — un Group porte un displayName et des members[], et la sémantique des autorisations y est explicitement hors périmètre. Un test le garde (T13).

Savoir qui appartient à quoi et décider ce qui est permis sont deux métiers. Les fondre donne un annuaire qui distribue des pouvoirs en silence.

Installer

npm i @mostajs/teams

Composer

import { createTeams, createMemoryRepositories } from '@mostajs/teams';

const teams = createTeams({
  repositories: createMemoryRepositories(),      // en production : vos dépôts (data-plug côté app)
  roles: ['owner', 'dev', 'tester', 'member'],   // le vocabulaire MÉTIER est déclaré par l'app
});

const noyau = await teams.create({ key: 'noyau', name: 'Équipe noyau' });
await teams.members.add(noyau.id, 'u-42', 'dev');
await teams.assignments.assign(noyau.id, { type: 'projet', id: 'collabtrax' }, 'owner');

await teams.peopleOfTarget({ type: 'projet', id: 'collabtrax' });
// → [{ userId:'u-42', teamKey:'noyau', teamRole:'dev', assignmentRole:'owner', … }]

La clé d'une équipe est stable à vie : la renommer est refusé. Les liens, les exports et les historiques qui la citent restent vrais — un identifiant qui bouge périme tout ce qui le référence.

Le vocabulaire des rôles est une donnée, pas du code

Le moteur ne possède aucun mot : il impose la règle (« un rôle hors vocabulaire est refusé »). Le défaut est un seed minimal — ['owner','member'] et ['owner','contributor','observer'] — vrai dans tout domaine. Livrer dev et tester rendrait ce module implicitement « informatique », alors qu'un chantier dira chef et exécutant.

import { MINIMAL_ROLES } from '@mostajs/teams/seed-roles';

Interopérer

toScimGroup / fromScimGroup traduisent une équipe en SCIM Group (RFC 7643) : un annuaire d'entreprise peut donc alimenter ou lire l'organisation sans que le module connaisse son dialecte.

Ce qu'il ne fait pas

Autoriser → @mostajs/rbac et rbac-tenant, côté app · identifier les personnes → users (injecté, il hydrate members.list) · notifier → notifications (injecté ; une notification qui échoue ne casse pas un ajout) · stocker → les dépôts que vous injectez.

Contrat des dépôts (N0/N1) : create · findById · update · find(predicate) · delete · all. En N2+ et dans les apps, l'autre convention règne (BaseRepository / FilterQuery de @mostajs/orm) : l'adaptation appartient à l'application, jamais au module.

Tests

npm test   # 16/16