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

@vinadesignstore/core-client

v0.4.1

Published

Auth API client and server session runtime for Vina Design Store applications.

Readme

@vinadesignstore/core-client

VNDS Auth API client and session runtime. Version 0.4.1 accepts only authenticated encrypted session cookies and handles revoked sessions and SDK errors consistently across root/server ESM/CommonJS imports. Version 0.4.0 adds live permission checks and catalog/grant administration. Deploy the matching Auth permission migration/API before upgrading consumers. Version 0.3.0 includes platform, discord, and /server, but no permission APIs.

pnpm add @vinadesignstore/core-client

Entry points and credentials

| Entry | Use | | --- | --- | | @vinadesignstore/core-client | Auth/settings/permissions/platform/Discord clients and pure refresh scheduling helpers. Browser-compatible imports do not make secret-bearing calls browser-safe. | | @vinadesignstore/core-client/server | Node.js session encryption, cookie management, environment validation, and viewer resolution. Never import into browser components. No Next.js dependency. |

Create secret-bearing clients only on the server:

import { createVndsCoreClient } from "@vinadesignstore/core-client";

const core = createVndsCoreClient({
  baseUrl: process.env.VNDS_AUTH_BASE_URL!,
  appId: process.env.VNDS_CORE_APP_ID!,
  apiKey: process.env.VNDS_CORE_API_KEY!,
});

Use the issued app ID/key and your Auth origin (https://auth.vinadesignstore.com for VNDS production). Keep VNDS_CORE_API_KEY out of client components and public environment variables. The public npm package does not grant API access by itself.

OAuth and authorization

Store a random state and PKCE verifier in the server-managed OAuth request cookie, redirect to the authorize URL, validate/consume state on callback, and exchange the code server-side:

const pkce = await core.auth.generatePkcePair();
const authorizeUrl = core.auth.buildAuthorizeUrl({
  appId: process.env.VNDS_CORE_APP_ID!,
  redirectUri: "https://store.example.com/auth/callback",
  state, // Fresh state persisted for this request.
  codeChallenge: pkce.codeChallenge,
});
// In the callback, after validating returned state:
const tokens = await core.auth.exchangeAuthorizationCode({
  code,
  codeVerifier: storedVerifier,
  redirectUri: "https://store.example.com/auth/callback",
});

The API uses /api/auth/oauth2/{authorize,token,userinfo,introspect}. core.auth also exposes token refresh, revocation, and client-credentials helpers. Code exchange, refresh, introspection, client credentials, and secret-bearing API requests belong on the server.

The viewer requires active introspection, completed onboarding in both identity responses, and matching subjects. It then requests fresh grants for the credential-bound app and checks the returned subject and expected app slug. Role claims are display data; userinfo roles, raw Discord IDs, and decoded ID-token claims never replace permission checks.

Useful identity claims include onboarding_complete, password_set, discord_connected, discord_member, discord_user_id, discord_member_guild_ids, discord_guild_memberships, and roles_last_synced_at. Membership reflects Auth's synchronized Discord snapshot; discord_member means membership in at least one configured guild.

import { resolveVndsViewer, requirePermission } from "@vinadesignstore/core-client/server";

const viewer = await resolveVndsViewer({
  core,
  expectedAppSlug: "online", // Trusted app configuration, never request input.
  getValidSession: session.getValidSession,
});
requirePermission(viewer, "online.products.write");
// Apply resource restrictions, then perform the write.

core.permissions.get({ accessToken }) returns { subject, appSlug, permissions, roleIds } from /api/satellite/permissions. The viewer exposes those fresh fields; hasPermission(viewer, key) and requirePermission(viewer, key) check exact valid keys. Only pass server-resolved viewers to these helpers. Missing keys deny even when a role is named admin or owner.

Each viewer resolution performs a fresh permission request with cache: "no-store". Do not persist grants in session cookies or process caches; request-local reuse is sufficient. Removing a grant or disabling a key affects the next check. Invalid/unauthorized users resolve to no viewer; identity or permission-service failures throw VndsCoreError with status 503, never reuse prior grants.

Deferred jobs and Discord handlers can use core.permissions.resolve({ userId }) or core.permissions.resolve({ discordUserId, guildId }). This machine lookup requires explicit permissions:read app capability and checks current user eligibility. Verify the returned app slug and expected subject at the execution boundary; its app credentials are never browser-safe.

Settings, platform, and Discord clients

await core.settings.set("storefront", "branding", { accent: "#7c3aed" });
const branding = await core.settings.get("storefront", "branding");

settings.get|list|set|delete call /api/configs/[namespace] and /api/configs/[namespace]/[key]. Keep them server-side and enforce the viewer's access in your local handler before reading or mutating application settings.

Delegated platform calls combine the server-held app credentials with the signed-in operator token. Auth validates both and independently checks the exact platform permission for each operation:

const access = await core.platform.access.check({ accessToken });
if (access.permissions.includes("platform.users.read")) {
  const users = await core.platform.users.list({ accessToken, limit: 50 });
}

Available namespaces are apps, users, roles, permissions, discord, configurations, access, and audit. permissions.list|create|update manage catalog metadata and activation; key/owning app are immutable. Role create/update accepts permissionKeys; users.permissions(id, { accessToken }) explains effective grants and their role/source. access.check returns actual platform keys alongside authorized. They support registry lifecycle/rotation, user/profile/role/ban/password/invite operations, role and configuration CRUD, Discord server synchronization, access policy/approved emails, and audit reads. Exact input types ship with the package. Destructive operations require exact confirmation values; Auth audits safe metadata and redacts configuration secrets. Never pass a platform client, password, invite link, or generated key into logs or client props unintentionally.

core.discord.resolveAssistantViewer({ discordUserId, guildId }) calls Auth's server-only Discord assistant identity endpoint. It requires app credentials and the server's allowed-app checks; it is not a browser identity lookup.

Server session runtime

The /server entry centralizes encrypted session cookies, OAuth request cookies, internal return paths, refresh persistence, fresh permissions, and viewer resolution. Environment validation is lazy: import/build does not require production secrets; the first operation reports missing configuration.

With Next.js, pass its cookie provider at the application boundary:

import { cookies } from "next/headers";
import {
  createVndsServerClientFromEnv,
  createVndsSessionManager,
} from "@vinadesignstore/core-client/server";

const { core } = createVndsServerClientFromEnv();
export const session = createVndsSessionManager({ core, cookies });

Set a dedicated VNDS_SESSION_SECRET to encrypt local cookies. Read-only calls do not rotate tokens. A route/action that can write the response cookie opts into getValidSession({ persistSession: true }); never enable this in a Server Component read. App routes own callback, refresh, logout, and final viewer shape.

One OAuth session per browser profile is supported; multi-user roster APIs were removed. Version 0.4.1 reads only the existing encrypted v1 cookie format with exactly four segments. Existing sealed cookies remain valid with the same session secret; legacy plaintext sessions require a fresh sign-in. Malformed, tampered, unknown-version, and wrong-secret cookies are rejected. Viewer authorization still requires live token and permission validation.

Browser components can import getInitialSessionRefreshDelay, getNextSessionRefreshDelay, isSessionWithinRefreshWindow, and their timing constants from the package root.

Maintainer checks

For changes in the VNDS monorepo, run package tests/typecheck, pnpm build:sdk, and pnpm pack:sdk. Increment the version before pnpm publish:sdk; it runs registry/isolated-install checks and normal pnpm Git checks. Published versions cannot be replaced. No separate runtime package is required.