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

@nexus-systems/manager

v0.2.0

Published

Cliente HTTP para validação de licença contra o Nexus License Manager

Readme

@nexus-systems/manager

Cliente HTTP leve para validação de licenças contra o Nexus License Manager (POST /api/v1/license/validate).


O que mudou a partir da v0.2

O servidor passou a devolver (e este pacote a expor) uma política explícita para o seu app saber como proceder, sem inferir só pelo status ou pela mensagem de erro.

| Área | Antes | Agora (recomendado) | | :--- | :--- | :--- | | Sucesso | status, datas, paymentUrl, token | Os campos acima mais enforcement e clientActions | | Erro | error, message, httpStatus | Mantém isso mais code (estável), enforcement (em geral deny) e clientActions quando o servidor enviar | | Parse | Validação manual de campos | Resposta de sucesso normalizada com os mesmos schemas do contrato interno (compatível com servidor legado sem os novos campos) |

Implementação: o contrato vive em packages/license-contract (só workspace). Os tipos estáveis (LicenseClientAction, LicenseErrorCode, etc.) são reexportados por @nexus-systems/manager — use o manager como única dependência npm.


Uso correto (enforcement + ações)

  1. result.ok — distingue sucesso da chamada HTTP vs. falha de rede/servidor/negócio.
  2. Em sucesso, use result.enforcement como decisão principal:
    • allow — assinatura em dia; operação normal (clientActions costuma incluir ALLOW_FULL_ACCESS).
    • grace — assinatura em atraso (overdue); o JWT costuma ter TTL menor no servidor. Não trate como active: mostre aviso, ofereça pagamento; só bloqueie se a sua política de produto exigir.
  3. result.clientActions — lista de códigos estáveis (banner, modal, link de pagamento). Mapeie cada código na sua UI; não dependa só de strings em message.
  4. Em erro, use result.code para lógica (ex.: LICENSE_NOT_FOUND) e trate result.enforcement === 'deny' como bloqueio de licença. Para erros HTTP desta rota, se o servidor for antigo, enforcement pode ser omitido no JSON — o pacote assume deny nesses casos.

Exemplo mínimo:

import { NexusManager } from '@nexus-systems/manager';

const nexus = new NexusManager({
  licenseKey: process.env.NEXUS_LICENSE_KEY,
  clientSecret: process.env.NEXUS_CLIENT_SECRET, // se o servidor exigir LICENSE_CLIENT_SECRET
});

const result = await nexus.validate();

if (!result.ok) {
  // Bloquear acesso: enforcement efetiva é deny (ou assumida deny)
  console.error(result.code, result.message);
  return;
}

switch (result.enforcement) {
  case 'allow':
    // liberar uso pleno
    break;
  case 'grace':
    // manter acesso com avisos; usar result.clientActions e result.paymentUrl
    break;
  default:
    // defensivo; em sucesso normal da API atual não deve ocorrer
    break;
}

for (const action of result.clientActions) {
  // ex.: SHOW_PAYMENT_REMINDER → banner; OPEN_PAYMENT_URL → botão para result.paymentUrl
}

Evite: tratar só result.status === 'active' como “pode usar” e ignorar overdue — em grace a licença ainda pode ser válida com ressalvas.


Instalação

npm install @nexus-systems/manager
# ou
pnpm add @nexus-systems/manager
# ou
yarn add @nexus-systems/manager

O pacote publicado inclui o contrato no bundle e declara zod como dependência de runtime (não é necessário instalar o contrato separadamente).


Configuração

Variáveis de ambiente suportadas

  • NEXUS_LICENSE_KEY — chave da licença.
  • NEXUS_CLIENT_SECRET — deve coincidir com LICENSE_CLIENT_SECRET no servidor, quando esse segredo estiver configurado.
  • NEXUS_MANAGER_BASE_URL — URL base do gerenciador (sem barra final; padrão https://manager.nexus-system.com.br).

Exemplo em Node.js / TypeScript

import { NexusManager } from '@nexus-systems/manager';

const nexus = new NexusManager({
  licenseKey: 'SUA_CHAVE_AQUI',
  clientSecret: 'SEU_SEGREDO_AQUI',
});

async function checkLicense() {
  const result = await nexus.validate();

  if (!result.ok) {
    console.error(result.error, result.code, result.message);
    return;
  }

  if (result.enforcement === 'grace') {
    console.warn('Assinatura em atraso — avisar usuário e priorizar pagamento.');
  }

  if (result.paymentUrl) {
    console.log('Portal de pagamento:', result.paymentUrl);
  }

  // JWT para verificação offline (conforme sua política de segurança)
  console.log('Token até:', result.tokenExpiresAt);
}

void checkLicense();

Exemplo em middleware (Next.js)

overdue vem como grace: redirecionar tudo que não é active para uma página de erro bloqueia clientes que ainda têm janela de uso. Prefira ramificar por enforcement:

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { NexusManager } from '@nexus-systems/manager';

const nexus = new NexusManager();

export async function middleware(request: NextRequest) {
  const result = await nexus.validate();

  if (!result.ok) {
    return NextResponse.redirect(new URL('/license-error', request.url));
  }

  if (result.enforcement === 'deny') {
    return NextResponse.redirect(new URL('/license-blocked', request.url));
  }

  if (result.enforcement === 'grace') {
    // Ex.: cookie/header para a app mostrar banner; não precisa bloquear rota inteira
    const res = NextResponse.next();
    res.headers.set('x-license-grace', '1');
    return res;
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/admin/:path*',
};

API

NexusManager

constructor(options?: NexusManagerOptions)

| Opção | Tipo | Descrição | | :--- | :--- | :--- | | baseUrl | string | URL base do gerenciador (sem / final). | | licenseKey | string | Chave da licença. | | clientSecret | string | Segredo alinhado a LICENSE_CLIENT_SECRET no servidor. | | env | Record<string, string \| undefined> | Variáveis de ambiente alternativas (ex. workers). | | fetch | typeof fetch | Implementação customizada de fetch. |

validate(): Promise<LicenseValidationResult>

Chama o endpoint de validação e devolve um discriminated union em ok.

Sucesso (ok: true):

| Campo | Descrição | | :--- | :--- | | status | active | overdue em respostas válidas atuais (espelho da assinatura). | | enforcement | allow | graceuse para decidir rigor de bloqueio vs. aviso. | | clientActions | Códigos estáveis sugeridos (ALLOW_FULL_ACCESS, SHOW_PAYMENT_REMINDER, …). | | subscriptionPeriodEnd | Fim do período de cobrança atual (UTC). | | tokenExpiresAt | Expiração do JWT retornado (UTC). | | paymentUrl | URL de pagamento quando aplicável. | | token | JWT RS256 do gerenciador. |

Erro (ok: false):

| Campo | Descrição | | :--- | :--- | | error | Categoria grossa: unauthorized, forbidden, bad_request, server, network. | | message | Texto do servidor ou fallback. | | httpStatus | Status HTTP quando aplicável. | | code | Código estável (LICENSE_NOT_FOUND, …) quando o servidor enviar. | | enforcement | Em erros desta rota costuma ser deny; omitido em servidor legado. | | clientActions | Ações sugeridas em erros estruturados (ex.: BLOCK_ACCESS). |


Licença

MIT