User Manager - ArtyProf/steamworks-ffi-node GitHub Wiki

User Manager API Documentation

Complete reference for Steam User functionality in Steamworks FFI.

Overview

The SteamUserManager provides 100% coverage of the ISteamUser interface with 28 functions for authentication, session tickets, license verification, voice recording, and user information.

Quick Reference

Category Functions Description
Login State 1 Check Steam login status
Session Tickets 3 P2P/game server authentication tickets
Auth Sessions 2 Validate incoming auth tickets
License Verification 1 Check app/DLC ownership
Encrypted Tickets 2 Secure backend authentication
Security Info 2 User security settings and NAT status
User Info 3 Steam level, badges, data folder
Market Eligibility 1 Steam Market access status
Store Auth URL 1 In-game browser authentication
Duration Control 2 Anti-indulgence compliance (China)
Game Advertising 1 Advertise game server to friends
Voice Recording 6 Record and transmit voice chat
Cleanup 1 Cancel all active tickets

Login State

Check if the user is logged into Steam.

isLoggedOn()

Check if the user is logged into Steam.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_BLoggedOn() - Check login status

Returns: boolean - true if user is logged in

Example:

import SteamworksSDK from 'steamworks-ffi-node';

const steam = SteamworksSDK.getInstance();

if (steam.user.isLoggedOn()) {
  console.log('User is logged into Steam');
} else {
  console.log('User is offline or not logged in');
}

Session Tickets

Generate authentication tickets for P2P or game server authentication.

getAuthSessionTicket(identity?)

Get an auth session ticket for P2P or game server authentication.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetAuthSessionTicket() - Create session ticket

Parameters:

  • identity?: SteamNetworkingIdentityOptions - Optional: restrict ticket to specific recipient (Steam ID, IP, or string)

Returns: GetAuthSessionTicketResult

Type:

interface GetAuthSessionTicketResult {
  success: boolean;      // Whether the operation was successful
  authTicket: number;    // The auth ticket handle (0 if failed)
  ticketData: Buffer;    // The ticket data as a Buffer
  ticketSize: number;    // The actual ticket size in bytes
  error?: string;        // Error message if failed
}

interface SteamNetworkingIdentityOptions {
  steamId?: string;      // Restrict ticket to specific Steam ID
  ipAddress?: string;    // Restrict ticket to specific IP address (e.g., '192.168.1.100')
  genericString?: string; // Restrict ticket to specific service/recipient identifier
}

Examples:

// Get an unrestricted ticket (works with any recipient)
const result = steam.user.getAuthSessionTicket();

// Restrict ticket to a specific Steam ID
const result = steam.user.getAuthSessionTicket({
  steamId: '76561198001234567'
});

// Restrict ticket to a specific IP address
const result = steam.user.getAuthSessionTicket({
  ipAddress: '192.168.1.100'
});

// Restrict ticket to a service identifier
const result = steam.user.getAuthSessionTicket({
  genericString: 'my-dedicated-server'
});

if (result.success) {
  console.log(`Got ticket handle: ${result.authTicket}`);
  console.log(`Ticket size: ${result.ticketSize} bytes`);
  
  // Send to server for validation
  sendToServer({
    ticket: result.ticketData,
    steamId: steam.getSteamId()
  });
}

Remarks:

  • Call cancelAuthTicket() when done with the ticket
  • Ticket is valid until cancelled or user logs off
  • Maximum ticket size is 8192 bytes
  • If identity is omitted, creates an unrestricted ticket (usable by any recipient)
  • Identity restrictions add an extra security layer for high-security scenarios
  • Restrictions are embedded in the ticket data itself (ticket size remains the same)

getAuthTicketForWebApi(identity?)

Get an auth ticket for Steam Web API authentication.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetAuthTicketForWebApi() - Create web API ticket

Parameters:

  • identity?: SteamNetworkingIdentityOptions - Optional: restrict ticket to specific recipient (Steam ID, IP, or string)

Returns: Promise<GetAuthTicketForWebApiResult>

Type:

interface GetAuthTicketForWebApiResult {
  success: boolean;      // Whether the operation was successful
  authTicket: number;    // The auth ticket handle (0 if failed)
  ticketData: Buffer;    // The ticket data as a Buffer
  ticketSize: number;    // The actual ticket size in bytes
  ticketHex: string;     // The ticket as a hex string (for web API usage)
  error?: string;        // Error message if failed
}

interface SteamNetworkingIdentityOptions {
  steamId?: string;      // Restrict ticket to specific Steam ID
  ipAddress?: string;    // Restrict ticket to specific IP address (e.g., '192.168.1.100')
  genericString?: string; // Restrict ticket to specific service/recipient identifier
}

Examples:

// Get an unrestricted web API ticket
const result = await steam.user.getAuthTicketForWebApi();

// Restrict ticket to a specific Steam ID
const result = await steam.user.getAuthTicketForWebApi({
  steamId: '76561198001234567'
});

// Restrict ticket to a specific IP address
const result = await steam.user.getAuthTicketForWebApi({
  ipAddress: '192.168.1.100'
});

// Restrict ticket to a service identifier
const result = await steam.user.getAuthTicketForWebApi({
  genericString: 'my-backend-server'
});

if (result.success) {
  // Use hex string for API authentication
  const response = await fetch('https://api.example.com/auth', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Steam-Auth-Ticket': result.ticketHex
    },
    body: JSON.stringify({ steamId: steam.getSteamId() })
  });
}

Remarks:

Implementation: This method uses the native GetAuthTicketForWebApi() function with proper callback handling via Koffi's registered callbacks. The callback system is automatically registered on first use and cleaned up during shutdown.

Validation: Tickets should be validated using Steam's Web API: https://api.steampowered.com/ISteamUserAuth/AuthenticateUserTicket/v1/

Identity Parameter: The identity parameter accepts options for restricting the ticket to a specific recipient:

  • steamId - Restrict to specific Steam user (format: "steamid:76561198001234567")
  • ipAddress - Restrict to specific IP address (format: "ip:192.168.1.100")
  • genericString - Generic service identifier (format: "my-service")

Ticket Format: Returns tickets in the proper Web API format (234 bytes) that validate correctly with Steam's authentication endpoints.

Async Operation: This is a true async operation that waits for Steam's callback. The method polls RunCallbacks() internally with a 5-second timeout.


cancelAuthTicket(authTicket)

Cancel an auth ticket previously obtained.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_CancelAuthTicket() - Cancel auth ticket

Parameters:

  • authTicket: number - The ticket handle to cancel

Returns: void

Example:

// Get a ticket
const ticket = steam.user.getAuthSessionTicket();

// ... use the ticket ...

// Clean up when done
steam.user.cancelAuthTicket(ticket.authTicket);

Auth Sessions

Validate incoming authentication tickets from other players.

beginAuthSession(ticketData, steamId)

Begin validating an auth session ticket.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_BeginAuthSession() - Start auth session validation

Parameters:

  • ticketData: Buffer - The raw ticket data received from the client
  • steamId: string - The Steam ID of the user who sent the ticket

Returns: BeginAuthSessionResult

Type:

interface BeginAuthSessionResult {
  success: boolean;                     // Whether the initial validation passed
  result: EBeginAuthSessionResult;      // The result code from BeginAuthSession
  error?: string;                       // Error message if failed
}

enum EBeginAuthSessionResult {
  OK = 0,                  // Ticket is valid for this game and this steamID
  InvalidTicket = 1,       // Ticket is not valid
  DuplicateRequest = 2,    // A ticket has already been submitted for this steamID
  InvalidVersion = 3,      // Ticket is from an incompatible interface version
  GameMismatch = 4,        // Ticket is not for this game
  ExpiredTicket = 5,       // Ticket has expired
}

Example:

// Server receives ticket from client
function onClientConnect(ticketData: Buffer, clientSteamId: string) {
  const result = steam.user.beginAuthSession(ticketData, clientSteamId);
  
  if (result.success) {
    console.log(`Auth session started for ${clientSteamId}`);
  } else {
    console.log(`Auth failed: ${result.error}`);
    disconnectClient(clientSteamId, result.result);
  }
}

endAuthSession(steamId)

End an auth session previously started with beginAuthSession().

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_EndAuthSession() - End auth session

Parameters:

  • steamId: string - The Steam ID of the user whose session to end

Returns: void

Example:

function onClientDisconnect(clientSteamId: string) {
  steam.user.endAuthSession(clientSteamId);
  console.log(`Ended auth session for ${clientSteamId}`);
}

License Verification

Check if a user owns specific apps or DLC.

userHasLicenseForApp(steamId, appId)

Check if a user has a license for a specific app.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_UserHasLicenseForApp() - Check license ownership

Parameters:

  • steamId: string - The Steam ID of the user to check
  • appId: number - The App ID to check ownership for

Returns: EUserHasLicenseForAppResult

Type:

enum EUserHasLicenseForAppResult {
  HasLicense = 0,        // User has a license for specified app
  DoesNotHaveLicense = 1, // User does not have a license for the specified app
  NoAuth = 2,            // User has not been authenticated
}

Example:

// Check if user owns a DLC
const dlcResult = steam.user.userHasLicenseForApp(clientSteamId, 12345);

if (dlcResult === EUserHasLicenseForAppResult.HasLicense) {
  console.log('User owns the DLC');
} else if (dlcResult === EUserHasLicenseForAppResult.DoesNotHaveLicense) {
  console.log('User does not own the DLC');
} else {
  console.log('User not authenticated');
}

Remarks:

  • ⚠️ Important: This function should only be called after successfully authenticating the user with beginAuthSession()
  • The user must be authenticated before their license information is available
  • If called before authentication, it will return NoAuth (2)
  • Common workflow: Receive ticket → beginAuthSession()userHasLicenseForApp() → Grant/deny access

Complete Authentication Example:

// 1. Receive and validate the user's auth ticket
const authResult = steam.user.beginAuthSession(ticketData, clientSteamId);

if (authResult.success) {
  // 2. Now check if they own specific DLC/app
  const licenseResult = steam.user.userHasLicenseForApp(clientSteamId, dlcAppId);
  
  if (licenseResult === EUserHasLicenseForAppResult.HasLicense) {
    console.log('User authenticated and owns the DLC');
  } else if (licenseResult === EUserHasLicenseForAppResult.NoAuth) {
    console.log('User not yet authenticated - call beginAuthSession first');
  }
  
  // 3. Clean up when done
  // steam.user.endAuthSession(clientSteamId);
}

Encrypted Tickets

Request and retrieve encrypted app tickets for secure backend authentication.

requestEncryptedAppTicket(dataToInclude?)

Request an encrypted app ticket from Steam.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_RequestEncryptedAppTicket() - Request encrypted ticket

Parameters:

  • dataToInclude?: Buffer - Optional data to include in the ticket (max 128 bytes)

Returns: Promise<RequestEncryptedAppTicketResult>

Type:

interface RequestEncryptedAppTicketResult {
  success: boolean;    // Whether the request was successful
  error?: string;      // Error message if failed
}

Example:

// Request an encrypted ticket
const result = await steam.user.requestEncryptedAppTicket();
if (result.success) {
  // Now retrieve the ticket
  const ticket = steam.user.getEncryptedAppTicket();
  if (ticket.success) {
    // Send to your backend for verification
    sendToBackend(ticket.ticketData);
  }
}

getEncryptedAppTicket()

Get the encrypted app ticket after requesting it.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetEncryptedAppTicket() - Retrieve encrypted ticket

Returns: GetEncryptedAppTicketResult

Type:

interface GetEncryptedAppTicketResult {
  success: boolean;      // Whether the operation was successful
  ticketData: Buffer;    // The encrypted ticket data
  ticketSize: number;    // The actual ticket size in bytes
  ticketHex: string;     // The ticket as a hex string
  error?: string;        // Error message if failed
}

Example:

const result = steam.user.getEncryptedAppTicket();
if (result.success) {
  console.log(`Got encrypted ticket (${result.ticketSize} bytes)`);
  // Send ticketHex to your backend
  authenticateWithBackend(result.ticketHex);
}

Security Info

Get user security settings and network status.

getUserSecurityInfo()

Get the user's security settings.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_BIsPhoneVerified() - Check phone verification
  • SteamAPI_ISteamUser_BIsTwoFactorEnabled() - Check 2FA status
  • SteamAPI_ISteamUser_BIsPhoneIdentifying() - Check phone identifying
  • SteamAPI_ISteamUser_BIsPhoneRequiringVerification() - Check phone verification requirement

Returns: UserSecurityInfo

Type:

interface UserSecurityInfo {
  phoneVerified: boolean;             // Whether the user's phone number is verified
  twoFactorEnabled: boolean;          // Whether the user has 2FA enabled
  phoneIdentifying: boolean;          // Whether the user's phone number is identifying
  phoneRequiringVerification: boolean; // Whether the user's phone number needs verification
}

Example:

const security = steam.user.getUserSecurityInfo();

if (security.twoFactorEnabled) {
  console.log('User has 2FA enabled');
}

if (security.phoneVerified) {
  console.log('Phone number is verified');
}

isBehindNAT()

Check if the user appears to be behind a NAT.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_BIsBehindNAT() - Check NAT status

Returns: boolean - true if user is behind NAT

Example:

if (steam.user.isBehindNAT()) {
  console.log('User is behind NAT - may need relay');
}

User Info

Get information about the current user.

getPlayerSteamLevel()

Get the user's Steam level.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetPlayerSteamLevel() - Get Steam level

Returns: number - The user's Steam level, or 0 if not available

Example:

const level = steam.user.getPlayerSteamLevel();
console.log(`Steam Level: ${level}`);

getGameBadgeLevel(series, foil)

Get the user's game badge level.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetGameBadgeLevel() - Get badge level

Parameters:

  • series: number - The badge series (usually 1 for games with one badge set)
  • foil: boolean - Whether to get the foil badge (true) or regular badge (false)

Returns: number - The badge level, or 0 if none

Example:

// Get regular badge level
const regularLevel = steam.user.getGameBadgeLevel(1, false);
console.log(`Regular badge level: ${regularLevel}`);

// Get foil badge level
const foilLevel = steam.user.getGameBadgeLevel(1, true);
console.log(`Foil badge level: ${foilLevel}`);

getUserDataFolder()

Get the path to the local user data folder.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetUserDataFolder() - Get user data path

Returns: string | null - The path to the user data folder, or null if not available

Example:

const folder = steam.user.getUserDataFolder();
if (folder) {
  console.log(`User data folder: ${folder}`);
  // Typically: C:\Program Files\Steam\userdata\<steamid>\<appid>\local
}

Market Eligibility

Check if the user can use the Steam Community Market.

getMarketEligibility()

Get the user's Steam Community Market eligibility.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetMarketEligibility() - Get market eligibility

Returns: Promise<MarketEligibilityResult>

Type:

interface MarketEligibilityResult {
  allowed: boolean;             // Whether the user is allowed to use the market
  notAllowedReason: number;     // The reason why the user is not allowed (if not allowed)
  allowedAtTime: number;        // When the user will be allowed (Unix timestamp)
  steamGuardRequiredDays: number; // Days of Steam Guard required
  newDeviceCooldownDays: number;  // New device cooldown days
}

Example:

const eligibility = await steam.user.getMarketEligibility();
if (eligibility.allowed) {
  console.log('User can use the Steam Market');
} else {
  console.log(`Market restricted: reason ${eligibility.notAllowedReason}`);
}

Store Auth URL

Generate authenticated URLs for in-game browser checkout.

requestStoreAuthURL(redirectURL)

Request an authenticated URL for in-game browser store checkout.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_RequestStoreAuthURL() - Request authenticated URL

Parameters:

  • redirectURL: string - The URL to redirect to after authentication

Returns: Promise<StoreAuthURLResult>

Type:

interface StoreAuthURLResult {
  success: boolean;    // Whether the request was successful
  url: string | null;  // The authenticated URL for in-game browser checkout
  error?: string;      // Error message if failed
}

Example:

const result = await steam.user.requestStoreAuthURL('https://store.steampowered.com/');
if (result.success && result.url) {
  // Open in-game browser immediately (URL has short lifetime)
  openBrowser(result.url);
}

Remarks:

  • The URL has a very short lifetime (~seconds) to prevent history-snooping attacks
  • The resulting auth cookie lasts ~1 day; consider refreshing every 12 hours

Duration Control

Support for anti-indulgence compliance (primarily for China region).

getDurationControl()

Get duration control status for the current user.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetDurationControl() - Get duration control status

Returns: Promise<DurationControlResult>

Type:

interface DurationControlResult {
  success: boolean;        // Whether the call was successful
  appId: number;           // App ID generating playtime
  applicable: boolean;     // Whether duration control applies to this user + game
  secondsLast5Hours: number; // Seconds of playtime in last 5 hours
  progress: number;        // Recommended progress (0 = ok, 1 = exit game)
  notification: number;    // Notification to show (0 = none)
  secondsToday: number;    // Playtime on current calendar day in seconds
  secondsRemaining: number; // Playtime remaining until regulatory limit in seconds
}

Example:

const duration = await steam.user.getDurationControl();
if (duration.applicable) {
  console.log(`Time remaining: ${duration.secondsRemaining} seconds`);
  if (duration.progress === 1) {
    console.log('Player should exit the game');
  }
}

setDurationControlOnlineState(state)

Set the duration control online state.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_BSetDurationControlOnlineState() - Set online state

Parameters:

  • state: EDurationControlOnlineState - The online state to set

Type:

enum EDurationControlOnlineState {
  Invalid = 0,       // Default state
  Offline = 1,       // Player is in offline mode
  Online = 2,        // Player is online
  OnlineHighPri = 3, // Player is online in high priority mode (competitive match)
}

Returns: boolean - true if successful

Example:

// Player is in an online match
steam.user.setDurationControlOnlineState(EDurationControlOnlineState.Online);

// Player is in an important competitive match
steam.user.setDurationControlOnlineState(EDurationControlOnlineState.OnlineHighPri);

// Player is playing offline
steam.user.setDurationControlOnlineState(EDurationControlOnlineState.Offline);

Game Advertising

Advertise game server information to friends.

advertiseGame(serverSteamId, serverIP, serverPort)

Advertise the game server to friends for joining.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_AdvertiseGame() - Advertise game server

Parameters:

  • serverSteamId: string - The Steam ID of the game server (use '0' for none)
  • serverIP: number - The IP address of the server (in host byte order)
  • serverPort: number - The port of the server

Returns: void

Example:

// Advertise that the user is on a game server
steam.user.advertiseGame('90071234567890', ipToInt('192.168.1.100'), 27015);

// Clear the advertisement
steam.user.advertiseGame('0', 0, 0);

Voice Recording

Record and transmit voice chat audio.

startVoiceRecording()

Start voice recording.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_StartVoiceRecording() - Start recording

Returns: void

Example:

// Start recording when push-to-talk key is pressed
steam.user.startVoiceRecording();

// In your game loop, retrieve and send voice data
const voice = steam.user.getVoice();
if (voice.result === EVoiceResult.OK) {
  sendToOtherPlayers(voice.voiceData);
}

stopVoiceRecording()

Stop voice recording.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_StopVoiceRecording() - Stop recording

Returns: void

Example:

// Stop recording when push-to-talk key is released
steam.user.stopVoiceRecording();

// Keep fetching voice data until recording fully stops
let voice = steam.user.getVoice();
while (voice.result !== EVoiceResult.NotRecording) {
  if (voice.result === EVoiceResult.OK) {
    sendToOtherPlayers(voice.voiceData);
  }
  voice = steam.user.getVoice();
}

getAvailableVoice()

Get the amount of voice data available.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetAvailableVoice() - Get available voice data size

Returns: GetAvailableVoiceResult

Type:

interface GetAvailableVoiceResult {
  result: EVoiceResult;    // Voice result code
  compressedBytes: number; // Number of compressed bytes available
}

enum EVoiceResult {
  OK = 0,                // Voice call was successful
  NotInitialized = 1,    // Steam voice chat has not been initialized
  NotRecording = 2,      // Voice recording is not active
  NoData = 3,            // No data is available (microphone may be off or silent)
  BufferTooSmall = 4,    // The provided buffer was too small
  DataCorrupted = 5,     // Voice data is corrupted
  Restricted = 6,        // Voice chat is restricted for this user
  UnsupportedCodec = 7,  // The voice codec is not supported
  ReceiverOutOfDate = 8, // The receiver is using an outdated voice codec
  ReceiverDidNotAnswer = 9, // The receiver did not answer
}

Example:

const available = steam.user.getAvailableVoice();
if (available.result === EVoiceResult.OK && available.compressedBytes > 0) {
  console.log(`${available.compressedBytes} bytes of voice data ready`);
}

getVoice(bufferSize?)

Get recorded voice data.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetVoice() - Get recorded voice data

Parameters:

  • bufferSize?: number - Size of the buffer to allocate for voice data (default: 8192)

Returns: GetVoiceResult

Type:

interface GetVoiceResult {
  result: EVoiceResult;        // Voice result code
  voiceData: Buffer | null;    // Buffer containing compressed voice data (if successful)
  bytesWritten: number;        // Number of bytes written to the buffer
}

Example:

// In your game loop:
const voice = steam.user.getVoice();

switch (voice.result) {
  case EVoiceResult.OK:
    // Send compressed voice data to other players
    network.broadcast(voice.voiceData);
    break;
  case EVoiceResult.NoData:
    // Microphone is silent, nothing to do
    break;
  case EVoiceResult.NotRecording:
    // Recording has stopped
    break;
}

decompressVoice(compressedData, sampleRate, bufferSize?)

Decompress voice data.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_DecompressVoice() - Decompress voice data

Parameters:

  • compressedData: Buffer - The compressed voice data to decompress
  • sampleRate: number - The desired output sample rate (11025-48000)
  • bufferSize?: number - Size of the output buffer (default: 20480)

Returns: DecompressVoiceResult

Type:

interface DecompressVoiceResult {
  result: EVoiceResult;       // Voice result code
  audioData: Buffer | null;   // Buffer containing decompressed PCM audio data
  bytesWritten: number;       // Number of bytes written to the buffer
}

Example:

// Receive compressed voice data from another player
const compressedData = network.receiveVoiceData();

// Decompress at optimal sample rate
const sampleRate = steam.user.getVoiceOptimalSampleRate();
const audio = steam.user.decompressVoice(compressedData, sampleRate);

if (audio.result === EVoiceResult.OK) {
  // Play the PCM audio through your audio system
  audioPlayer.playPCM(audio.audioData, sampleRate);
}

getVoiceOptimalSampleRate()

Get the optimal sample rate for voice decompression.

Steamworks SDK Functions:

  • SteamAPI_ISteamUser_GetVoiceOptimalSampleRate() - Get optimal sample rate

Returns: number - The optimal sample rate (typically 11025, 22050, or 44100)

Example:

const optimalRate = steam.user.getVoiceOptimalSampleRate();
console.log(`Optimal sample rate: ${optimalRate} Hz`);

// Use for decompression
const audio = steam.user.decompressVoice(voiceData, optimalRate);

Cleanup

Clean up resources when shutting down.

cancelAllTickets()

Cancel all active auth tickets.

Returns: void

Example:

// Clean up when shutting down
steam.user.cancelAllTickets();

Test Files

Test files are available in the repository:

  • TypeScript tests: tests/ts/test-user.ts
  • JavaScript tests: tests/js/test-user.js

Run tests using npm:

# TypeScript tests
npm run test:user:ts

# JavaScript tests
npm run test:user:js
⚠️ **GitHub.com Fallback** ⚠️