Thanks for helping improve the Wynncraft API v3 TypeScript client. This guide covers local setup, project conventions, and what we expect in pull requests.
- Bun (used for install, scripts, and CI)
- Node.js 18+ (consumer smoke tests run on 18, 20, and 22)
git clone https://github.com/jakehwll/wynnjs.git
cd wynnjs
bun installRun the full local quality gate before opening a PR:
bun run ciThat runs lint, format check, typecheck, tests, build, example typecheck, and a dry-run npm pack.
Useful individual commands:
| Command | Purpose |
|---|---|
bun run test |
Run all Vitest tests |
bun run test:watch |
Watch mode |
bun run typecheck |
tsc --noEmit (packages/api/src) |
bun run typecheck:examples |
Typecheck examples against built dist/ |
bun run lint / bun run lint:fix |
Oxlint |
bun run format / bun run format:check |
Oxfmt |
bun run build |
Build workspace packages (api + docs) |
bun run docs |
Dev server for VitePress docs |
bun run docs:build |
Build static docs site |
bun run test:fixtures |
Refresh doc example JSON fixtures |
Docs deploy to GitHub Pages via .github/workflows/docs.yml on pushes to main. In the repo settings, set Pages → Source to GitHub Actions. VitePress base is /wynnjs/.
packages/
api/ # published @wynnjs/api
src/
client.ts # WynnClient entry point
modules/ # API modules (player, guild, item, …)
schemas/ # Zod schemas + exported types, grouped by domain
<module>/
__fixtures__/ # Doc example JSON for schema tests
testing/ # Shared test helpers
examples/ # Runnable usage samples
scripts/ # Fixture sync and tooling
apps/
docs/ # VitePress site (@wynnjs/docs)
The published package ships dist/, plus README.md and LICENSE from packages/api/. Source lives under packages/api/src/.
Most endpoint work touches three places under packages/api/:
-
Schema —
packages/api/src/schemas/<module>/<endpoint>.ts- Define Zod schemas for request options and response shapes
- Export inferred TypeScript types
-
Module method —
packages/api/src/modules/<module>.ts- Add or update the client method that calls
this.client.request() - Document params and return shape with JSDoc (
@param,@returns)
- Add or update the client method that calls
-
Tests
- Schema fixture test in
packages/api/src/schemas/<module>/<module>.test.tsusingexpectDocExample() - Unit or integration tests colocated with the code they cover (
*.test.tsnext to the source file)
- Schema fixture test in
Re-export new types from packages/api/src/schemas/index.ts if needed. The package src/index.ts re-exports everything from schemas automatically.
- Regular query params go in
params - Wynncraft presence flags (
?fullResult,?static, etc.) go inpresenceParamsviaRequestConfig - Path segments should be passed through
encodeURIComponent() - Authenticated endpoints require
WynnClientOptions.auth
Match the Wynncraft API docs literally. Some endpoints return UUID-keyed maps (Record<string, T>) rather than flat objects — preserve that in the schema even if it looks awkward in IDE hovers.
Public API surface should be documented:
- Module classes and methods
WynnClient, auth types, errors, and HTTP helpers- Non-obvious option fields (e.g.
options.fullResult,options.identifier)
Use @param for each argument (including nested option fields like options.page) and @returns for the response shape. Add @example when usage is non-obvious.
If you add a new common workflow, consider a small runnable sample in packages/api/examples/. Use fictional usernames and UUIDs — do not commit real player data.
Doc examples are stored as JSON under each module's __fixtures__/ directory and validated against Zod schemas:
import { expectDocExample } from "../../testing/doc-example";
import { GetPlayerResultSchema } from "./get-player";
expectDocExample(import.meta.url, GetPlayerResultSchema, "get-player");Refresh fixtures from the docs with:
bun run test:fixturesReview the diff carefully before committing — fixtures should reflect the official docs, not live API drift you didn't intend.
Pure helpers (auth, http, errors) have focused unit tests colocated in packages/api/src/*.test.ts.
packages/api/src/client.test.ts uses axios-mock-adapter to verify request wiring without hitting the live API.
- Formatter: Oxfmt (
.oxfmtrc.json) - Linter: Oxlint (
.oxlintrc.json) - TypeScript: strict mode, no
anyunless unavoidable - Keep diffs focused — match existing naming, imports, and file structure
- Do not hand-edit
dist/; it is build output
- Branch from
main - Make your changes with tests
- Run
bun run cilocally - Open a PR with a short description of what changed and why
CI must pass before merge. It runs the same checks as bun run ci plus a Node consumer smoke test that installs the packed tarball and verifies ESM + CJS imports.
- Types and schemas match the official Wynncraft v3 API
- New public methods have JSDoc
- Tests cover schema shapes and any non-trivial request logic
- No secrets, real usernames, or session tokens in examples or fixtures
The npm package uses independent semver (currently 3.0.0). The Wynncraft API release the client targets is WYNNCRAFT_API_VERSION in packages/api/src/constants.ts (currently 3.7.2).
- Client release (
packages/api/package.jsonversion) — bump for fixes, features, or breaking client changes (3.0.1,3.1.0,4.0.0, …). - API alignment (
WYNNCRAFT_API_VERSION) — update when you realign schemas and methods to a new Wynncraft API release. Note the change inCHANGELOG.md; bump the client major/minor if the API delta is breaking for consumers.
Publishing runs in GitHub Actions via npm trusted publishing (OIDC). No long-lived NPM_TOKEN is required for npm publish.
- Ensure
@wynnjs/apiexists under your npm account or org (first publish creates it). - Open Packages →
@wynnjs/api→ Settings → Trusted publishing. - Select GitHub Actions and configure:
- Repository owner:
jakehwll - Repository name:
wynnjs - Workflow filename:
publish.yml(filename only, not the path) - Environment: leave blank (this workflow does not use a GitHub Environment)
- Repository owner:
- Save the trusted publisher.
- Optional hardening (recommended with 2FA): Settings → Publishing access → Require two-factor authentication and disallow tokens. Trusted publishing still works; revoke any old automation publish tokens.
packages/api/package.json repository.url must match the GitHub repo (git+https://github.com/jakehwll/wynnjs.git).
- Bump
versioninpackages/api/package.jsonand add a rootCHANGELOG.mdentry (docs sync it automatically ondocs/docs:build). - Merge to
main. - Create a GitHub Release with tag
vX.Y.Z(must matchpackages/api/package.json, e.g.v3.0.0). - The Publish workflow runs CI, verifies the tag, and publishes with provenance via OIDC.
To publish without a release, use Actions → Publish → Run workflow on main.
By contributing, you agree that your contributions will be licensed under the project's MIT License.