Skip to content

Latest commit

 

History

History
116 lines (93 loc) · 6.23 KB

File metadata and controls

116 lines (93 loc) · 6.23 KB

ThunderID JavaScript SDKs — Agent Instructions

Project overview

pnpm + Turborepo monorepo of TypeScript SDKs under packages/: a framework-agnostic core (@thunderid/javascript), a browser layer (@thunderid/browser), a server layer (@thunderid/node), and framework SDKs built on top of those (react, vue, nuxt, nextjs, express, react-router, tanstack-router). samples/<framework>/quickstart directories contain standalone demo apps — not part of any published package.

SDK development specification

Every change to this SDK goes through the ThunderID SDK development specification. It is maintained in the product repository and governs all four SDK repositories, so it is linked here rather than copied.

  • SDK development specification: the contract this SDK implements. Layering, operational modes, configuration keys, client surface, error model, security floor, platform packaging, testing, and the cross-SDK parity rules.
  • SDK threat model: the security posture the specification's floor comes from.
  • sdk-development skill: loads both documents and drives the work, from locating the SDK checkouts through validation to raising the linked pull requests.

Read the specification before adding or changing an operation, configuration key, error, or UI component. A capability that lands here usually needs to land in the sibling SDKs too, and the pull request has to answer that question either way, by linking the sibling pull requests or by saying why they are not needed.

Skills

  • Fix npm Vulnerability — Resolve a pnpm/npm security advisory. Use when pnpm audit or Dependabot surfaces a security advisory. Tries to update the head dependency first; falls back to a scoped override with a tracking GitHub issue.
  • Prune npm Overrides — Audit the pnpm overrides this repo already carries and remove the ones upstream has since fixed. Use when asked to check, clean up, or prune the overrides in pnpm-workspace.yaml, or when an override's tracking issue comes up for review.

Build & test

pnpm install

pnpm build          # turbo run build across all packages
pnpm test           # turbo run test
pnpm lint           # turbo run lint (@thunderid/eslint-plugin)
pnpm typecheck      # turbo run typecheck
pnpm format:check

# Scope to a single package:
pnpm --filter @thunderid/<pkg> run build
pnpm --filter @thunderid/<pkg> run test

Package hierarchy — check before adding a util

@thunderid/javascript is the framework-agnostic core (auth flows, token management, i18n, VendorConstants, shared utils). Every other package depends on it, directly or transitively:

  • @thunderid/browser@thunderid/javascript + DOM/browser APIs (storage, session sync, WebAuthn).
  • @thunderid/node@thunderid/javascript + server-side session/cookie handling.
  • @thunderid/react, @thunderid/vue@thunderid/browser.
  • @thunderid/nextjs@thunderid/node + @thunderid/react.
  • @thunderid/nuxt@thunderid/node + @thunderid/vue.
  • @thunderid/express@thunderid/node.
  • @thunderid/react-router, @thunderid/tanstack-router@thunderid/react.

Before adding a helper/util/constant to a framework package, check whether it belongs lower in this hierarchy instead. If the same logic would be needed by more than one framework package (or you're about to copy-paste one), it almost certainly belongs in @thunderid/javascript — or @thunderid/browser/ @thunderid/node if it needs DOM/server APIs — and should be re-exported from there, not duplicated. Every package's src/index.ts re-exports its dependency's exports (export * from '@thunderid/javascript', etc.), so check there before assuming a helper isn't already available.

Vendor naming rules

The SDK is white-labelable: a consuming app can override the brand/vendor namespace via the vendor config field, so storage keys, cookie names, CSS class prefixes, state keys, etc. shouldn't be pinned to one brand.

  • Do not hardcode the literal thunderid/ThunderID/THUNDERID (any casing) when building a runtime key/name that a consumer's vendor override should control — storage keys, cookie/session names, CSS class prefixes, useState/composable keys, log tags, DOM id/data-* attributes, and the like.
  • It's fine for the entry point — the main client class, provider component, or a file whose purpose IS to represent the SDK itself (e.g. ThunderIDClient, ThunderIDProvider, ThunderIDBrowserClient) — to carry the name. That's a fixed identity, not a per-tenant value. Don't flag those.
  • Avoiding the vendor name entirely is the best outcome, when the brand prefix isn't actually load-bearing.
  • When a brand-scoped namespace is genuinely required, resolve it through getVendorPrefix(vendor) (defined in @thunderid/javascript, re-exported via @thunderid/browser/@thunderid/node) instead of hardcoding a literal or repeating an inline vendor ?? 'thunderid' fallback. That default belongs in one place.

Code style

  • TypeScript, ESLint via @thunderid/eslint-plugin, Prettier.
  • Every source file carries a copyright header (@thunderid/copyright-header ESLint rule); samples/** is exempt (see eslint.config.js).
  • Prefer editing or re-exporting an existing util over duplicating a helper across packages (see hierarchy above).

File layout

packages/
  javascript/       Framework-agnostic core SDK
  browser/          Browser/DOM layer (storage, WebAuthn, session sync)
  node/             Server-side layer (cookies, sessions)
  react/            React components + hooks
  vue/              Vue components + composables
  nextjs/           Next.js SDK (client + server)
  nuxt/             Nuxt module
  express/          Express middleware
  react-router/     React Router integration
  tanstack-router/  TanStack Router integration
samples/            Standalone quickstart demo apps, one per framework