Documentação
ReferênciaSDK JavaScriptClients

Clients

createClient para o navegador, createServerClient para todo o resto.

createClient — navegador

import { createClient, Storage } from '@nulvless/nulvless-js';

const nulvless = createClient(url, publishableKey, options?);
urlstringOptional

O issuer do seu ambiente — https://<project>.nulvless.co. Em produção você pode usar seu domínio personalizado, como https://api.exemplo.com.

publishableKeystringOptional

Chave publicável, começando com pk-.

optionsClientOptionsOptional

Opcional — veja Configuração.

lib/nulvless.ts
export const nulvless = createClient('https://acme.nulvless.co', 'pk-…', {
  storage: Storage.Local,
  trackUser: true,
  language: () => 'pt-BR',
});

A chave publicável pode ir para produção sem risco. Ela só consegue fazer o que o usuário autenticado já conseguiria — não é uma capacidade própria.

Armazenamento de sessão

O client de navegador persiste a sessão para você — no localStorage por padrão, ou, quando o código roda onde não existe window (SSR, testes), num armazenamento em memória do próprio client. Escolha outro adaptador com storage:

import { Storage } from '@nulvless/nulvless-js';

createClient(url, key, { storage: Storage.Local });

As chaves têm como padrão nlv-<slug>-token e nlv-<slug>-token-accounts, e podem ser sobrescritas com storageKeys.

createServerClient — servidor

import { createServerClient } from '@nulvless/nulvless-js';

const nulvless = createServerClient(url, secretKey, options?);
urlstringOptional

O issuer do seu ambiente

secretKeystringOptional

Chave secreta, começando com sk-

optionsServerClientOptionsOptional

Igual a ClientOptions, menos storage e storageKeys

Nunca mande uma chave secreta para o navegador

Chaves sk- alcançam as partes administrativas da API. Crie o client de servidor apenas em código de servidor — rotas de API, handlers, workers.

Repassando os headers do usuário

A impressão digital da sessão registra o dispositivo e a localização de onde ela foi criada. No servidor, a requisição que a plataforma enxerga é a do seu servidor, não a do usuário — então esses campos descreveriam a sua infraestrutura.

O forwardUserHeaders copia os headers relevantes da requisição que chegou:

import { createServerClient, forwardUserHeaders } from '@nulvless/nulvless-js';

const nulvless = createServerClient(url, 'sk-…');

const { data, error } = await nulvless.auth.grants.invite(
  { invites: [{ email: '[email protected]', role_id: roleId }], resource: 'acme' },
  { headers: forwardUserHeaders(req) },
);

Para aplicar em toda chamada em vez de uma a uma, resolva os headers de forma preguiçosa:

createServerClient(url, key, {
  trackUser: true,
  headers: () => forwardUserHeaders(cls.get('req')),
});

Mantendo as respostas de auth fora dos caches

O forwardUserHeaders cuida da requisição que entra. Este cuida da resposta que sai.

Sempre que a sua resposta cria, renova ou encerra uma sessão, aplique o applyAuthCacheHeaders nela:

import { createServerClient, forwardUserHeaders, applyAuthCacheHeaders } from '@nulvless/nulvless-js';

export async function POST(request: Request) {
  const { data } = await nulvless.auth.signIn(params, {
    headers: forwardUserHeaders(request),
  });

  const response = NextResponse.json({ ok: true });
  response.cookies.set('session', data.access_token);

  return applyAuthCacheHeaders(response);
}

Ele aceita um Response web (App Router, Workers, Deno) ou um ServerResponse do Node (Express, Pages Router), e devolve o mesmo objeto para a chamada caber dentro de um return:

app.post('/login', async (req, res) => {
  const { data } = await nulvless.auth.signIn(params, {
    headers: forwardUserHeaders(req),
  });

  applyAuthCacheHeaders(res);
  res.cookie('session', data.access_token, { httpOnly: true, sameSite: 'lax' });
  res.json({ ok: true });
});

Quando o framework aceita um mapa simples de headers, espalhe o AUTH_CACHE_HEADERS.

Uma resposta de login cacheada entrega a sessão ao próximo visitante

Se uma CDN cacheia uma resposta que carrega um cookie de sessão novo, ela entrega esse cookie para o próximo visitante. A proteção que você esperaria não vale aqui: caches compartilhados são proibidos de reusar respostas de requisições que carregam Authorization, mas a sua é autenticada por cookie, que não tem essa regra. Isso já aconteceu em produção com CloudFront, Vercel Edge e Cloudflare.

As respostas da API do nulvless já saem com Cache-Control: no-store, então isto vale apenas para as respostas que o seu app devolve.

Multi-conta

Defina multiUser: true num client de navegador para manter várias contas autenticadas e alternar entre elas.

const nulvless = createClient(url, key, { multiUser: true });

await nulvless.auth.add(authenticated);
const accounts = await nulvless.auth.list();
await nulvless.auth.switch(userId);
await nulvless.auth.remove(userId);

O auth.get() devolve a sessão ativa e o auth.set() a substitui. Isso vem desligado por padrão — habilite só se o seu produto realmente troca de conta.

Nesta página