{"_id":"@yotoplay/oauth-device-code-flow","_rev":"31-59d8aabbdde9ebc3054aa0668a350d02","name":"@yotoplay/oauth-device-code-flow","dist-tags":{"latest":"1.2.1"},"versions":{"1.0.0":{"name":"@yotoplay/oauth-device-code-flow","version":"1.0.0","keywords":["auth0","device-code","authentication","oauth","typescript"],"author":{"name":"Yoto"},"license":"MIT","_id":"@yotoplay/oauth-device-code-flow@1.0.0","maintainers":[{"name":"alvinometric","email":"hello@alvin.codes"},{"name":"emmabeynon","email":"emma.beynon@gmail.com"},{"name":"gregyoto","email":"greg@yotoplay.com"},{"name":"tomhazledine","email":"tom@tomhazledine.com"},{"name":"erixk","email":"erixk2807@gmail.com"}],"homepage":"https://github.com/yotoplay/oauth-device-code-flow#readme","bugs":{"url":"https://github.com/yotoplay/oauth-device-code-flow/issues"},"dist":{"shasum":"cd9e5baa97e8b17464aeb530b8fc67679c3b9214","tarball":"https://registry.npmjs.org/@yotoplay/oauth-device-code-flow/-/oauth-device-code-flow-1.0.0.tgz","fileCount":18,"integrity":"sha512-U5chpcIAE9brD62SuAl2XIsOCFoi0IvfSV2QyjXbevjN+4qiUSC6OKt1x5IkBJnw6NSQF4sdkiPDe/SGRbIsIw==","signatures":[{"sig":"MEYCIQCYJp7SZumbkeuLRcqHAgV2SmhJeUMfBzuXoAy0IsmwFAIhAJALgY5bGcEVwYvP0amfqNK/8o8+1DITb+kELJq+uBYg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31856},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"97baf98a381d14c9e0bf5fc3b91f19f6524ed4be","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc","release":"semantic-release","test:watch":"vitest","type-check":"tsc --noEmit","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"gregyoto","email":"greg@yotoplay.com"},"repository":{"url":"git+https://github.com/yotoplay/oauth-device-code-flow.git","type":"git"},"_npmVersion":"10.9.2","description":"Auth0 device code authentication flow for Node.js applications","directories":{},"_nodeVersion":"22.17.0","dependencies":{"axios":"^1.6.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.35.0","vitest":"^3.2.4","@eslint/js":"^9.35.0","typescript":"^5.0.0","@types/node":"^24.3.1","semantic-release":"^24.2.7","@semantic-release/git":"^10.0.1","@typescript-eslint/parser":"^8.43.0","@semantic-release/changelog":"^6.0.3","@typescript-eslint/eslint-plugin":"^8.43.0"},"peerDependencies":{"typescript":">=4.9.0"},"_npmOperationalInternal":{"tmp":"tmp/oauth-device-code-flow_1.0.0_1757363959983_0.9665783358623712","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"@yotoplay/oauth-device-code-flow","version":"0.0.1","keywords":["auth0","device-code","authentication","oauth","typescript"],"author":{"name":"Yoto"},"license":"MIT","_id":"@yotoplay/oauth-device-code-flow@0.0.1","maintainers":[{"name":"alvinometric","email":"hello@alvin.codes"},{"name":"emmabeynon","email":"emma.beynon@gmail.com"},{"name":"gregyoto","email":"greg@yotoplay.com"},{"name":"tomhazledine","email":"tom@tomhazledine.com"},{"name":"erixk","email":"erixk2807@gmail.com"}],"homepage":"https://github.com/yotoplay/oauth-device-code-flow#readme","bugs":{"url":"https://github.com/yotoplay/oauth-device-code-flow/issues"},"dist":{"shasum":"4924c435dd6af801639685431cff63813bb50372","tarball":"https://registry.npmjs.org/@yotoplay/oauth-device-code-flow/-/oauth-device-code-flow-0.0.1.tgz","fileCount":18,"integrity":"sha512-vLJJ1N9AXrROycl7p2Z6eGN6lqiJ08h403Lh1482sTlrCzqbI27fRGAl90LPG0WOv40urJrB8hmF0wHcGvXLqA==","signatures":[{"sig":"MEYCIQDhtK3g8XvH1KCU2UIFqgCULiSr3rI6zXq7FJadopHXWAIhAOudk/UOXpX8WFXY7iPQxYT1gTEtq3MCGiXwifv3QrB9","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30579},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"a3d23cff67f1aab5f46aef6c650ac8fcfc44016f","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc","release":"semantic-release","test:watch":"vitest","type-check":"tsc --noEmit","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"gregyoto","email":"greg@yotoplay.com"},"repository":{"url":"git+https://github.com/yotoplay/oauth-device-code-flow.git","type":"git"},"_npmVersion":"10.9.2","description":"Auth0 device code authentication flow for Node.js applications","directories":{},"_nodeVersion":"22.17.0","dependencies":{"axios":"^1.6.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.35.0","vitest":"^3.2.4","@eslint/js":"^9.35.0","typescript":"^5.0.0","@types/node":"^24.3.1","semantic-release":"^24.2.7","@semantic-release/git":"^10.0.1","@typescript-eslint/parser":"^8.43.0","@semantic-release/changelog":"^6.0.3","@typescript-eslint/eslint-plugin":"^8.43.0"},"peerDependencies":{"typescript":">=4.9.0"},"_npmOperationalInternal":{"tmp":"tmp/oauth-device-code-flow_0.0.1_1757412930972_0.7772991714924931","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@yotoplay/oauth-device-code-flow","version":"1.0.1","keywords":["auth0","device-code","authentication","oauth","typescript"],"author":{"name":"Yoto"},"license":"MIT","_id":"@yotoplay/oauth-device-code-flow@1.0.1","maintainers":[{"name":"alvinometric","email":"hello@alvin.codes"},{"name":"emmabeynon","email":"emma.beynon@gmail.com"},{"name":"gregyoto","email":"greg@yotoplay.com"},{"name":"tomhazledine","email":"tom@tomhazledine.com"},{"name":"erixk","email":"erixk2807@gmail.com"}],"homepage":"https://github.com/yotoplay/oauth-device-code-flow#readme","bugs":{"url":"https://github.com/yotoplay/oauth-device-code-flow/issues"},"dist":{"shasum":"e279e3a65fa5bf166c0b4f8c129c5409079b7ce4","tarball":"https://registry.npmjs.org/@yotoplay/oauth-device-code-flow/-/oauth-device-code-flow-1.0.1.tgz","fileCount":18,"integrity":"sha512-4JWw5wKkneN0qKYM2IHoiFggYfjirH+A+NOUSUR2bEEMj21YVeWWcYulZuuROsybf/AdBfqS9XXkqiRHfEwLtA==","signatures":[{"sig":"MEMCH3Q4jc3Xwxj8wK6OfO7/VBoifAVk8R+joBKCgNhUNoMCIFoIFuXNGV59wkKw7+2fOdqlM2vzkhJk+RXxUOqkLLJC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30579},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"b56fd0fd6befe04932af67d97f2b2f6411bc29e0","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc","release":"semantic-release","test:watch":"vitest","type-check":"tsc --noEmit","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"gregyoto","email":"greg@yotoplay.com"},"repository":{"url":"git+https://github.com/yotoplay/oauth-device-code-flow.git","type":"git"},"_npmVersion":"10.9.2","description":"Auth0 device code authentication flow for Node.js applications","directories":{},"_nodeVersion":"22.17.0","dependencies":{"axios":"^1.6.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.35.0","vitest":"^3.2.4","@eslint/js":"^9.35.0","typescript":"^5.0.0","@types/node":"^24.3.1","semantic-release":"^24.2.7","@semantic-release/git":"^10.0.1","@typescript-eslint/parser":"^8.43.0","@semantic-release/changelog":"^6.0.3","@typescript-eslint/eslint-plugin":"^8.43.0"},"peerDependencies":{"typescript":">=4.9.0"},"_npmOperationalInternal":{"tmp":"tmp/oauth-device-code-flow_1.0.1_1757413039682_0.9602536489697207","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@yotoplay/oauth-device-code-flow","version":"1.0.2","keywords":["auth0","device-code","authentication","oauth","typescript"],"author":{"name":"Yoto"},"license":"MIT","_id":"@yotoplay/oauth-device-code-flow@1.0.2","maintainers":[{"name":"alvinometric","email":"hello@alvin.codes"},{"name":"emmabeynon","email":"emma.beynon@gmail.com"},{"name":"gregyoto","email":"greg@yotoplay.com"},{"name":"tomhazledine","email":"tom@tomhazledine.com"},{"name":"erixk","email":"erixk2807@gmail.com"}],"homepage":"https://github.com/yotoplay/oauth-device-code-flow#readme","bugs":{"url":"https://github.com/yotoplay/oauth-device-code-flow/issues"},"dist":{"shasum":"ada76ca5a2cc8a8ffad681469d793e6a9f92d4de","tarball":"https://registry.npmjs.org/@yotoplay/oauth-device-code-flow/-/oauth-device-code-flow-1.0.2.tgz","fileCount":18,"integrity":"sha512-oj+xaaw1XXTHsgvKAKyk0kgxELs60Qn7lXjEC4ITen149cXfts9//DNnpltPKifk35XKApF7591NI2MWFj0DIA==","signatures":[{"sig":"MEYCIQCvcgKeMVamlISuWpPeBpPdkLHtDrDhTjuE8L7fm08qTAIhAKqHbLQd8/NzMQJjaAMEcohLWvTXAooAQJrRgiKRRHVb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30287},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"601204356b60c0b0eff4819bff2a6abd8fb6760f","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc","release":"semantic-release","test:watch":"vitest","type-check":"tsc --noEmit","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"gregyoto","email":"greg@yotoplay.com"},"repository":{"url":"git+https://github.com/yotoplay/oauth-device-code-flow.git","type":"git"},"_npmVersion":"10.9.2","description":"Auth0 device code authentication flow for Node.js applications","directories":{},"_nodeVersion":"22.17.0","dependencies":{"axios":"^1.6.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.35.0","vitest":"^3.2.4","@eslint/js":"^9.35.0","typescript":"^5.0.0","@types/node":"^24.3.1","semantic-release":"^24.2.7","@semantic-release/git":"^10.0.1","@typescript-eslint/parser":"^8.43.0","@semantic-release/changelog":"^6.0.3","@typescript-eslint/eslint-plugin":"^8.43.0"},"peerDependencies":{"typescript":">=4.9.0"},"_npmOperationalInternal":{"tmp":"tmp/oauth-device-code-flow_1.0.2_1757449327003_0.2378746764356061","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@yotoplay/oauth-device-code-flow","version":"1.2.1","keywords":["auth0","device-code","authentication","oauth","typescript"],"author":{"name":"Yoto"},"license":"MIT","_id":"@yotoplay/oauth-device-code-flow@1.2.1","maintainers":[{"name":"alvinometric","email":"hello@alvin.codes"},{"name":"emmabeynon","email":"emma.beynon@gmail.com"},{"name":"gregyoto","email":"greg@yotoplay.com"},{"name":"tomhazledine","email":"tom@tomhazledine.com"},{"name":"erixk","email":"erixk2807@gmail.com"},{"name":"theresa-yo","email":"theresa.may@yotoplay.com"}],"homepage":"https://github.com/yotoplay/oauth-device-code-flow#readme","bugs":{"url":"https://github.com/yotoplay/oauth-device-code-flow/issues"},"dist":{"shasum":"5b8b3ac5a82693dd8dbd3ce97ef9565258f2158a","tarball":"https://registry.npmjs.org/@yotoplay/oauth-device-code-flow/-/oauth-device-code-flow-1.2.1.tgz","fileCount":18,"integrity":"sha512-d7m925ctUkALaA8+SjaodSfcvQaBVhrAaNmVbbd9KlrbKNDD6xY/Nj38sSyBGjimqlEN+gpRF7lL0bR/PEhY0A==","signatures":[{"sig":"MEQCIBdw1ZVCCCq9evfX4n+eAtNGbJ8Ej6V1RT1Mlzw/EyxtAiAk272WKZcZZeTuQ/H/y6jeNnujpbgmOtYJxeqn0FJl5Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30640},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"5fb643005b34656e542183d5667406fb97589369","scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts","test":"vitest run","build":"tsc","release":"semantic-release","test:watch":"vitest","type-check":"tsc --noEmit","prepublishOnly":"npm run build && npm run test","release:dry-run":"GITHUB_TOKEN=${GITHUB_TOKEN:-$(gh auth token 2>/dev/null || echo 'test-token')} NPM_TOKEN=${NPM_TOKEN:-test-token} semantic-release --dry-run"},"_npmUser":{"name":"gregyoto","email":"greg@yotoplay.com"},"repository":{"url":"git+ssh://git@github.com/yotoplay/oauth-device-code-flow.git","type":"git"},"_npmVersion":"10.9.3","description":"Auth0 device code authentication flow for Node.js applications","directories":{},"_nodeVersion":"20.19.5","dependencies":{"axios":"^1.13.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.39.1","vitest":"^3.2.4","@eslint/js":"^9.39.1","typescript":"^5.9.3","@types/node":"^24.10.1","semantic-release":"^24.2.9","@semantic-release/git":"^10.0.1","@typescript-eslint/parser":"^8.48.0","@semantic-release/changelog":"^6.0.3","@typescript-eslint/eslint-plugin":"^8.48.0"},"peerDependencies":{"typescript":">=4.9.0"},"_npmOperationalInternal":{"tmp":"tmp/oauth-device-code-flow_1.2.1_1764344787835_0.3370308553332708","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-09-08T20:39:19.982Z","modified":"2026-08-18T09:45:59.962Z","1.0.0":"2025-09-08T20:39:20.177Z","0.0.1":"2025-09-09T10:15:31.138Z","1.0.1":"2025-09-09T10:17:20.029Z","1.0.2":"2025-09-09T20:22:07.201Z","1.2.1":"2025-11-28T15:46:28.127Z"},"bugs":{"url":"https://github.com/yotoplay/oauth-device-code-flow/issues"},"author":{"name":"Yoto"},"license":"MIT","homepage":"https://github.com/yotoplay/oauth-device-code-flow#readme","keywords":["auth0","device-code","authentication","oauth","typescript"],"repository":{"url":"git+ssh://git@github.com/yotoplay/oauth-device-code-flow.git","type":"git"},"description":"Auth0 device code authentication flow for Node.js applications","maintainers":[{"email":"dan@danwebb.net","name":"danwrong"},{"email":"rob.beal@yotoplay.com","name":"yoto-robbeal"},{"email":"asta.malyskaite@yotoplay.com","name":"aistyna"},{"email":"vincenzo.ciaccio@gmail.com","name":"vikkio88"},{"email":"eriks@yotoplay.com","name":"erixk"},{"email":"ralph@yotoplay.com","name":"yoto_ralph"},{"email":"hiroshi.sipahioglu@yotoplay.com","name":"hiro11"},{"email":"hasan.abdulgader@yotoplay.com","name":"hasan-yoto"},{"email":"adam.flitney@gmail.com","name":"adamflitney"},{"email":"jaimen.lathia@yotoplay.com","name":"jaimen-yoto"},{"email":"seb.sim@yotoplay.com","name":"seb.sim"},{"email":"caneycode@gmail.com","name":"escaney"},{"email":"tami.effendowicz@yotoplay.com","name":"tami.effendowicz"},{"email":"liam.sennitt@yotoplay.com","name":"liam-yoto"},{"email":"kieran.mozer@yotoplay.com","name":"kmoze"},{"email":"yusyuan.cheng@yotoplay.com","name":"yusyuan-yoto"},{"email":"Olliewarway@gmail.com","name":"owarway"},{"email":"onishiweb@gmail.com","name":"onishiweb"},{"email":"tash.mulla@yotoplay.com","name":"tash.mulla"},{"email":"filip@yotoplay.com","name":"filipyoto"},{"email":"sian.lynch@yotoplay.com","name":"sianyoto"},{"email":"luke.jeffery@yotoplay.com","name":"lukejeffery-yoto"},{"email":"security-integrations@yotoplay.com","name":"yoto-security-integrations"},{"email":"hello@alvin.codes","name":"alvinometric"},{"email":"emma.beynon@gmail.com","name":"emmabeynon"},{"email":"greg@yotoplay.com","name":"gregyoto"},{"email":"tom@tomhazledine.com","name":"tomhazledine"},{"email":"theresa.may@yotoplay.com","name":"theresa-yo"}],"readme":"# @yotoplay/oauth-device-code-flow\n\nA TypeScript library for implementing Auth0 Device Code Flow authentication in Node.js applications. Perfect for CLI tools, IoT devices, and applications that need to authenticate users on devices with limited input capabilities.\n\n## Features\n\n- 🔐 **Complete Device Code Flow**: Full implementation of OAuth 2.0 Device Authorization Grant\n- 🔄 **Token Management**: Built-in token storage, validation, and refresh capabilities\n\n## Installation\n\n```bash\nnpm install @yotoplay/oauth-device-code-flow\n```\n\n## Quick Start\n\n```typescript\nimport { DeviceCodeAuth, TokenManager } from '@yotoplay/oauth-device-code-flow';\n\n// Initialize the auth client\nconst auth = new DeviceCodeAuth({\n  domain: 'your-domain.auth0.com',\n  clientId: 'your-client-id',\n  audience: 'your-api-audience'\n});\n\n// Initialize token manager\nconst tokenManager = new TokenManager('./tokens.json');\n\n// Start the device code flow\nasync function authenticate() {\n  // Step 1: Initiate device code flow (with custom scopes)\n  const deviceCodeResult = await auth.initiateDeviceCodeFlow('openid profile email offline_access content:write media:write');\n  \n  if (!deviceCodeResult.success) {\n    console.error('Failed to initiate auth:', deviceCodeResult.error);\n    return;\n  }\n\n  // Step 2: Display instructions to user\n  console.log('Please visit:', deviceCodeResult.verificationUri);\n  console.log('And enter code:', deviceCodeResult.userCode);\n  \n  // Step 3: Poll for tokens\n  const tokenResult = await auth.pollForToken(\n    deviceCodeResult.deviceCode,\n    deviceCodeResult.interval,\n    300000 // 5 minute timeout\n  );\n  \n  if (tokenResult.success) {\n    // Step 4: Save tokens\n    await tokenManager.saveTokens(tokenResult.tokens);\n    console.log('Authentication successful!');\n  } else {\n    console.error('Authentication failed:', tokenResult.error);\n  }\n}\n\nauthenticate();\n```\n\n## API Reference\n\n### DeviceCodeAuth\n\nMain class for handling Auth0 device code authentication.\n\n#### Constructor\n\n```typescript\nnew DeviceCodeAuth(config: Auth0Config)\n```\n\n**Parameters:**\n- `config.domain`: Your Auth0 domain (e.g., `'your-domain.auth0.com'`)\n- `config.clientId`: Your Auth0 application client ID\n- `config.audience`: Your API audience identifier\n\n#### Methods\n\n##### `initiateDeviceCodeFlow(scope?)`\n\nInitiates the device code flow and returns device code information.\n\n**Parameters:**\n- `scope`: Optional OAuth scopes (default: `\"openid profile email offline_access\"`)\n\n**Returns:** `Promise<DeviceCodeResult>`\n\n```typescript\n// Use default scopes\nconst result = await auth.initiateDeviceCodeFlow();\n\n// Use custom scopes\nconst result = await auth.initiateDeviceCodeFlow('openid profile email offline_access content:write media:write');\n\nif (result.success) {\n  console.log('Visit:', result.verificationUri);\n  console.log('Code:', result.userCode);\n}\n```\n\n##### `pollForToken(deviceCode, interval, timeout?)`\n\nPolls Auth0 for token completion. Handles all OAuth2 error scenarios automatically.\n\n**Parameters:**\n- `deviceCode`: Device code from `initiateDeviceCodeFlow()`\n- `interval`: Polling interval in seconds\n- `timeout`: Optional timeout in milliseconds (default: 300000)\n\n**Returns:** `Promise<PollingResult>`\n\n```typescript\nconst result = await auth.pollForToken(deviceCode, 5, 300000);\nif (result.success) {\n  console.log('Access token:', result.tokens.accessToken);\n}\n```\n\n##### `refreshToken(refreshToken)`\n\nRefreshes an expired access token using a refresh token.\n\n**Parameters:**\n- `refreshToken`: The refresh token to use\n\n**Returns:** `Promise<AuthResult>`\n\n```typescript\nconst result = await auth.refreshToken(refreshToken);\nif (result.success) {\n  console.log('New access token:', result.tokens.accessToken);\n}\n```\n\n### TokenManager\n\nUtility class for managing stored authentication tokens.\n\n#### Constructor\n\n```typescript\nnew TokenManager(tokenPath: string)\n```\n\n**Parameters:**\n- `tokenPath`: File path where tokens will be stored\n\n#### Methods\n\n##### `saveTokens(tokens)`\n\nSaves tokens to the filesystem with secure permissions (600).\n\n```typescript\nawait tokenManager.saveTokens({\n  accessToken: 'your-access-token',\n  refreshToken: 'your-refresh-token',\n  expiresAt: Date.now() + 3600000,\n  tokenType: 'Bearer'\n});\n```\n\n##### `loadTokens()`\n\nLoads tokens from the filesystem.\n\n**Returns:** `Promise<StoredTokens | null>`\n\n```typescript\nconst tokens = await tokenManager.loadTokens();\nif (tokens) {\n  console.log('Loaded tokens:', tokens);\n}\n```\n\n##### `clearTokens()`\n\nRemoves stored tokens from the filesystem.\n\n```typescript\nawait tokenManager.clearTokens();\n```\n\n##### `areTokensValid(tokens)`\n\nChecks if tokens are valid (not expired, not expiring soon).\n\n**Returns:** `boolean`\n\n```typescript\nconst isValid = tokenManager.areTokensValid(tokens);\n```\n\n##### `isTokenExpired(tokens)`\n\nChecks if tokens are expired.\n\n**Returns:** `boolean`\n\n```typescript\nconst isExpired = tokenManager.isTokenExpired(tokens);\n```\n\n## Complete Example\n\nHere's a complete example that demonstrates the full authentication flow:\n\n```typescript\nimport { DeviceCodeAuth, TokenManager } from '@yotoplay/oauth-device-code-flow';\n\nconst auth = new DeviceCodeAuth({\n  domain: 'your-domain.auth0.com',\n  clientId: 'your-client-id',\n  audience: 'your-api-audience'\n});\n\nconst tokenManager = new TokenManager('./auth-tokens.json');\n\nasync function main() {\n  try {\n    // Check if we have valid stored tokens\n    const storedTokens = await tokenManager.loadTokens();\n    \n    if (storedTokens && tokenManager.areTokensValid(storedTokens)) {\n      console.log('Using existing valid tokens');\n      return storedTokens;\n    }\n    \n    // If tokens are expired but we have a refresh token, try to refresh\n    if (storedTokens && storedTokens.refreshToken) {\n      console.log('Refreshing expired tokens...');\n      const refreshResult = await auth.refreshToken(storedTokens.refreshToken);\n      \n      if (refreshResult.success) {\n        await tokenManager.saveTokens(refreshResult.tokens);\n        console.log('Tokens refreshed successfully');\n        return refreshResult.tokens;\n      }\n    }\n    \n    // Start new device code flow\n    console.log('Starting device code authentication...');\n    \n    const deviceCodeResult = await auth.initiateDeviceCodeFlow();\n    if (!deviceCodeResult.success) {\n      throw new Error(`Failed to initiate auth: ${deviceCodeResult.error}`);\n    }\n    \n    console.log('\\n🔐 Authentication Required');\n    console.log('Please visit:', deviceCodeResult.verificationUri);\n    console.log('And enter this code:', deviceCodeResult.userCode);\n    console.log('\\nWaiting for authentication...');\n    \n    const tokenResult = await auth.pollForToken(\n      deviceCodeResult.deviceCode,\n      deviceCodeResult.interval,\n      300000 // 5 minute timeout\n    );\n    \n    if (!tokenResult.success) {\n      throw new Error(`Authentication failed: ${tokenResult.error}`);\n    }\n    \n    await tokenManager.saveTokens(tokenResult.tokens);\n    console.log('✅ Authentication successful!');\n    \n    return tokenResult.tokens;\n    \n  } catch (error) {\n    console.error('Authentication error:', error);\n    throw error;\n  }\n}\n\n// Run the authentication\nmain().then(tokens => {\n  console.log('Ready to make authenticated API calls!');\n  console.log('Access token:', tokens.accessToken);\n}).catch(error => {\n  console.error('Failed to authenticate:', error);\n  process.exit(1);\n});\n```\n\n## Error Handling\n\nThe library provides comprehensive error handling for all OAuth2 scenarios:\n\n- **`authorization_pending`**: User hasn't completed authorization yet (handled automatically)\n- **`slow_down`**: Polling too frequently (interval automatically increased)\n- **`expired_token`**: Device code expired (returns error immediately)\n- **`access_denied`**: User denied authorization (returns error immediately)\n- **Network errors**: Properly caught and returned as error messages\n\n## TypeScript Support\n\nThe library is built with TypeScript and includes comprehensive type definitions:\n\n```typescript\nimport type { \n  Auth0Config, \n  DeviceCodeResponse, \n  TokenResponse, \n  StoredTokens, \n  AuthError, \n  AuthResult, \n  DeviceCodeResult, \n  PollingResult \n} from '@yotoplay/oauth-device-code-flow';\n```\n\n## Requirements\n\n- Node.js 16+ (for ES modules support)\n- TypeScript 4.9+ (if using TypeScript)\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Support\n\nIf you encounter any issues or have questions, please open an issue on GitHub.\n","readmeFilename":"README.md"}