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

@seamless-auth/types

v0.6.0

Published

Shared TypeScript types and Zod schemas for SeamlessAuth.

Downloads

2,054

Readme

@seamless-auth/types

npm CI Node License: AGPL-3.0-only

Shared TypeScript types and Zod schemas for the SeamlessAuth ecosystem.

This package is the single source of truth for the SeamlessAuth domain models (Users, Credentials, Sessions, Auth, Auth Events, Organizations) and for the request and response contracts built on top of them. Every layer of the stack validates against the same schemas:

  • API servers
  • SDKs and server adapters
  • Frontend applications
  • CLI tools

Because everything downstream imports these contracts, a change here is treated as breaking by default. See Versioning and stability.

Requirements

| | | | -------------------- | ------------------------- | | Node | 24 (>=24 <25) | | TypeScript | 5.x | | Runtime dependencies | zod@^4 and nothing else |

The package ships as ESM only. The root import works under any module resolution, but the subpath exports are resolved from package.json exports, so consumers that use them need moduleResolution set to node16, nodenext, or bundler.

Installation

npm install @seamless-auth/types

Quick start

import { UserSchema, type User } from '@seamless-auth/types';

// Validate untrusted input and get a fully typed value back.
const user: User = UserSchema.parse(await response.json());

Usage

Validate data

Every model is a Zod schema, so you get runtime validation and the static type from one declaration:

import { LoginRequestSchema } from '@seamless-auth/types';

const parsed = LoginRequestSchema.safeParse(req.body);
if (!parsed.success) {
  return res.status(400).json({ error: parsed.error.issues });
}

Infer types

import type { User } from '@seamless-auth/types';

function handleUser(user: User) {
  console.log(user.email);
}

Roles

Role schemas accept plain roles such as admin and colon-separated scoped roles such as admin:read and admin:write. Whitespace, underscores, slashes, and backslashes are rejected, so a role name is always safe to embed in a JWT claim, a URL path segment, or a config file without escaping.

Match roles without Zod

roleGrantsAccess and hasScopedRole are plain string logic, but reaching them through the package root loads Zod and every schema in the barrel. Code on the authorization hot path can import them from @seamless-auth/types/role/matching instead, which has no runtime dependencies:

import { hasScopedRole } from '@seamless-auth/types/role/matching';

if (!hasScopedRole(user.roles, 'billing:invoices:read')) {
  throw new Error('forbidden');
}

@seamless-auth/types/role adds RoleNameSchema on top of the same matchers, and the package root still exports all of them, so existing imports keep working.

Modules

Every module is re-exported from the package root, so import from @seamless-auth/types unless one of the subpath exports below fits better.

| Module | Covers | | -------------- | ------------------------------------------------------------------- | | common | Pagination, message and error envelopes, metadata | | role | Role name rules plus the scoped-role matcher (roleGrantsAccess) | | user | User domain model, wire shape, create and update requests | | credential | WebAuthn credentials and their API responses | | session | Sessions and session listings | | authEvent | Auth event model, the event type enum, and event queries | | messaging | Email and SMS message shapes plus auth delivery instructions | | systemConfig | System config, login methods, lockout policy, OAuth provider config | | auth | Login, refresh, registration, OTP, magic link, and logout contracts | | oauth | Public provider listings and the OAuth login handshake | | webauthn | Registration and assertion request and response contracts | | totp | TOTP enrollment, status, and verification | | stepUp | Step-up freshness status | | organization | Organizations, memberships, and the org switch response | | me | The caller's own user and GET /users/me | | metrics | Dashboard metrics, timeseries, and security anomalies | | admin | Admin-only user detail, anomalies, and device replacement recovery |

Subpath exports

| Subpath | Covers | | ------------------------------------ | -------------------------------------- | | @seamless-auth/types/role | Role name schema plus the matchers | | @seamless-auth/types/role/matching | The matchers alone, with no Zod import |

Conventions

Zod is the source of truth. Models are declared as schemas and the TypeScript type is inferred from the schema. No type in this package is hand-written alongside a schema that already describes it:

export const UserSchema = z.object({
  id: z.uuid(),
  email: z.email(),
});

export type User = z.infer<typeof UserSchema>;

Every exported schema has a matching type alias. XSchema is always paired with X, so you never have to write z.infer<typeof XSchema> at a call site. This is enforced by a test, not by convention alone.

Framework-agnostic. No server, browser, or Node-only APIs, and no runtime dependency beyond Zod, so the same contracts load in an API process, a browser bundle, and a CLI.

Strict typing throughout. No any and no non-null assertions. Wire-facing schemas are .strict() where unknown keys should be rejected rather than silently dropped.

Versioning and stability

This package follows semantic versioning:

  • PATCH for fixes with no effect on the contract, including docs and internal tidying
  • MINOR for additive changes such as a new module, export, or optional field
  • MAJOR for breaking changes such as a removed or renamed export, a field whose type changes, or a schema that now rejects input it used to accept

A widening change (a wider enum, a field that becomes nullable) is not breaking at runtime, but it does change the inferred TypeScript type, so it is called out in the release notes.

Releases are managed with Changesets. See RELEASES.md for the release flow and CHANGELOG.md for the history.

Supply chain

  • Published from CI only, from a tagged release on main, never from a developer machine.
  • Every release carries npm provenance, so the published tarball is cryptographically linked to the commit and workflow that built it.
  • One runtime dependency (zod). Dependency updates are automated and reviewed like any other change.
  • The published tarball is limited to dist, the non-test sources under src, README.md, CHANGELOG.md, LICENSE, and package.json. npm run check-npm-build prints the contents in CI on every push and release.
  • Sources ship alongside the declaration maps and source maps, so Go to Definition in your editor lands on the actual schema rather than a .d.ts.

Security

Do not open a public issue for a vulnerability. Report it privately to [email protected]. See SECURITY.md for what to include, our acknowledgement window, and the coordinated disclosure process.

Development

nvm use          # Node 24, pinned by .nvmrc
npm ci

npm run build      # compile to dist/
npm run dev        # tsc --watch
npm run typecheck
npm run lint
npm run format:check
npm test

Contributing

Contributions are welcome. Start with the organization contributing guide and the repository standards. AGENTS.md documents the repository layout and the working standards in more detail.

For a change in this repository specifically:

  1. Add or change the schema under src/schemas/<model>/.
  2. Export it from src/index.ts if it is part of the public API.
  3. Run npm run typecheck, npm run lint, npm run format:check, npm test, and npm run build.
  4. Run npm run changeset and write the notes for the repositories that consume these contracts, not for the implementation. A change to src/ without a changeset ships nothing.

Keep schemas Zod-based, keep the package framework-agnostic, and treat any change to an existing schema as breaking until you can argue otherwise.

License

AGPL-3.0-only © Fells Code, LLC

Links