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

@pieai/swimmer-backend-client

v0.7.2

Published

Thin TypeScript client for shared SwimmerBackend authentication, wallet, and entitlement-grant contracts.

Downloads

814

Readme

@pieai/swimmer-backend-client

A deliberately small TypeScript client for stable SwimmerBackend authentication, wallet, and entitlement-grant contracts. It accepts a Supabase-compatible client supplied by the product and never embeds project URLs or keys.

pnpm add @pieai/[email protected]
import { createAuthClient } from '@pieai/swimmer-backend-client';

const auth = createAuthClient(supabase);
const session = await auth.signInAnonymously();

Server routes that receive a bearer token can verify it through the same shared identity contract without decoding or returning the token:

import { verifyAccessToken } from '@pieai/swimmer-backend-client';

const user = await verifyAccessToken(serverSupabase, accessToken);
if (!user) throw new Error('Invalid access token');

The supplied provider must implement auth.getUser(accessToken). Provider errors are surfaced so the product can choose its own 401/503 policy; a missing or malformed user returns null.

For an authenticated API request, read the current access token immediately before sending the request so Supabase can refresh its session when needed:

const accessToken = await auth.getAccessToken();
if (!accessToken) throw new Error('Authentication required');
const response = await fetch('/api/example', {
  headers: { Authorization: `Bearer ${accessToken}` },
});

Do not log, persist, or copy the token into application session state. The public AuthSessionRecord intentionally contains only the user identity; the client never exposes refresh tokens or the provider's raw session.

Email sign-in, sign-up, magic-link requests, and anonymous-account linking are separate explicit methods. A magic-link request must receive the product's allow-listed redirect URL. The package never turns one failed action into a different account action; products own that UX policy.

Server-authoritative products can use the additive wallet subpath without reimplementing RPC names or parsing Postgres bigint responses:

import { createWalletClient } from '@pieai/swimmer-backend-client/wallet';

const wallet = createWalletClient(serverSupabase, 'anvil');
const reservation = await wallet.reserve({
  amountPowerUnits: '250',
  idempotencyKey: 'run:123:reserve',
  userId,
});

After a product payment adapter has confirmed a provider-side refund, dispute, or payment reversal, it can reverse an exact committed top-up source. A balance shortfall is explicit and does not consume reserved funds:

const reversal = await wallet.reverseGrant({
  amountPowerUnits: '250',
  idempotencyKey: 'refund:provider-event-id:attempt:1',
  reason: 'refund',
  sourceGrantId,
});

Do not pass raw webhook states directly to this method. Provider signature verification, event ordering, pending/failed refunds, and dispute reinstatement remain the payment adapter's responsibility.

Products can read a server-selected current plan grant through the additive entitlements subpath. The product owns the RPC name and maps planId to its own feature policy; this reader never exposes grant-history metadata or a write method:

import { createEntitlementClient } from '@pieai/swimmer-backend-client/entitlements';

const entitlements = createEntitlementClient(
  serverSupabase.schema('university'),
  'university_read_plan_grant',
);
const grant = await entitlements.readGrant(userId);
// { planId: 'member', validFrom: '...', validUntil: '...' }

The RPC must be protected by the product's authenticated-user boundary. Grant issuance remains a trusted server/payment-fulfillment operation, never a browser call.

The facade does not create a Supabase client or manage a service-role key. Use it only from an already trusted server boundary. Never put credentials, prompts, generated content, or provider responses in wallet metadata.

Shared avatar profile

createProfileClient from @pieai/swimmer-backend-client/profiles reads the current user's core.profiles avatar and sends explicit updates through the Backend-owned profile-avatar gateway. This release candidate is not yet published or deployed. Products must not copy this implementation or install an unpublished replacement in production.

The gateway verifies the user, fully validates the published AvatarKit recipe, and derives its compact portrait. It never accepts an owner ID from the browser. Updates carry an operation UUID and the exact updatedAt string from the last read; preserve microseconds rather than rebuilding that value with Date. Repeated operations are reconciled; stale writes do not replace newer profiles.

Supabase PostgreSQL TLS

Node services can import supabasePostgresTls from @pieai/swimmer-backend-client/postgres-tls and pass its options as the driver's ssl configuration. The helper pins the public Supabase Root 2021 CA selected by the official production dashboard, retains certificate and hostname verification, and requires TLS 1.2 or newer. It owns no connection, password, role or user context. Products must still verify the expected project and use an isolated runtime LOGIN. Do not replace it with rejectUnauthorized: false or ssl: 'require'.

Source: Supabase's apps/studio/hooks/custom-content/custom-content.json at 26585dd4a4d6db8910a595214c9f6e8fdd206768, and the public certificate URL documented in postgres-tls.ts. The certificate expires in April 2031; vendor rotation requires a reviewed package update. This public trust anchor is not a credential or copied application code. This shared owner is independent of University progress and product work ownership.

Deploy the two profile RPCs and the configured gateway before consuming this subpath. SWIMMER_PROFILE_AVATAR_ORIGINS and SWIMMER_PROFILE_AVATAR_APPS are explicit allowlists; missing configuration fails closed. The platform JWT check stays enabled and the gateway independently verifies the user through Auth.

Product schemas, game rooms, seats, pricing policy, prompts, and UI state do not belong in this package. They remain owned by their product repositories. The commercial subpath contains transport types only; it does not calculate fees or choose a payment provider.