@buoy-gg/license 7.0.36 → 7.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +28 -0
  2. package/lib/commonjs/LicenseManager.js +2 -2
  3. package/lib/commonjs/accountAccess.js +1 -0
  4. package/lib/commonjs/api.js +1 -1
  5. package/lib/commonjs/config.js +2 -2
  6. package/lib/commonjs/device-info.js +1 -1
  7. package/lib/commonjs/device-info.web.js +1 -1
  8. package/lib/commonjs/fingerprint.js +1 -1
  9. package/lib/commonjs/fingerprint.web.js +1 -1
  10. package/lib/commonjs/foreground.js +1 -0
  11. package/lib/commonjs/foreground.web.js +1 -0
  12. package/lib/commonjs/freeToken.js +6 -0
  13. package/lib/commonjs/headless.js +1 -0
  14. package/lib/commonjs/hooks.js +2 -2
  15. package/lib/commonjs/index.js +2 -2
  16. package/lib/commonjs/index.web.js +2 -2
  17. package/lib/commonjs/storage.js +1 -0
  18. package/lib/commonjs/storage.web.js +1 -0
  19. package/lib/commonjs/tier.js +2 -2
  20. package/lib/commonjs/weekendPro.js +2 -2
  21. package/lib/module/LicenseManager.js +1 -1
  22. package/lib/module/accountAccess.js +1 -0
  23. package/lib/module/api.js +1 -1
  24. package/lib/module/config.js +1 -1
  25. package/lib/module/device-info.js +1 -1
  26. package/lib/module/device-info.web.js +1 -1
  27. package/lib/module/fingerprint.js +1 -1
  28. package/lib/module/fingerprint.web.js +1 -1
  29. package/lib/module/foreground.js +1 -0
  30. package/lib/module/foreground.web.js +1 -0
  31. package/lib/module/freeToken.js +6 -0
  32. package/lib/module/headless.js +1 -0
  33. package/lib/module/hooks.js +1 -1
  34. package/lib/module/index.js +1 -1
  35. package/lib/module/index.web.js +1 -1
  36. package/lib/module/storage.js +1 -0
  37. package/lib/module/storage.web.js +1 -0
  38. package/lib/module/tier.js +1 -1
  39. package/lib/module/weekendPro.js +1 -1
  40. package/lib/typescript/commonjs/LicenseManager.d.ts +59 -4
  41. package/lib/typescript/commonjs/LicenseManager.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/accountAccess.d.ts +16 -0
  43. package/lib/typescript/commonjs/accountAccess.d.ts.map +1 -0
  44. package/lib/typescript/commonjs/api.d.ts +32 -3
  45. package/lib/typescript/commonjs/api.d.ts.map +1 -1
  46. package/lib/typescript/commonjs/config.d.ts +46 -13
  47. package/lib/typescript/commonjs/config.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/device-info.d.ts +16 -0
  49. package/lib/typescript/commonjs/device-info.d.ts.map +1 -1
  50. package/lib/typescript/commonjs/device-info.web.d.ts +7 -0
  51. package/lib/typescript/commonjs/device-info.web.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/fingerprint.d.ts +1 -1
  53. package/lib/typescript/commonjs/fingerprint.d.ts.map +1 -1
  54. package/lib/typescript/commonjs/fingerprint.web.d.ts +1 -1
  55. package/lib/typescript/commonjs/fingerprint.web.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/foreground.d.ts +3 -0
  57. package/lib/typescript/commonjs/foreground.d.ts.map +1 -0
  58. package/lib/typescript/commonjs/foreground.web.d.ts +2 -0
  59. package/lib/typescript/commonjs/foreground.web.d.ts.map +1 -0
  60. package/lib/typescript/commonjs/freeToken.d.ts +34 -0
  61. package/lib/typescript/commonjs/freeToken.d.ts.map +1 -0
  62. package/lib/typescript/commonjs/headless.d.ts +10 -0
  63. package/lib/typescript/commonjs/headless.d.ts.map +1 -0
  64. package/lib/typescript/commonjs/hooks.d.ts +7 -3
  65. package/lib/typescript/commonjs/hooks.d.ts.map +1 -1
  66. package/lib/typescript/commonjs/index.d.ts +3 -1
  67. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  68. package/lib/typescript/commonjs/index.web.d.ts +3 -10
  69. package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/storage.d.ts +12 -0
  71. package/lib/typescript/commonjs/storage.d.ts.map +1 -0
  72. package/lib/typescript/commonjs/storage.web.d.ts +6 -0
  73. package/lib/typescript/commonjs/storage.web.d.ts.map +1 -0
  74. package/lib/typescript/commonjs/tier.d.ts +10 -8
  75. package/lib/typescript/commonjs/tier.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/types.d.ts +18 -9
  77. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/weekendPro.d.ts +8 -12
  79. package/lib/typescript/commonjs/weekendPro.d.ts.map +1 -1
  80. package/lib/typescript/module/LicenseManager.d.ts +59 -4
  81. package/lib/typescript/module/LicenseManager.d.ts.map +1 -1
  82. package/lib/typescript/module/accountAccess.d.ts +16 -0
  83. package/lib/typescript/module/accountAccess.d.ts.map +1 -0
  84. package/lib/typescript/module/api.d.ts +32 -3
  85. package/lib/typescript/module/api.d.ts.map +1 -1
  86. package/lib/typescript/module/config.d.ts +46 -13
  87. package/lib/typescript/module/config.d.ts.map +1 -1
  88. package/lib/typescript/module/device-info.d.ts +16 -0
  89. package/lib/typescript/module/device-info.d.ts.map +1 -1
  90. package/lib/typescript/module/device-info.web.d.ts +7 -0
  91. package/lib/typescript/module/device-info.web.d.ts.map +1 -1
  92. package/lib/typescript/module/fingerprint.d.ts +1 -1
  93. package/lib/typescript/module/fingerprint.d.ts.map +1 -1
  94. package/lib/typescript/module/fingerprint.web.d.ts +1 -1
  95. package/lib/typescript/module/fingerprint.web.d.ts.map +1 -1
  96. package/lib/typescript/module/foreground.d.ts +3 -0
  97. package/lib/typescript/module/foreground.d.ts.map +1 -0
  98. package/lib/typescript/module/foreground.web.d.ts +2 -0
  99. package/lib/typescript/module/foreground.web.d.ts.map +1 -0
  100. package/lib/typescript/module/freeToken.d.ts +34 -0
  101. package/lib/typescript/module/freeToken.d.ts.map +1 -0
  102. package/lib/typescript/module/headless.d.ts +10 -0
  103. package/lib/typescript/module/headless.d.ts.map +1 -0
  104. package/lib/typescript/module/hooks.d.ts +7 -3
  105. package/lib/typescript/module/hooks.d.ts.map +1 -1
  106. package/lib/typescript/module/index.d.ts +3 -1
  107. package/lib/typescript/module/index.d.ts.map +1 -1
  108. package/lib/typescript/module/index.web.d.ts +3 -10
  109. package/lib/typescript/module/index.web.d.ts.map +1 -1
  110. package/lib/typescript/module/storage.d.ts +12 -0
  111. package/lib/typescript/module/storage.d.ts.map +1 -0
  112. package/lib/typescript/module/storage.web.d.ts +6 -0
  113. package/lib/typescript/module/storage.web.d.ts.map +1 -0
  114. package/lib/typescript/module/tier.d.ts +10 -8
  115. package/lib/typescript/module/tier.d.ts.map +1 -1
  116. package/lib/typescript/module/types.d.ts +18 -9
  117. package/lib/typescript/module/types.d.ts.map +1 -1
  118. package/lib/typescript/module/weekendPro.d.ts +8 -12
  119. package/lib/typescript/module/weekendPro.d.ts.map +1 -1
  120. package/package.json +33 -9
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # @buoy-gg/license
2
+
3
+ Account validation, access state, and feature checks used by Buoy packages. Application integrations normally initialize accounts through `Buoy.init` or `FloatingDevTools` from `@buoy-gg/core`; installing this package alone does not add a tool menu.
4
+
5
+ ## Application setup
6
+
7
+ Follow the [Quick Start](https://buoy.gg/buoy/latest/docs/quick-start) to sign in and supply a Free or Pro account key. Keep the version compatible with the exact peer requirements of your other Buoy packages. Review peer-dependency warnings when upgrading.
8
+
9
+ ## Entry points
10
+
11
+ | Import | Intended use |
12
+ | --- | --- |
13
+ | `@buoy-gg/license` | Application manager, React hooks, account state, and feature access. |
14
+ | `@buoy-gg/license/headless` | Node-compatible validation and policy functions for custom hosts. |
15
+
16
+ The root exports `LicenseManager`, `useAccountAccess`, `useLicense`, and feature/tier hooks. The headless entry point exports validation, tier resolution, account-access resolution, cache-signature helpers, and lifecycle constants. It does not create a complete account manager for your host.
17
+
18
+ Custom hosts must handle validation, expiry, transient failures, caching, and revalidation. Do not treat a supplied key or a locally selected tier as proof of access. Use the exported policy with validated state, and refresh connected services when admission changes.
19
+
20
+ ## Check integration
21
+
22
+ Initialize through core and confirm that valid account access enables the intended tool. Check the signed-out and failed-validation states too. A temporary network failure and an invalid key are different conditions; preserve that distinction in messages to users.
23
+
24
+ Account and license validation require network requests. Disabling optional development telemetry does not disable validation. See [Telemetry](https://buoy.gg/buoy/latest/docs/telemetry) and [pricing](https://buoy.gg/pricing) for data flows and current plan features.
25
+
26
+ ## License
27
+
28
+ Proprietary software. See the package LICENSE and [Buoy terms](https://buoy.gg/terms).
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.LicenseManager=void 0;var _config=require("./config.js");var _api=require("./api.js");var _fingerprint=require("./fingerprint");var _cacheSignature=require("./cacheSignature.js");var _tier=require("./tier.js");/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.LicenseManager=void 0;var _storage=require("./storage");var _config=require("./config.js");var _api=require("./api.js");var _fingerprint=require("./fingerprint");var _cacheSignature=require("./cacheSignature.js");var _freeToken=require("./freeToken.js");var _tier=require("./tier.js");var _accountAccess=require("./accountAccess.js");var _foreground=require("./foreground");/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -13,4 +13,4 @@
13
13
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
14
14
  * including a free one (`npx buoy login`). Buy a key at
15
15
  * https://buoy.gg or use it free on Saturday and Sunday.
16
- */const LICENSE_STORAGE_DIR="buoy-license";let _FileSystem=null;let _licenseStorage=null;const _memoryStore=new Map;function loadFileSystem(){if(_FileSystem)return _FileSystem;try{const s=require("expo-file-system/legacy");_FileSystem=s?.default||s;if(_FileSystem?.documentDirectory){return _FileSystem}_FileSystem=null}catch{}try{const s=require("expo-file-system");_FileSystem=s?.default||s;if(_FileSystem?.documentDirectory){return _FileSystem}_FileSystem=null}catch{}return null}function getLicenseStorageDir(){const s=loadFileSystem();if(!s?.documentDirectory)return null;return`${s.documentDirectory}${LICENSE_STORAGE_DIR}/`}function getLicenseFilePath(s){const e=getLicenseStorageDir();if(!e)return null;return`${e}${encodeURIComponent(s)}.json`}function loadAsyncStorage(){try{const s=require("@react-native-async-storage/async-storage");const e=s?.default||s;if(typeof e?.getItem==="function"&&typeof e.setItem==="function"&&typeof e.removeItem==="function"){return e}}catch{}return null}function hasLocalStorage(){try{return typeof localStorage!=="undefined"&&!!localStorage}catch{return false}}async function getLicenseStorage(){if(_licenseStorage)return _licenseStorage;const s=loadFileSystem();let e=null;if(s?.documentDirectory){_licenseStorage={async getItem(i){const t=getLicenseFilePath(i);if(!t)return null;try{const r=await s.getInfoAsync(t);if(!r.exists)return null;return await s.readAsStringAsync(t)}catch{return null}},async setItem(i,t){const r=getLicenseStorageDir();const n=getLicenseFilePath(i);if(!r||!n)return;try{const a=await s.getInfoAsync(r);if(!a.exists){await s.makeDirectoryAsync(r,{intermediates:true})}await s.writeAsStringAsync(n,t)}catch(a){console.warn("[Buoy] License storage write failed:",a)}},async removeItem(i){const t=getLicenseFilePath(i);if(!t)return;try{await s.deleteAsync(t,{idempotent:true})}catch{}}}}else if(e=loadAsyncStorage()){const i=e;_licenseStorage={async getItem(t){try{return await i.getItem(t)}catch{return null}},async setItem(t,r){try{await i.setItem(t,r)}catch(n){console.warn("[Buoy] License storage write failed:",n)}},async removeItem(t){try{await i.removeItem(t)}catch{}}}}else if(hasLocalStorage()){_licenseStorage={async getItem(i){try{return localStorage.getItem(i)}catch{return null}},async setItem(i,t){try{localStorage.setItem(i,t)}catch{}},async removeItem(i){try{localStorage.removeItem(i)}catch{}}}}else{_licenseStorage={async getItem(i){return _memoryStore.get(i)??null},async setItem(i,t){_memoryStore.set(i,t)},async removeItem(i){_memoryStore.delete(i)}}}return _licenseStorage}function tierOfCache(s){if(s.tier)return s.tier;return s.isPro?"pro":"anonymous"}class LicenseManagerImpl{state={isInitialized:false,isValidating:false,isPro:false,tier:"anonymous",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};listeners=new Set;revalidationTimer=null;cachedLicense=null;fingerprintPromise=null;initPromise=null;generation=0;retryTimer=null;retryAttempt=0;deviceRegistrationCallback=null;pendingRegistration=null;async initialize(){if(this.initPromise)return this.initPromise;if(this.state.isInitialized)return;this.initPromise=this._doInitialize();return this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;try{const e=await this.loadCachedLicense();if(e){const i=(0,_cacheSignature.verifyCacheSignature)(e);this.cachedLicense=e;this.state.licenseKey=e.licenseKey;this.applyTier(i&&this.isCacheValid(e)?tierOfCache(e):"anonymous");this.state.expiresAt=e.expiresAt?new Date(e.expiresAt):null;if(e.licenseKey&&!(i&&this.isCacheValid(e)&&this.isCacheFresh(e))){this.validateInBackground(e.licenseKey)}}this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer()}catch(e){console.warn("[React Buoy] License initialization failed:",e);this.state.isInitialized=true;this.emit({type:"initialized",isPro:false})}}async setLicenseKey(e,i){if(!e||e.trim().length===0){this.state.error="License key is required";this.state.errorKind="verdict";return false}const t=e.trim().toUpperCase();const r=this.cachedLicense;if(!i?.force&&r&&r.valid&&r.licenseKey===t&&r.fingerprint&&(0,_cacheSignature.verifyCacheSignature)(r)&&this.isCacheValid(r)&&this.isCacheFresh(r)){this.applyTier(tierOfCache(r));this.state.licenseKey=t;this.state.isValidating=false;this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.emit({type:"validated",isPro:this.state.isPro});return true}this.generation+=1;this.cancelRetry();if(i?.force&&!i.isRetry)this.retryAttempt=0;const n=this.generation;this.state.licenseKey=t;this.state.isValidating=true;this.state.error=null;this.state.errorKind=null;this.emit({type:"validating",isPro:this.state.isPro});let a;try{a=await(0,_api.validateLicense)(t)}catch(c){const o=c instanceof Error?c.message:"Validation failed";if(n!==this.generation)return false;if((0,_api.isTransientLicenseError)(c)){this.state.isValidating=false;if(this.cachedLicense&&this.cachedLicense.licenseKey===t&&(0,_cacheSignature.verifyCacheSignature)(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)){this.applyTier(tierOfCache(this.cachedLicense));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=this.cachedLicense.expiresAt?new Date(this.cachedLicense.expiresAt):null;this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=o;this.state.errorKind="transport";this.scheduleRetry(t);this.emit({type:"error",isPro:this.state.isPro,error:o});return false}this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}try{if(n!==this.generation)return false;const c=(0,_api.parseValidationResult)(a);if((0,_api.isFatalLicenseError)(c.code)){this.applyTier((0,_tier.tierAfterFatalError)(c.code));this.state.isValidating=false;this.state.error=c.detail;this.state.errorKind="verdict";await this.clearCachedLicense();this.emit({type:"error",isPro:false,error:c.detail});return false}if(!a.data){this.state.isValidating=false;this.state.error=c.detail||"License not found";this.state.errorKind="verdict";await this.clearCachedLicense();this.emit({type:"error",isPro:false,error:this.state.error});return false}const o=(0,_tier.resolveTier)(a.data);this.applyTier(o);this.state.isValidating=false;this.state.expiresAt=a.data.attributes.expiry?new Date(a.data.attributes.expiry):null;const d=a.data.id;const f=Date.now();let l=this.cachedLicense?.fingerprint;let h=this.cachedLicense?.deviceName;let y=false;if(!l){l=await this.getOrCreateDeviceFingerprint();h=(0,_fingerprint.getDefaultDeviceName)();y=true}let u=false;if(y){if(this.deviceRegistrationCallback){this.pendingRegistration={licenseId:d,licenseKey:t,fingerprint:l};this.deviceRegistrationCallback({fingerprint:l,defaultName:h});u=true}else{this.registerDeviceAsync(d,t,l,h)}}const g={licenseKey:t,licenseId:d,valid:true,isPro:o==="pro",tier:o,expiresAt:a.data.attributes.expiry??null,cachedAt:f,lastValidatedAt:f,fingerprint:u?void 0:l,deviceName:u?void 0:h};this.cachedLicense=await this.persistCache(g);this.retryAttempt=0;this.emit({type:"validated",isPro:this.state.isPro});return true}catch(c){const o=c instanceof Error?c.message:"Validation failed";if(n!==this.generation)return false;this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}}scheduleRetry(e){this.cancelRetry();const i=_config.LICENSE_TRANSIENT_RETRY_DELAYS[this.retryAttempt];if(i===void 0)return;this.retryAttempt+=1;const t=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(t!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},i);if(__DEV__){global.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}}cancelRetry(){if(this.retryTimer){clearTimeout(this.retryTimer);this.retryTimer=null}}async clearLicense(){this.generation+=1;this.cancelRetry();this.retryAttempt=0;this.state.licenseKey=null;this.applyTier("anonymous");this.state.expiresAt=null;this.state.error=null;this.state.errorKind=null;this.cachedLicense=null;await this.clearCachedLicense();this.emit({type:"deactivated",isPro:false})}applyTier(e){this.state.tier=e;this.state.tierSource=e==="anonymous"?"none":"key";this.state.isPro=e==="pro"}getTier(){return this.state.tier}isPro(){return this.state.tier==="pro"}hasEntitlement(e){if(e==="PRO"){return this.state.isPro}return this.state.isPro}getState(){return{...this.state}}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){this.deviceRegistrationCallback=e;return()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}const{licenseId:i,licenseKey:t,fingerprint:r}=this.pendingRegistration;const n=e.trim()||(0,_fingerprint.getDefaultDeviceName)();const a=(0,_fingerprint.getDeviceMetadata)();try{await(0,_api.activateMachine)(i,t,r,n,a)}catch(c){const o=c instanceof Error?c.message:String(c);if(o==="FINGERPRINT_TAKEN"||o==="MACHINE_LIMIT_EXCEEDED"){}else{console.warn("[Buoy] Device registration failed:",o);throw c}}if(this.cachedLicense){this.cachedLicense.fingerprint=r;this.cachedLicense.deviceName=n;this.cachedLicense=await this.persistCache(this.cachedLicense)}this.pendingRegistration=null}emit(e){const i=[...this.listeners];i.forEach(t=>{try{t(e)}catch(r){console.warn("[React Buoy] License listener error:",r)}})}isCacheValid(e){const i=Date.now();const t=i-e.cachedAt;if(t>_config.LICENSE_CACHE_DURATION){return false}if(e.expiresAt){const r=new Date(e.expiresAt).getTime();if(i>r){return false}}return true}isCacheFresh(e){return Date.now()-(e.lastValidatedAt??0)<_config.LICENSE_LAUNCH_VALIDATION_TTL}async persistCache(e){const i=(0,_cacheSignature.signCache)(e);const t=await getLicenseStorage();await t.setItem(_config.LICENSE_STORAGE_KEY,JSON.stringify(i));return i}async loadCachedLicense(){try{const e=await getLicenseStorage();const i=await e.getItem(_config.LICENSE_STORAGE_KEY);if(!i)return null;const t=JSON.parse(i);return t}catch(e){console.warn("[Buoy] Error loading cached license:",e);return null}}getOrCreateDeviceFingerprint(){if(!this.fingerprintPromise){this.fingerprintPromise=(async()=>{const e=await getLicenseStorage();const i=await e.getItem(_config.DEVICE_FINGERPRINT_STORAGE_KEY);if(i)return i;const t=this.cachedLicense?.fingerprint||(0,_fingerprint.generateUUID)();await e.setItem(_config.DEVICE_FINGERPRINT_STORAGE_KEY,t);return t})()}return this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;try{const e=await getLicenseStorage();await e.removeItem(_config.LICENSE_STORAGE_KEY)}catch{}}registerDeviceAsync(e,i,t,r){const n=(0,_fingerprint.getDeviceMetadata)();(0,_api.activateMachine)(e,i,t,r,n).catch(a=>{if(a.message!=="FINGERPRINT_TAKEN"&&a.message!=="MACHINE_LIMIT_EXCEEDED"){console.warn("[Buoy] Device registration failed (non-blocking):",a.message)}})}validateInBackground(e){const i=this.generation;(0,_api.validateLicense)(e).then(async t=>{if(i!==this.generation)return;const r=(0,_api.parseValidationResult)(t);if(r.valid&&t.data){const n=(0,_tier.resolveTier)(t.data);this.applyTier(n);const a=Date.now();this.cachedLicense=await this.persistCache({...this.cachedLicense??{},licenseKey:e,licenseId:t.data.id,valid:true,isPro:n==="pro",tier:n,expiresAt:t.data.attributes.expiry??null,cachedAt:a,lastValidatedAt:a});this.state.expiresAt=t.data.attributes.expiry?new Date(t.data.attributes.expiry):null;this.emit({type:"validated",isPro:this.state.isPro})}else if((0,_api.isFatalLicenseError)(r.code)){console.warn("[React Buoy] Background validation: license is invalid -",r.code);this.applyTier((0,_tier.tierAfterFatalError)(r.code));await this.clearCachedLicense();this.emit({type:"deactivated",isPro:false})}}).catch(t=>{console.warn("[React Buoy] Background validation failed:",t);if((0,_api.isTransientLicenseError)(t)&&i===this.generation&&!this.state.isPro){this.scheduleRetry(e)}})}startRevalidationTimer(){if(this.revalidationTimer){clearInterval(this.revalidationTimer)}this.revalidationTimer=setInterval(()=>{if(this.state.licenseKey&&!this.state.isValidating){this.validateInBackground(this.state.licenseKey)}},_config.LICENSE_REVALIDATION_INTERVAL);if(__DEV__){global.__LICENSE_MANAGER_TIMER__=this.revalidationTimer}}stopRevalidationTimer(){if(this.revalidationTimer){clearInterval(this.revalidationTimer);this.revalidationTimer=null}this.cancelRetry()}async forceReregister(){if(this.cachedLicense){this.cachedLicense.fingerprint=void 0;this.cachedLicense.deviceName=void 0}this.fingerprintPromise=null;await this.clearCachedLicense();try{const e=await getLicenseStorage();await e.removeItem(_config.DEVICE_FINGERPRINT_STORAGE_KEY)}catch{}}}const LicenseManager=exports.LicenseManager=new LicenseManagerImpl;if(__DEV__){if(global.__LICENSE_MANAGER_TIMER__){clearInterval(global.__LICENSE_MANAGER_TIMER__)}if(global.__LICENSE_MANAGER_RETRY_TIMER__){clearTimeout(global.__LICENSE_MANAGER_RETRY_TIMER__);global.__LICENSE_MANAGER_RETRY_TIMER__=void 0}}
16
+ */async function boundedStorage(o,e){let t;try{return await Promise.race([o,new Promise(i=>{t=setTimeout(()=>i(e),15e3)})])}finally{if(t)clearTimeout(t)}}function tierOfCache(o){if(o.tier==="pro"||o.tier==="free")return o.tier;return o.isPro?"pro":"free"}class LicenseManagerImpl{state={isInitialized:false,isValidating:false,isPro:false,tier:"free",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};listeners=new Set;revalidationTimer=null;cachedLicense=null;fingerprintPromise=null;initPromise=null;generation=0;persistence=Promise.resolve();verifiedAt=null;expiryTimer=null;removeForegroundListener=null;retryTimer=null;retryAttempt=0;deviceRegistrationCallback=null;pendingRegistration=null;async initialize(){if(this.initPromise)return this.initPromise;if(this.state.isInitialized)return;this.initPromise=this._doInitialize();return this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;const e=this.generation;try{const t=await boundedStorage(this.loadCachedLicense(),null);if(e!==this.generation){this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer();return}if(t&&(this.configuredKey===void 0||t.licenseKey===this.configuredKey)){const i=(0,_cacheSignature.verifyCacheSignature)(t);this.cachedLicense=t;this.state.licenseKey=t.licenseKey;if(i&&this.isCacheValid(t))this.applyTier(tierOfCache(t));else this.lock();this.state.expiresAt=t.expiresAt?new Date(t.expiresAt):null;if(i&&this.isCacheValid(t))this.setVerifiedAt(t.cachedAt);if(this.configuredKey===void 0&&t.licenseKey&&!(i&&this.isCacheValid(t)&&this.isCacheFresh(t))){this.validateInBackground(t.licenseKey)}}this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer()}catch(t){console.warn("[React Buoy] License initialization failed:",t);this.state.isInitialized=true;this.emit({type:"initialized",isPro:false})}}async configure(e){if(e===void 0){await this.initialize();return this.hasAccountAccess()}const t=e.trim().toUpperCase();const i=++this.generation;this.cancelRetry();this.configuredKey=t||null;if(this.state.licenseKey!==this.configuredKey)this.lock();this.state.licenseKey=this.configuredKey;this.state.isValidating=!!t;this.emit({type:"validating",isPro:this.isPro()});await this.initialize();if(i!==this.generation)return false;if(!t){await this.clearLicense();return false}return this.setLicenseKey(t)}async setLicenseKey(e,t){if(!e||e.trim().length===0){this.state.error="License key is required";this.state.errorKind="verdict";return false}const i=e.trim().toUpperCase();const s=++this.generation;this.cancelRetry();if(!t?.isRetry)this.retryAttempt=0;if(this.state.licenseKey!==i)this.lock();this.state.licenseKey=i;this.state.isValidating=true;this.state.error=null;this.state.errorKind=null;this.emit({type:"validating",isPro:this.isPro()});if((0,_freeToken.isBuoyToken)(i))return this.admitToken(i,s);if(!this.cachedLicense){const a=await boundedStorage(this.loadCachedLicense(),null);if(s!==this.generation)return false;if(a?.licenseKey===i){this.cachedLicense=a;if((0,_cacheSignature.verifyCacheSignature)(a)&&this.isCacheValid(a)){this.applyTier(tierOfCache(a));this.state.expiresAt=a.expiresAt?new Date(a.expiresAt):null;this.setVerifiedAt(a.cachedAt);this.emit({type:"validating",isPro:this.isPro()})}}}const r=this.cachedLicense;if(!t?.force&&r&&r.valid&&r.licenseKey===i&&r.fingerprint&&(0,_cacheSignature.verifyCacheSignature)(r)&&this.isCacheValid(r)&&this.isCacheFresh(r)){this.applyTier(tierOfCache(r));this.state.licenseKey=i;this.state.isValidating=false;this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);this.emit({type:"validated",isPro:this.state.isPro});return true}const c=await boundedStorage(this.loadHold(),null);if(s!==this.generation)return false;const u=(c?.backoffUntil??0)-Date.now();if(u>0){return this.standDown(i,s,"License server is rate limited; retrying later.",u)}if(!t?.force&&c?.key===i&&c.verdictAt!==void 0&&Date.now()-c.verdictAt>=0&&Date.now()-c.verdictAt<_config.LICENSE_VERDICT_CACHE_DURATION){this.lock();this.state.isValidating=false;this.state.error=c.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});return false}let n;try{n=await(0,_api.validateLicense)(i)}catch(a){const h=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;if((0,_api.isTransientLicenseError)(a)){if((0,_api.isRateLimited)(a)){const l=Math.min((0,_api.backoffAfter)(a,_config.LICENSE_QUOTA_COOLDOWN,_config.LICENSE_RATE_LIMIT_DEFAULT_WAIT)*2**this.retryAttempt,_config.LICENSE_QUOTA_COOLDOWN);this.retryAttempt+=1;await this.saveHold({...this.hold,backoffUntil:Date.now()+l});if(s!==this.generation)return false;return this.standDown(i,s,h,l)}this.state.isValidating=false;if(this.cachedLicense&&this.cachedLicense.licenseKey===i&&(0,_cacheSignature.verifyCacheSignature)(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)){this.applyTier(tierOfCache(this.cachedLicense));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=this.cachedLicense.expiresAt?new Date(this.cachedLicense.expiresAt):null;this.setVerifiedAt(this.cachedLicense.cachedAt);if(!this.isPro())this.scheduleRetry(i);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=h;this.state.errorKind="transport";this.scheduleRetry(i);this.emit({type:"error",isPro:this.state.isPro,error:h});return false}this.state.isValidating=false;this.state.error=h;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:h});return false}try{if(s!==this.generation)return false;const a=(0,_api.parseValidationResult)(n);const h=n.data?.relationships?.product?.data?.id;if((!h||h===_config.KEYGEN_CONFIG.productId)&&a.code==="EXPIRED"&&((0,_tier.isRecognizedAccount)(n.data)||this.cachedLicense?.licenseKey===i&&(0,_cacheSignature.verifyCacheSignature)(this.cachedLicense)&&this.isCacheValid(this.cachedLicense))){const p=Date.now();const T=await this.saveCache({licenseKey:i,licenseId:n.data?.id??"",valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:p,lastValidatedAt:p,fingerprint:this.cachedLicense?.licenseKey===i?this.cachedLicense.fingerprint:void 0},s);if(s!==this.generation||!T)return false;this.cachedLicense=T;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(p);this.emit({type:"validated",isPro:false});return true}if((0,_api.isFatalLicenseError)(a.code)||!(0,_api.isAcceptedValidation)(n)){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();await this.saveHold({key:i,code:a.code,detail:this.state.error,verdictAt:Date.now()});return false}if(!n.data){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License not found";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const l=(0,_tier.resolveTier)(n.data);const _=n.data.id;const g=Date.now();const A=(0,_api.machineCount)(n)>=_config.LICENSE_FLEET_MACHINE_THRESHOLD;const m=(0,_fingerprint.isDevBundle)();const I=m&&!A;const R=l==="free"&&(A||!m);let d=this.cachedLicense?.fingerprint;let f=this.cachedLicense?.deviceName;let v=false;if(!d){d=await boundedStorage(this.getOrCreateDeviceFingerprint(),(0,_fingerprint.generateUUID)());if(s!==this.generation)return false;f=(0,_fingerprint.getDefaultDeviceName)();v=I}let y=false;if(v){if(this.deviceRegistrationCallback){this.pendingRegistration={licenseId:_,licenseKey:i,fingerprint:d};this.deviceRegistrationCallback({fingerprint:d,defaultName:f});y=true}else{this.registerDeviceAsync(_,i,d,f)}}const E={licenseKey:i,licenseId:_,valid:true,isPro:l==="pro",tier:l,expiresAt:n.data.attributes.expiry??null,cachedAt:g,lastValidatedAt:g,fingerprint:y?void 0:d,deviceName:y?void 0:f,quiet:R||void 0};const L=await this.saveCache(E,s);if(s!==this.generation||!L)return false;this.cachedLicense=L;this.applyTier(l);this.state.isValidating=false;this.state.expiresAt=E.expiresAt?new Date(E.expiresAt):null;this.setVerifiedAt(g);if(this.hold)await this.saveHold(null);if(s!==this.generation)return false;this.retryAttempt=0;this.emit({type:"validated",isPro:this.state.isPro});return true}catch(a){const h=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;this.state.isValidating=false;this.state.error=h;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:h});return false}}scheduleRetry(e){this.cancelRetry();const t=_config.LICENSE_TRANSIENT_RETRY_DELAYS[this.retryAttempt];if(t===void 0)return;this.retryAttempt+=1;const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},t);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}}async admitToken(e,t){const i=(0,_freeToken.verifyFreeToken)(e);if(t!==this.generation)return false;if(!i){this.lock();this.state.isValidating=false;this.state.error="This key is not valid. Check that it was copied completely.";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const s=Date.now();const r=this.cachedLicense?.fingerprint??await boundedStorage(this.getOrCreateDeviceFingerprint(),(0,_fingerprint.generateUUID)());if(t!==this.generation)return false;const c=await this.saveCache({licenseKey:e,licenseId:`token:${i.accountHash}`,valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:s,lastValidatedAt:s,fingerprint:r,deviceName:this.cachedLicense?.deviceName??(0,_fingerprint.getDefaultDeviceName)(),quiet:true},t);if(t!==this.generation||!c)return false;this.cachedLicense=c;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(s);this.retryAttempt=0;this.emit({type:"validated",isPro:false});return true}standDown(e,t,i,s){if(t!==this.generation)return false;this.state.isValidating=false;const r=this.cachedLicense;if(r&&r.licenseKey===e&&(0,_cacheSignature.verifyCacheSignature)(r)&&this.isCacheValid(r)){this.applyTier(tierOfCache(r));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);if(!this.isPro())this.scheduleRetryIn(e,s);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=i;this.state.errorKind="transport";this.scheduleRetryIn(e,s);this.emit({type:"error",isPro:this.state.isPro,error:i});return false}scheduleRetryIn(e,t){this.cancelRetry();const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},Math.max(1,Math.min(t,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)devTimers.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}cancelRetry(){if(this.retryTimer){clearTimeout(this.retryTimer);this.retryTimer=null}}async clearLicense(){this.generation+=1;this.cancelRetry();this.retryAttempt=0;this.configuredKey=null;this.state.licenseKey=null;this.lock();this.state.expiresAt=null;this.state.error=null;this.state.errorKind=null;this.cachedLicense=null;this.pendingRegistration=null;this.state.isValidating=false;this.emit({type:"deactivated",isPro:false});await this.clearCachedLicense();if(this.hold?.verdictAt!==void 0){await this.saveHold(this.hold.backoffUntil?{backoffUntil:this.hold.backoffUntil}:null)}}applyTier(e){this.state.tier=e;this.state.tierSource="key";this.state.isPro=e==="pro"}lock(){this.state.tier="free";this.state.tierSource="none";this.state.isPro=false;this.verifiedAt=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null}getTier(){if(!this.hasAccountAccess())return"free";if(this.state.expiresAt&&Date.now()>=this.state.expiresAt.getTime())return"free";return this.state.tier}isPro(){return this.getTier()==="pro"}hasEntitlement(e){return this.isPro()}getState(){const e=this.getAccountAccess();const t=this.getTier();return{...this.state,tier:t,isPro:t==="pro",access:e}}getAccountAccess(){return(0,_accountAccess.resolveAccountAccess)({initialized:this.state.isInitialized,validating:this.state.isValidating,key:this.state.licenseKey,tierSource:this.state.tierSource,verifiedAt:this.verifiedAt})}hasAccountAccess(){return this.getAccountAccess().status==="admitted"}setVerifiedAt(e){this.verifiedAt=e;if(this.expiryTimer)clearTimeout(this.expiryTimer);const t=e+_config.LICENSE_CACHE_DURATION;const i=this.state.expiresAt?.getTime();const s=i&&i>Date.now()?Math.min(t,i):t;const r=s-Date.now();this.expiryTimer=setTimeout(()=>{this.expiryTimer=null;if(this.verifiedAt!==e)return;this.emit({type:"validated",isPro:this.isPro()});if(Date.now()<t)this.setVerifiedAt(e)},Math.max(1,Math.min(r,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)devTimers.__LICENSE_MANAGER_EXPIRY_TIMER__=this.expiryTimer}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){this.deviceRegistrationCallback=e;return()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}const{licenseId:t,licenseKey:i,fingerprint:s}=this.pendingRegistration;const r=this.generation;const c=e.trim()||(0,_fingerprint.getDefaultDeviceName)();const u=(0,_fingerprint.getDeviceMetadata)();try{await(0,_api.activateMachine)(t,i,s,c,u)}catch(n){const a=n instanceof Error?n.message:String(n);if(a==="FINGERPRINT_TAKEN"||a==="MACHINE_LIMIT_EXCEEDED"){}else{console.warn("[Buoy] Device registration failed:",a);throw n}}if(r!==this.generation)return;if(this.cachedLicense?.licenseKey===i){const n=await this.saveCache({...this.cachedLicense,fingerprint:s,deviceName:c},r);if(r!==this.generation)return;if(n)this.cachedLicense=n}this.pendingRegistration=null}emit(e){const t=[...this.listeners];t.forEach(i=>{try{i(e)}catch(s){console.warn("[React Buoy] License listener error:",s)}})}isCacheValid(e){const t=Date.now();const i=t-e.cachedAt;if(!e.valid||!Number.isFinite(e.cachedAt)||i<0||i>=_config.LICENSE_CACHE_DURATION){return false}return true}isCacheFresh(e){const t=this.isQuiet(e)?_config.LICENSE_QUIET_VALIDATION_TTL:_config.LICENSE_LAUNCH_VALIDATION_TTL;return Date.now()-(e.lastValidatedAt??0)<t}isQuiet(e){if(e.quiet!==void 0)return e.quiet;return tierOfCache(e)==="free"&&!(0,_fingerprint.isDevBundle)()}async loadHold(){if(this.hold!==void 0)return this.hold;try{const e=await(0,_storage.getLicenseStorage)();const t=await e.getItem(_config.LICENSE_HOLD_STORAGE_KEY);const i=t?JSON.parse(t):null;this.hold=i&&typeof i==="object"?i:null}catch{this.hold=null}return this.hold}async saveHold(e){this.hold=e;try{const t=await(0,_storage.getLicenseStorage)();if(e)await t.setItem(_config.LICENSE_HOLD_STORAGE_KEY,JSON.stringify(e));else await t.removeItem(_config.LICENSE_HOLD_STORAGE_KEY)}catch{}}async persistCache(e){const t=(0,_cacheSignature.signCache)(e);const i=await(0,_storage.getLicenseStorage)();await i.setItem(_config.LICENSE_STORAGE_KEY,JSON.stringify(t));return t}saveCache(e,t){const i=this.persistence.catch(()=>{}).then(async()=>{if(t!==this.generation)return null;const s=await this.persistCache(e);return t===this.generation?s:null});this.persistence=i;return boundedStorage(i,(0,_cacheSignature.signCache)(e))}async loadCachedLicense(){try{await this.persistence.catch(()=>{});const e=await(0,_storage.getLicenseStorage)();const t=await e.getItem(_config.LICENSE_STORAGE_KEY);if(!t)return null;const i=JSON.parse(t);return i}catch(e){console.warn("[Buoy] Error loading cached license:",e);return null}}getOrCreateDeviceFingerprint(){if(!this.fingerprintPromise){this.fingerprintPromise=(async()=>{const e=await(0,_storage.getLicenseStorage)();const t=await e.getItem(_config.DEVICE_FINGERPRINT_STORAGE_KEY);if(t)return t;const i=this.cachedLicense?.fingerprint||(0,_fingerprint.generateUUID)();await e.setItem(_config.DEVICE_FINGERPRINT_STORAGE_KEY,i);return i})()}return this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;const e=this.persistence.catch(()=>{}).then(async()=>{const t=await(0,_storage.getLicenseStorage)();await t.removeItem(_config.LICENSE_STORAGE_KEY)});this.persistence=e;await boundedStorage(e.catch(()=>{}),void 0)}registerDeviceAsync(e,t,i,s){const r=(0,_fingerprint.getDeviceMetadata)();(0,_api.activateMachine)(e,t,i,s,r).catch(c=>{if(c.message!=="FINGERPRINT_TAKEN"&&c.message!=="MACHINE_LIMIT_EXCEEDED"){console.warn("[Buoy] Device registration failed (non-blocking):",c.message)}})}validateInBackground(e){void this.setLicenseKey(e,{force:true,isRetry:true})}refreshAccess(){this.emit({type:"validated",isPro:this.isPro()})}startRevalidationTimer(){if(!this.removeForegroundListener){this.removeForegroundListener=(0,_foreground.subscribeForeground)(()=>this.refreshAccess());if(typeof __DEV__!=="undefined"&&__DEV__)devTimers.__LICENSE_MANAGER_FOREGROUND_OFF__=this.removeForegroundListener}if(this.revalidationTimer){clearInterval(this.revalidationTimer)}this.revalidationTimer=setInterval(()=>{if(!this.state.licenseKey||this.state.isValidating)return;const e=this.cachedLicense;if(e&&e.licenseKey===this.state.licenseKey&&this.isCacheFresh(e))return;this.validateInBackground(this.state.licenseKey)},_config.LICENSE_REVALIDATION_INTERVAL);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_TIMER__=this.revalidationTimer}}stopRevalidationTimer(){this.removeForegroundListener?.();this.removeForegroundListener=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null;if(this.revalidationTimer){clearInterval(this.revalidationTimer);this.revalidationTimer=null}this.cancelRetry()}async forceReregister(){if(this.cachedLicense){this.cachedLicense.fingerprint=void 0;this.cachedLicense.deviceName=void 0}this.fingerprintPromise=null;await this.clearCachedLicense();try{const e=await(0,_storage.getLicenseStorage)();await e.removeItem(_config.DEVICE_FINGERPRINT_STORAGE_KEY)}catch{}}}const LicenseManager=exports.LicenseManager=new LicenseManagerImpl;const devTimers=globalThis;if(typeof __DEV__!=="undefined"&&__DEV__){devTimers.__LICENSE_MANAGER_FOREGROUND_OFF__?.();devTimers.__LICENSE_MANAGER_FOREGROUND_OFF__=void 0;if(devTimers.__LICENSE_MANAGER_EXPIRY_TIMER__)clearTimeout(devTimers.__LICENSE_MANAGER_EXPIRY_TIMER__);if(devTimers.__LICENSE_MANAGER_TIMER__){clearInterval(devTimers.__LICENSE_MANAGER_TIMER__)}if(devTimers.__LICENSE_MANAGER_RETRY_TIMER__){clearTimeout(devTimers.__LICENSE_MANAGER_RETRY_TIMER__);devTimers.__LICENSE_MANAGER_RETRY_TIMER__=void 0}}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.resolveAccountAccess=resolveAccountAccess;var _config=require("./config.js");function resolveAccountAccess(i,r=Date.now()){const e=i.verifiedAt!==null&&Number.isFinite(i.verifiedAt)&&i.verifiedAt<=r?i.verifiedAt+_config.LICENSE_CACHE_DURATION:null;if(i.initialized&&i.key&&i.tierSource!=="none"&&e!==null&&r<e){return{status:"admitted",reason:null,validUntil:e}}if(e!==null&&r>=e){return{status:"locked",reason:"verification_expired",validUntil:e}}if(!i.initialized||i.validating){return{status:"initializing",reason:"checking",validUntil:e}}return{status:"locked",reason:e!==null&&r>=e?"verification_expired":"account_required",validUntil:e}}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.LicenseTransportError=void 0;exports.activateMachine=activateMachine;exports.isFatalLicenseError=isFatalLicenseError;exports.isTransientLicenseError=isTransientLicenseError;exports.parseValidationResult=parseValidationResult;exports.validateLicense=validateLicense;var _config=require("./config.js");const{accountId,productToken,apiUrl}=_config.KEYGEN_CONFIG;class LicenseTransportError extends Error{isTransient=true;constructor(r,n){super(r);this.name="LicenseTransportError";this.status=n}}exports.LicenseTransportError=LicenseTransportError;function isTransientLicenseError(e){if(e instanceof LicenseTransportError)return true;if(e instanceof TypeError)return true;return typeof e==="object"&&e!==null&&e.isTransient===true}async function describeFailure(e){try{const r=await e.json();return r.errors?.[0]?.detail||`HTTP ${e.status}`}catch{return`HTTP ${e.status}`}}function getBaseHeaders(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}function getLicenseAuthHeaders(e){return{...getBaseHeaders(),Authorization:`License ${e}`}}function getProductTokenHeaders(){return{...getBaseHeaders(),Authorization:`Bearer ${productToken}`}}async function validateLicense(e){const r=`${apiUrl}/${accountId}/licenses/actions/validate-key`;const n={meta:{key:e}};let t;try{t=await fetch(r,{method:"POST",headers:getBaseHeaders(),body:JSON.stringify(n)})}catch(i){throw new LicenseTransportError(i instanceof Error?i.message:"Network request failed",null)}if(!t.ok){throw new LicenseTransportError(await describeFailure(t),t.status)}try{return await t.json()}catch{throw new LicenseTransportError("License server returned an unreadable response",t.status)}}async function activateMachine(e,r,n,t,i){const u=`${apiUrl}/${accountId}/machines`;const d={data:{type:"machines",attributes:{fingerprint:n,name:t,metadata:i||{}},relationships:{license:{data:{type:"licenses",id:e}}}}};let s=await fetch(u,{method:"POST",headers:getLicenseAuthHeaders(r),body:JSON.stringify(d)});if(!s.ok){const a=await s.json();const o=a.errors?.[0]?.detail||"";const c=a.errors?.[0]?.code;if(o.toLowerCase().includes("authentication is not allowed by policy")){s=await fetch(u,{method:"POST",headers:getProductTokenHeaders(),body:JSON.stringify(d)})}else if(c==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}else if(c==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}else{throw new Error(o)}}if(!s.ok){const a=await s.json();const o=a.errors?.[0]?.code;if(o==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}if(o==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}const c=a.errors?.[0]?.detail||`HTTP ${s.status}`;throw new Error(c)}return s.json()}function parseValidationResult(e){const{meta:r,data:n}=e;return{valid:r.valid,code:r.code,detail:r.detail,metadata:n?.attributes?.metadata}}function isFatalLicenseError(e){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(e)}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.LicenseTransportError=void 0;exports.activateMachine=activateMachine;exports.backoffAfter=backoffAfter;exports.isAcceptedValidation=isAcceptedValidation;exports.isFatalLicenseError=isFatalLicenseError;exports.isRateLimited=isRateLimited;exports.isTransientLicenseError=isTransientLicenseError;exports.machineCount=machineCount;exports.parseValidationResult=parseValidationResult;exports.validateLicense=validateLicense;var _config=require("./config.js");const{accountId,productToken,apiUrl}=_config.KEYGEN_CONFIG;class LicenseTransportError extends Error{isTransient=true;constructor(e,n,o=null){super(e);this.name="LicenseTransportError";this.status=n;this.retryAfterMs=o}}exports.LicenseTransportError=LicenseTransportError;function isRateLimited(t){const e=t?.status;return e===429||e===402}function backoffAfter(t,e,n){if(t.status===402)return e;return t.retryAfterMs??n}function readRetryAfter(t){const e=r=>{try{return t.headers?.get?.(r)??null}catch{return null}};const n=e("Retry-After");if(n){const r=Number(n);if(Number.isFinite(r)&&r>=0)return r*1e3;const a=Date.parse(n);if(Number.isFinite(a))return Math.max(0,a-Date.now())}const o=Number(e("X-RateLimit-Reset"));if(Number.isFinite(o)&&o>0)return Math.max(0,o*1e3-Date.now());return null}function isTransientLicenseError(t){if(t instanceof LicenseTransportError)return true;if(t instanceof TypeError)return true;return typeof t==="object"&&t!==null&&t.isTransient===true}async function describeFailure(t){try{const e=await t.json();return e.errors?.[0]?.detail||`HTTP ${t.status}`}catch{return`HTTP ${t.status}`}}function getBaseHeaders(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}function getLicenseAuthHeaders(t){return{...getBaseHeaders(),Authorization:`License ${t}`}}function getProductTokenHeaders(){return{...getBaseHeaders(),Authorization:`Bearer ${productToken}`}}async function requestValidation(t,e){const n=`${apiUrl}/${accountId}/licenses/actions/validate-key`;const o={meta:{key:t}};let r;try{r=await fetch(n,{signal:e,method:"POST",headers:getBaseHeaders(),body:JSON.stringify(o)})}catch(a){throw new LicenseTransportError(a instanceof Error?a.message:"Network request failed",null)}if(!r.ok){throw new LicenseTransportError(await describeFailure(r),r.status,r.status===429?readRetryAfter(r):null)}try{const a=await r.json();if(!a||typeof a!=="object"||typeof a.meta?.valid!=="boolean"||typeof a.meta?.code!=="string"||!a.meta.code)throw new Error("Missing license verdict");return a}catch{throw new LicenseTransportError("License server returned an unreadable response",r.status)}}async function validateLicense(t){const e=typeof AbortController==="function"?new AbortController:null;let n;try{return await Promise.race([requestValidation(t,e?.signal),new Promise((o,r)=>{n=setTimeout(()=>{r(new LicenseTransportError("License verification timed out. Please retry.",null));e?.abort()},15e3)})])}finally{if(n)clearTimeout(n)}}function isAcceptedValidation(t){if(!t.data)return false;const e=t.data.relationships?.product?.data?.id;if(e&&e!==_config.KEYGEN_CONFIG.productId)return false;if(t.meta.valid&&t.meta.code==="VALID")return true;return["OVERDUE","NO_MACHINE","NO_MACHINES","TOO_MANY_MACHINES","TOO_MANY_CORES","TOO_MANY_PROCESSES","FINGERPRINT_SCOPE_MISMATCH","HEARTBEAT_NOT_STARTED","HEARTBEAT_DEAD"].includes(t.meta.code)}function machineCount(t){const e=t.data?.relationships?.machines?.meta?.count;return typeof e==="number"&&Number.isFinite(e)?e:0}async function activateMachine(t,e,n,o,r){const a=`${apiUrl}/${accountId}/machines`;const d={data:{type:"machines",attributes:{fingerprint:n,name:o,metadata:r||{}},relationships:{license:{data:{type:"licenses",id:t}}}}};let i=await fetch(a,{method:"POST",headers:getLicenseAuthHeaders(e),body:JSON.stringify(d)});if(!i.ok){const s=await i.json();const c=s.errors?.[0]?.detail||"";const u=s.errors?.[0]?.code;if(c.toLowerCase().includes("authentication is not allowed by policy")){i=await fetch(a,{method:"POST",headers:getProductTokenHeaders(),body:JSON.stringify(d)})}else if(u==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}else if(u==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}else{throw new Error(c)}}if(!i.ok){const s=await i.json();const c=s.errors?.[0]?.code;if(c==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}if(c==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}const u=s.errors?.[0]?.detail||`HTTP ${i.status}`;throw new Error(u)}return i.json()}function parseValidationResult(t){const{meta:e,data:n}=t;return{valid:e.valid,code:e.code,detail:e.detail,metadata:n?.attributes?.metadata}}function isFatalLicenseError(t){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(t)}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.LICENSE_TRANSIENT_RETRY_DELAYS=exports.LICENSE_STORAGE_KEY=exports.LICENSE_REVALIDATION_INTERVAL=exports.LICENSE_LAUNCH_VALIDATION_TTL=exports.LICENSE_CACHE_DURATION=exports.KEYGEN_POLICIES=exports.KEYGEN_CONFIG=exports.DEVICE_FINGERPRINT_STORAGE_KEY=exports.ANONYMOUS_TIER_ENABLED=void 0;/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.LICENSE_VERDICT_CACHE_DURATION=exports.LICENSE_TRANSIENT_RETRY_DELAYS=exports.LICENSE_STORAGE_KEY=exports.LICENSE_REVALIDATION_INTERVAL=exports.LICENSE_RATE_LIMIT_DEFAULT_WAIT=exports.LICENSE_QUOTA_COOLDOWN=exports.LICENSE_QUIET_VALIDATION_TTL=exports.LICENSE_LAUNCH_VALIDATION_TTL=exports.LICENSE_HOLD_STORAGE_KEY=exports.LICENSE_FLEET_MACHINE_THRESHOLD=exports.LICENSE_CACHE_DURATION=exports.KEYGEN_POLICIES=exports.KEYGEN_CONFIG=exports.FREE_TOKEN_PUBLIC_KEY=exports.DEVICE_FINGERPRINT_STORAGE_KEY=void 0;/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -14,4 +14,4 @@
14
14
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
15
15
  * including a free one (`npx buoy login`). Buy a key at
16
16
  * https://buoy.gg or use it free on Saturday and Sunday.
17
- */const KEYGEN_CONFIG=exports.KEYGEN_CONFIG={accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",productToken:"prod-4467c14b75b715e91884945cd3e69705846ccbce7dd5e380236a1ab3bc03139fv3",apiUrl:"https://api.keygen.sh/v1/accounts"};const KEYGEN_POLICIES=exports.KEYGEN_POLICIES={free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"};const LICENSE_CACHE_DURATION=exports.LICENSE_CACHE_DURATION=30*24*60*60*1e3;const LICENSE_REVALIDATION_INTERVAL=exports.LICENSE_REVALIDATION_INTERVAL=24*60*60*1e3;const LICENSE_STORAGE_KEY=exports.LICENSE_STORAGE_KEY="buoy-gg-license";const DEVICE_FINGERPRINT_STORAGE_KEY=exports.DEVICE_FINGERPRINT_STORAGE_KEY="buoy-gg-device-fingerprint";const LICENSE_LAUNCH_VALIDATION_TTL=exports.LICENSE_LAUNCH_VALIDATION_TTL=60*60*1e3;const LICENSE_TRANSIENT_RETRY_DELAYS=exports.LICENSE_TRANSIENT_RETRY_DELAYS=[5*1e3,20*1e3,60*1e3,5*60*1e3,15*60*1e3];const ANONYMOUS_TIER_ENABLED=exports.ANONYMOUS_TIER_ENABLED=true;
17
+ */const KEYGEN_CONFIG=exports.KEYGEN_CONFIG={accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",productToken:"prod-4467c14b75b715e91884945cd3e69705846ccbce7dd5e380236a1ab3bc03139fv3",apiUrl:"https://api.keygen.sh/v1/accounts"};const FREE_TOKEN_PUBLIC_KEY=exports.FREE_TOKEN_PUBLIC_KEY="3b546fc717a62683f3236c70167899a271bee3ffc04df6ec1eea60a394a2f1e9";const KEYGEN_POLICIES=exports.KEYGEN_POLICIES={free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"};const LICENSE_CACHE_DURATION=exports.LICENSE_CACHE_DURATION=30*24*60*60*1e3;const LICENSE_REVALIDATION_INTERVAL=exports.LICENSE_REVALIDATION_INTERVAL=24*60*60*1e3;const LICENSE_STORAGE_KEY=exports.LICENSE_STORAGE_KEY="buoy-gg-license";const DEVICE_FINGERPRINT_STORAGE_KEY=exports.DEVICE_FINGERPRINT_STORAGE_KEY="buoy-gg-device-fingerprint";const LICENSE_LAUNCH_VALIDATION_TTL=exports.LICENSE_LAUNCH_VALIDATION_TTL=60*60*1e3;const LICENSE_TRANSIENT_RETRY_DELAYS=exports.LICENSE_TRANSIENT_RETRY_DELAYS=[5*1e3,20*1e3,60*1e3,5*60*1e3,15*60*1e3];const LICENSE_RATE_LIMIT_DEFAULT_WAIT=exports.LICENSE_RATE_LIMIT_DEFAULT_WAIT=60*1e3;const LICENSE_QUOTA_COOLDOWN=exports.LICENSE_QUOTA_COOLDOWN=60*60*1e3;const LICENSE_VERDICT_CACHE_DURATION=exports.LICENSE_VERDICT_CACHE_DURATION=24*60*60*1e3;const LICENSE_FLEET_MACHINE_THRESHOLD=exports.LICENSE_FLEET_MACHINE_THRESHOLD=50;const LICENSE_QUIET_VALIDATION_TTL=exports.LICENSE_QUIET_VALIDATION_TTL=LICENSE_CACHE_DURATION;const LICENSE_HOLD_STORAGE_KEY=exports.LICENSE_HOLD_STORAGE_KEY="buoy-gg-license-hold";
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.generateUUID=generateUUID;exports.getDefaultDeviceName=getDefaultDeviceName;exports.getDeviceMetadata=getDeviceMetadata;exports.isSimulator=isSimulator;var _reactNative=require("react-native");function generateUUID(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;const r=e==="x"?t:t&3|8;return r.toString(16)})}function isSimulator(){if(_reactNative.Platform.OS==="ios"){const e=_reactNative.Platform.constants;if(e?.interfaceIdiom==="simulator"){return true}if("isTesting"in _reactNative.Platform&&_reactNative.Platform.isTesting){return true}return false}if(_reactNative.Platform.OS==="android"){const e=_reactNative.Platform.constants;const t=String(e?.Brand||"").toLowerCase();const r=String(e?.Model||"").toLowerCase();const n=String(e?.Fingerprint||"").toLowerCase();const a=t.includes("generic")||r.includes("sdk")||r.includes("emulator")||r.includes("android sdk")||n.includes("generic");return a}return false}function getDeviceMetadata(){const e={platform:_reactNative.Platform.OS,osVersion:String(_reactNative.Platform.Version),isSimulator:String(isSimulator())};if(_reactNative.Platform.OS==="android"){const t=_reactNative.Platform.constants;if(t?.Brand)e.brand=String(t.Brand);if(t?.Model)e.model=String(t.Model);if(t?.Manufacturer)e.manufacturer=String(t.Manufacturer)}if(_reactNative.Platform.OS==="ios"){const t=_reactNative.Platform.constants;if(t?.systemName)e.systemName=String(t.systemName);if(t?.interfaceIdiom)e.interfaceIdiom=String(t.interfaceIdiom)}return e}function getDefaultDeviceName(){const e=_reactNative.Platform.OS==="ios"?"iOS":_reactNative.Platform.OS==="android"?"Android":_reactNative.Platform.OS;const t=isSimulator()?" Simulator":"";return`My ${e} Device${t}`}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.generateUUID=generateUUID;exports.getDefaultDeviceName=getDefaultDeviceName;exports.getDeviceMetadata=getDeviceMetadata;exports.isDevBundle=isDevBundle;exports.isSimulator=isSimulator;var _reactNative=require("react-native");function generateUUID(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=Math.random()*16|0;const r=e==="x"?t:t&3|8;return r.toString(16)})}function isDevBundle(){try{const e=_reactNative.NativeModules?.SourceCode;const t=e?.scriptURL??e?.getConstants?.()?.scriptURL;if(typeof t==="string"&&t.length>0)return/^https?:\/\//i.test(t)}catch{}return typeof __DEV__!=="undefined"&&__DEV__}function isSimulator(){if(_reactNative.Platform.OS==="ios"){const e=_reactNative.Platform.constants;if(e?.interfaceIdiom==="simulator"){return true}if("isTesting"in _reactNative.Platform&&_reactNative.Platform.isTesting){return true}return false}if(_reactNative.Platform.OS==="android"){const e=_reactNative.Platform.constants;const t=String(e?.Brand||"").toLowerCase();const r=String(e?.Model||"").toLowerCase();const n=String(e?.Fingerprint||"").toLowerCase();const o=t.includes("generic")||r.includes("sdk")||r.includes("emulator")||r.includes("android sdk")||n.includes("generic");return o}return false}function getDeviceMetadata(){const e={platform:_reactNative.Platform.OS,osVersion:String(_reactNative.Platform.Version),isSimulator:String(isSimulator())};if(_reactNative.Platform.OS==="android"){const t=_reactNative.Platform.constants;if(t?.Brand)e.brand=String(t.Brand);if(t?.Model)e.model=String(t.Model);if(t?.Manufacturer)e.manufacturer=String(t.Manufacturer)}if(_reactNative.Platform.OS==="ios"){const t=_reactNative.Platform.constants;if(t?.systemName)e.systemName=String(t.systemName);if(t?.interfaceIdiom)e.interfaceIdiom=String(t.interfaceIdiom)}return e}function getDefaultDeviceName(){const e=_reactNative.Platform.OS==="ios"?"iOS":_reactNative.Platform.OS==="android"?"Android":_reactNative.Platform.OS;const t=isSimulator()?" Simulator":"";return`My ${e} Device${t}`}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.generateUUID=generateUUID;exports.getDefaultDeviceName=getDefaultDeviceName;exports.getDeviceMetadata=getDeviceMetadata;exports.isSimulator=isSimulator;function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const n=Math.random()*16|0;const r=e==="x"?n:n&3|8;return r.toString(16)})}function isSimulator(){return false}function detectPlatform(){if(typeof navigator==="undefined"){return"unknown"}const e=navigator.userAgent.toLowerCase();const n=navigator.platform?.toLowerCase()||"";if(e.includes("electron")){if(n.includes("mac")||e.includes("mac")){return"electron-macos"}if(n.includes("win")||e.includes("win")){return"electron-windows"}if(n.includes("linux")||e.includes("linux")){return"electron-linux"}return"electron"}if(n.includes("mac")||e.includes("mac")){return"macos"}if(n.includes("win")||e.includes("win")){return"windows"}if(n.includes("linux")||e.includes("linux")){return"linux"}if(/iphone|ipad|ipod/.test(e)){return"ios-web"}if(e.includes("android")){return"android-web"}return"web"}function getOSVersion(){if(typeof navigator==="undefined"){return"unknown"}const e=navigator.userAgent;const n=e.match(/Mac OS X ([\d_.]+)/);if(n){return n[1].replace(/_/g,".")}const r=e.match(/Windows NT ([\d.]+)/);if(r){const t={"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"};return t[r[1]]||r[1]}if(e.includes("Linux")){return"Linux"}return"unknown"}function getBrowserInfo(){if(typeof navigator==="undefined"){return{name:"unknown",version:"unknown"}}const e=navigator.userAgent;const n=e.match(/Electron\/([\d.]+)/);if(n){return{name:"Electron",version:n[1]}}const r=e.match(/Chrome\/([\d.]+)/);if(r&&!e.includes("Edg")){return{name:"Chrome",version:r[1]}}const t=e.match(/Edg\/([\d.]+)/);if(t){return{name:"Edge",version:t[1]}}const o=e.match(/Firefox\/([\d.]+)/);if(o){return{name:"Firefox",version:o[1]}}const i=e.match(/Version\/([\d.]+).*Safari/);if(i){return{name:"Safari",version:i[1]}}return{name:"unknown",version:"unknown"}}function getDeviceMetadata(){const e={platform:detectPlatform(),osVersion:getOSVersion(),isSimulator:"false"};const n=getBrowserInfo();e.browser=n.name;e.browserVersion=n.version;if(typeof window!=="undefined"&&window.screen){e.screenResolution=`${window.screen.width}x${window.screen.height}`}if(typeof navigator!=="undefined"&&navigator.language){e.language=navigator.language}try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return e}function getDefaultDeviceName(){const e=detectPlatform();const n=getBrowserInfo();if(e.startsWith("electron")){const r=e.replace("electron-","").replace("electron","Desktop");return`${r.charAt(0).toUpperCase()+r.slice(1)} App`}if(n.name!=="unknown"){return`${n.name} Browser`}return"Web Browser"}
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.generateUUID=generateUUID;exports.getDefaultDeviceName=getDefaultDeviceName;exports.getDeviceMetadata=getDeviceMetadata;exports.isDevBundle=isDevBundle;exports.isSimulator=isSimulator;function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const n=Math.random()*16|0;const r=e==="x"?n:n&3|8;return r.toString(16)})}function isDevBundle(){if(typeof __DEV__!=="undefined")return __DEV__;try{if(typeof navigator!=="undefined"&&/electron/i.test(navigator.userAgent))return true}catch{}return typeof process!=="undefined"&&process.env?.NODE_ENV!=="production"}function isSimulator(){return false}function detectPlatform(){if(typeof navigator==="undefined"){return"unknown"}const e=navigator.userAgent.toLowerCase();const n=navigator.platform?.toLowerCase()||"";if(e.includes("electron")){if(n.includes("mac")||e.includes("mac")){return"electron-macos"}if(n.includes("win")||e.includes("win")){return"electron-windows"}if(n.includes("linux")||e.includes("linux")){return"electron-linux"}return"electron"}if(n.includes("mac")||e.includes("mac")){return"macos"}if(n.includes("win")||e.includes("win")){return"windows"}if(n.includes("linux")||e.includes("linux")){return"linux"}if(/iphone|ipad|ipod/.test(e)){return"ios-web"}if(e.includes("android")){return"android-web"}return"web"}function getOSVersion(){if(typeof navigator==="undefined"){return"unknown"}const e=navigator.userAgent;const n=e.match(/Mac OS X ([\d_.]+)/);if(n){return n[1].replace(/_/g,".")}const r=e.match(/Windows NT ([\d.]+)/);if(r){const t={"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"};return t[r[1]]||r[1]}if(e.includes("Linux")){return"Linux"}return"unknown"}function getBrowserInfo(){if(typeof navigator==="undefined"){return{name:"unknown",version:"unknown"}}const e=navigator.userAgent;const n=e.match(/Electron\/([\d.]+)/);if(n){return{name:"Electron",version:n[1]}}const r=e.match(/Chrome\/([\d.]+)/);if(r&&!e.includes("Edg")){return{name:"Chrome",version:r[1]}}const t=e.match(/Edg\/([\d.]+)/);if(t){return{name:"Edge",version:t[1]}}const o=e.match(/Firefox\/([\d.]+)/);if(o){return{name:"Firefox",version:o[1]}}const i=e.match(/Version\/([\d.]+).*Safari/);if(i){return{name:"Safari",version:i[1]}}return{name:"unknown",version:"unknown"}}function getDeviceMetadata(){const e={platform:detectPlatform(),osVersion:getOSVersion(),isSimulator:"false"};const n=getBrowserInfo();e.browser=n.name;e.browserVersion=n.version;if(typeof window!=="undefined"&&window.screen){e.screenResolution=`${window.screen.width}x${window.screen.height}`}if(typeof navigator!=="undefined"&&navigator.language){e.language=navigator.language}try{e.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return e}function getDefaultDeviceName(){const e=detectPlatform();const n=getBrowserInfo();if(e.startsWith("electron")){const r=e.replace("electron-","").replace("electron","Desktop");return`${r.charAt(0).toUpperCase()+r.slice(1)} App`}if(n.name!=="unknown"){return`${n.name} Browser`}return"Web Browser"}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"generateUUID",{enumerable:true,get:function(){return _deviceInfo.generateUUID}});Object.defineProperty(exports,"getDefaultDeviceName",{enumerable:true,get:function(){return _deviceInfo.getDefaultDeviceName}});Object.defineProperty(exports,"getDeviceMetadata",{enumerable:true,get:function(){return _deviceInfo.getDeviceMetadata}});Object.defineProperty(exports,"isSimulator",{enumerable:true,get:function(){return _deviceInfo.isSimulator}});var _deviceInfo=require("./device-info");
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"generateUUID",{enumerable:true,get:function(){return _deviceInfo.generateUUID}});Object.defineProperty(exports,"getDefaultDeviceName",{enumerable:true,get:function(){return _deviceInfo.getDefaultDeviceName}});Object.defineProperty(exports,"getDeviceMetadata",{enumerable:true,get:function(){return _deviceInfo.getDeviceMetadata}});Object.defineProperty(exports,"isDevBundle",{enumerable:true,get:function(){return _deviceInfo.isDevBundle}});Object.defineProperty(exports,"isSimulator",{enumerable:true,get:function(){return _deviceInfo.isSimulator}});var _deviceInfo=require("./device-info");
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"generateUUID",{enumerable:true,get:function(){return _deviceInfoWeb.generateUUID}});Object.defineProperty(exports,"getDefaultDeviceName",{enumerable:true,get:function(){return _deviceInfoWeb.getDefaultDeviceName}});Object.defineProperty(exports,"getDeviceMetadata",{enumerable:true,get:function(){return _deviceInfoWeb.getDeviceMetadata}});Object.defineProperty(exports,"isSimulator",{enumerable:true,get:function(){return _deviceInfoWeb.isSimulator}});var _deviceInfoWeb=require("./device-info.web.js");
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"generateUUID",{enumerable:true,get:function(){return _deviceInfoWeb.generateUUID}});Object.defineProperty(exports,"getDefaultDeviceName",{enumerable:true,get:function(){return _deviceInfoWeb.getDefaultDeviceName}});Object.defineProperty(exports,"getDeviceMetadata",{enumerable:true,get:function(){return _deviceInfoWeb.getDeviceMetadata}});Object.defineProperty(exports,"isDevBundle",{enumerable:true,get:function(){return _deviceInfoWeb.isDevBundle}});Object.defineProperty(exports,"isSimulator",{enumerable:true,get:function(){return _deviceInfoWeb.isSimulator}});var _deviceInfoWeb=require("./device-info.web.js");
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.subscribeForeground=subscribeForeground;var _reactNative=require("react-native");function subscribeForeground(e){const r=_reactNative.AppState?.addEventListener("change",t=>{if(t==="active")e()});return()=>r?.remove()}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.subscribeForeground=subscribeForeground;function subscribeForeground(e){if(typeof window==="undefined"||typeof window.addEventListener!=="function")return()=>{};const n=()=>{if(!document.hidden)e()};window.addEventListener("focus",e);document.addEventListener("visibilitychange",n);return()=>{window.removeEventListener("focus",e);document.removeEventListener("visibilitychange",n)}}
@@ -0,0 +1,6 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.FREE_TOKEN_PREFIX=void 0;exports.__setFreeTokenPublicKeyForTests=__setFreeTokenPublicKeyForTests;exports.accountHashFor=accountHashFor;exports.isBuoyToken=isBuoyToken;exports.mintFreeToken=mintFreeToken;exports.publicKeyFor=publicKeyFor;exports.verifyFreeToken=verifyFreeToken;var _tweetnacl=_interopRequireDefault(require("tweetnacl"));var _config=require("./config.js");function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}/*!
2
+ * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
+ *
4
+ * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
5
+ * (https://buoy.gg/terms), not an OSS license.
6
+ */const FREE_TOKEN_PREFIX=exports.FREE_TOKEN_PREFIX="BUOY1";const FREE_TOKEN_VERSION=1;const FREE_TOKEN_TIER_FREE=1;const FREE_TOKEN_DOMAIN="buoy-free-token-v1:";const PAYLOAD_LENGTH=22;const SIGNATURE_LENGTH=64;const TOKEN_PATTERN=/^BUOY1-([A-Z2-7]+)-([A-Z2-7]+)$/;function isBuoyToken(t){return TOKEN_PATTERN.test(t.trim().toUpperCase())}const B32="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function base32Encode(t){let r="";let e=0;let n=0;for(const o of t){n=n<<8|o;e+=8;while(e>=5){r+=B32[n>>>e-5&31];e-=5}}if(e>0)r+=B32[n<<5-e&31];return r}function base32Decode(t){const r=[];let e=0;let n=0;for(const o of t){const s=B32.indexOf(o);if(s===-1)return null;n=n<<5|s;e+=5;if(e>=8){r.push(n>>>e-8&255);e-=8}}return new Uint8Array(r)}function hexToBytes(t){const r=t.trim().toLowerCase();const e=new Uint8Array(r.length/2);for(let n=0;n<e.length;n+=1)e[n]=parseInt(r.slice(n*2,n*2+2),16);return e}function bytesToHex(t){let r="";for(const e of t)r+=e.toString(16).padStart(2,"0");return r}function utf8(t){if(typeof TextEncoder!=="undefined")return new TextEncoder().encode(t);const r=new Uint8Array(t.length);for(let e=0;e<t.length;e+=1)r[e]=t.charCodeAt(e)&255;return r}function concat(t,r){const e=new Uint8Array(t.length+r.length);e.set(t,0);e.set(r,t.length);return e}function signedMessage(t){return concat(utf8(FREE_TOKEN_DOMAIN),t)}function accountHashFor(t){return _tweetnacl.default.hash(utf8(t)).slice(0,16)}function encodePayload(t,r){const e=new Uint8Array(PAYLOAD_LENGTH);e[0]=FREE_TOKEN_VERSION;e[1]=FREE_TOKEN_TIER_FREE;const n=Math.max(0,Math.min(4294967295,Math.floor(t)));e[2]=n>>>24&255;e[3]=n>>>16&255;e[4]=n>>>8&255;e[5]=n&255;e.set(r.slice(0,16),6);return e}function mintFreeToken(t,r,e){const n=encodePayload(r/1e3,accountHashFor(t));const{secretKey:o}=_tweetnacl.default.sign.keyPair.fromSeed(hexToBytes(e));const s=_tweetnacl.default.sign.detached(signedMessage(n),o);return`${FREE_TOKEN_PREFIX}-${base32Encode(n)}-${base32Encode(s)}`}function publicKeyFor(t){return bytesToHex(_tweetnacl.default.sign.keyPair.fromSeed(hexToBytes(t)).publicKey)}let activePublicKey=_config.FREE_TOKEN_PUBLIC_KEY;function __setFreeTokenPublicKeyForTests(t){activePublicKey=t??_config.FREE_TOKEN_PUBLIC_KEY}function verifyFreeToken(t,r=activePublicKey){const e=TOKEN_PATTERN.exec(t.trim().toUpperCase());if(!e)return null;const n=base32Decode(e[1]);const o=base32Decode(e[2]);if(!n||!o)return null;if(n.length!==PAYLOAD_LENGTH||o.length!==SIGNATURE_LENGTH)return null;if(n[0]!==FREE_TOKEN_VERSION||n[1]!==FREE_TOKEN_TIER_FREE)return null;try{if(!_tweetnacl.default.sign.detached.verify(signedMessage(n),o,hexToBytes(r)))return null}catch{return null}const s=(n[2]<<24>>>0)+(n[3]<<16)+(n[4]<<8)+n[5];return{tier:"free",issuedAt:s*1e3,accountHash:bytesToHex(n.slice(6,22))}}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"KEYGEN_CONFIG",{enumerable:true,get:function(){return _config.KEYGEN_CONFIG}});Object.defineProperty(exports,"LICENSE_CACHE_DURATION",{enumerable:true,get:function(){return _config.LICENSE_CACHE_DURATION}});Object.defineProperty(exports,"LICENSE_LAUNCH_VALIDATION_TTL",{enumerable:true,get:function(){return _config.LICENSE_LAUNCH_VALIDATION_TTL}});Object.defineProperty(exports,"LICENSE_REVALIDATION_INTERVAL",{enumerable:true,get:function(){return _config.LICENSE_REVALIDATION_INTERVAL}});Object.defineProperty(exports,"LICENSE_TRANSIENT_RETRY_DELAYS",{enumerable:true,get:function(){return _config.LICENSE_TRANSIENT_RETRY_DELAYS}});Object.defineProperty(exports,"LicenseTransportError",{enumerable:true,get:function(){return _api.LicenseTransportError}});Object.defineProperty(exports,"__setFreeTokenPublicKeyForTests",{enumerable:true,get:function(){return _freeToken.__setFreeTokenPublicKeyForTests}});Object.defineProperty(exports,"accountHashFor",{enumerable:true,get:function(){return _freeToken.accountHashFor}});Object.defineProperty(exports,"isAcceptedValidation",{enumerable:true,get:function(){return _api.isAcceptedValidation}});Object.defineProperty(exports,"isBuoyToken",{enumerable:true,get:function(){return _freeToken.isBuoyToken}});Object.defineProperty(exports,"isRecognizedAccount",{enumerable:true,get:function(){return _tier.isRecognizedAccount}});Object.defineProperty(exports,"isTransientLicenseError",{enumerable:true,get:function(){return _api.isTransientLicenseError}});Object.defineProperty(exports,"mintFreeToken",{enumerable:true,get:function(){return _freeToken.mintFreeToken}});Object.defineProperty(exports,"publicKeyFor",{enumerable:true,get:function(){return _freeToken.publicKeyFor}});Object.defineProperty(exports,"resolveAccountAccess",{enumerable:true,get:function(){return _accountAccess.resolveAccountAccess}});Object.defineProperty(exports,"resolveTier",{enumerable:true,get:function(){return _tier.resolveTier}});Object.defineProperty(exports,"signCache",{enumerable:true,get:function(){return _cacheSignature.signCache}});Object.defineProperty(exports,"validateLicense",{enumerable:true,get:function(){return _api.validateLicense}});Object.defineProperty(exports,"verifyCacheSignature",{enumerable:true,get:function(){return _cacheSignature.verifyCacheSignature}});Object.defineProperty(exports,"verifyFreeToken",{enumerable:true,get:function(){return _freeToken.verifyFreeToken}});var _api=require("./api.js");var _tier=require("./tier.js");var _freeToken=require("./freeToken.js");var _accountAccess=require("./accountAccess.js");var _cacheSignature=require("./cacheSignature.js");var _config=require("./config.js");
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useFeatureAccess=useFeatureAccess;exports.useIsPro=useIsPro;exports.useLicense=useLicense;exports.useProAccess=useProAccess;exports.useTier=useTier;var _react=require("react");var _LicenseManager=require("./LicenseManager.js");var _weekendPro=require("./weekendPro.js");/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.useAccountAccess=useAccountAccess;exports.useFeatureAccess=useFeatureAccess;exports.useIsPro=useIsPro;exports.useLicense=useLicense;exports.useProAccess=useProAccess;exports.useTier=useTier;var _react=require("react");var _LicenseManager=require("./LicenseManager.js");var _weekendPro=require("./weekendPro.js");/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -14,4 +14,4 @@
14
14
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
15
15
  * including a free one (`npx buoy login`). Buy a key at
16
16
  * https://buoy.gg or use it free on Saturday and Sunday.
17
- */function useLicense(){const[t,e]=(0,_react.useState)(_LicenseManager.LicenseManager.getState());(0,_react.useEffect)(()=>{const n=_LicenseManager.LicenseManager.subscribe(i=>{e(_LicenseManager.LicenseManager.getState())});_LicenseManager.LicenseManager.initialize().then(()=>{e(_LicenseManager.LicenseManager.getState())});return n},[]);const r=(0,_react.useCallback)(async n=>{const i=await _LicenseManager.LicenseManager.setLicenseKey(n,{force:true});e(_LicenseManager.LicenseManager.getState());return i},[]);const s=(0,_react.useCallback)(async()=>{await _LicenseManager.LicenseManager.clearLicense();e(_LicenseManager.LicenseManager.getState())},[]);return{...t,setLicenseKey:r,clearLicense:s}}function useTier(){const{tier:t,isInitialized:e}=useLicense();return e?t:"anonymous"}function useFeatureAccess(t){const{isPro:e,isInitialized:r,isValidating:s}=useLicense();const n=e;const i=!r||s;return{hasAccess:n,isPro:e,isLoading:i}}function useIsPro(){const{isPro:t,isInitialized:e,tier:r}=useLicense();const s=(0,_weekendPro.weekendPassAppliesTo)(r,(0,_weekendPro.useWeekendFreePro)());return e&&t||s}function useProAccess(){const{isPro:t,isInitialized:e,tier:r}=useLicense();const s=e&&t;const n=(0,_weekendPro.weekendPassAppliesTo)(r,(0,_weekendPro.useWeekendFreePro)())&&!s;const i=s?"licensed":n?"weekend":null;return{isPro:s||n,isLicensed:s,isWeekendFree:n,reason:i}}
17
+ */function useLicense(){const[n,e]=(0,_react.useState)(_LicenseManager.LicenseManager.getState());(0,_react.useEffect)(()=>{const t=_LicenseManager.LicenseManager.subscribe(c=>{e(_LicenseManager.LicenseManager.getState())});_LicenseManager.LicenseManager.initialize().then(()=>{e(_LicenseManager.LicenseManager.getState())});return t},[]);const r=(0,_react.useCallback)(async t=>{const c=await _LicenseManager.LicenseManager.setLicenseKey(t,{force:true});e(_LicenseManager.LicenseManager.getState());return c},[]);const s=(0,_react.useCallback)(async()=>{await _LicenseManager.LicenseManager.clearLicense();e(_LicenseManager.LicenseManager.getState())},[]);return{...n,setLicenseKey:r,clearLicense:s}}function useAccountAccess(){return useLicense().access}function useTier(){const{tier:n,isInitialized:e}=useLicense();return e?n:"free"}function useFeatureAccess(n){const{isPro:e,isInitialized:r,isValidating:s}=useLicense();const t=e;const c=!r||s;return{hasAccess:t,isPro:e,isLoading:c}}function useIsPro(){const{isPro:n,isInitialized:e,access:r}=useLicense();const s=(0,_weekendPro.weekendPassAppliesTo)(r.status==="admitted",(0,_weekendPro.useWeekendFreePro)());return e&&n||s}function useProAccess(){const{isPro:n,isInitialized:e,access:r}=useLicense();const s=e&&n;const t=(0,_weekendPro.weekendPassAppliesTo)(r.status==="admitted",(0,_weekendPro.useWeekendFreePro)())&&!s;const c=s?"licensed":t?"weekend":null;return{isPro:s||t,isLicensed:s,isWeekendFree:t,reason:c}}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"ANONYMOUS_TIER_ENABLED",{enumerable:true,get:function(){return _config.ANONYMOUS_TIER_ENABLED}});Object.defineProperty(exports,"DeviceRegistrationModal",{enumerable:true,get:function(){return _DeviceRegistrationModal.DeviceRegistrationModal}});Object.defineProperty(exports,"LicenseManager",{enumerable:true,get:function(){return _LicenseManager.LicenseManager}});Object.defineProperty(exports,"LicenseTransportError",{enumerable:true,get:function(){return _api.LicenseTransportError}});exports.hasEntitlement=hasEntitlement;exports.isPro=isPro;Object.defineProperty(exports,"isTransientLicenseError",{enumerable:true,get:function(){return _api.isTransientLicenseError}});Object.defineProperty(exports,"isWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.isWeekendFreePro}});exports.setLicenseKey=setLicenseKey;Object.defineProperty(exports,"useFeatureAccess",{enumerable:true,get:function(){return _hooks.useFeatureAccess}});Object.defineProperty(exports,"useIsPro",{enumerable:true,get:function(){return _hooks.useIsPro}});Object.defineProperty(exports,"useLicense",{enumerable:true,get:function(){return _hooks.useLicense}});Object.defineProperty(exports,"useProAccess",{enumerable:true,get:function(){return _hooks.useProAccess}});Object.defineProperty(exports,"useTier",{enumerable:true,get:function(){return _hooks.useTier}});Object.defineProperty(exports,"useWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.useWeekendFreePro}});var _LicenseManager=require("./LicenseManager.js");var _DeviceRegistrationModal=require("./DeviceRegistrationModal.js");var _hooks=require("./hooks.js");var _config=require("./config.js");var _api=require("./api.js");var _weekendPro=require("./weekendPro.js");function _interopRequireWildcard(r,t){if("function"==typeof WeakMap)var u=new WeakMap,c=new WeakMap;return(_interopRequireWildcard=function(e,a){if(!a&&e&&e.__esModule)return e;var n,o,s={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return s;if(n=a?c:u){if(n.has(e))return n.get(e);n.set(e,s)}for(const i in e)"default"!==i&&{}.hasOwnProperty.call(e,i)&&((o=(n=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,i))&&(o.get||o.set)?n(s,i,o):s[i]=e[i]);return s})(r,t)}/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"DeviceRegistrationModal",{enumerable:true,get:function(){return _DeviceRegistrationModal.DeviceRegistrationModal}});Object.defineProperty(exports,"LicenseManager",{enumerable:true,get:function(){return _LicenseManager.LicenseManager}});Object.defineProperty(exports,"LicenseTransportError",{enumerable:true,get:function(){return _api.LicenseTransportError}});exports.hasEntitlement=hasEntitlement;Object.defineProperty(exports,"isBuoyToken",{enumerable:true,get:function(){return _freeToken.isBuoyToken}});exports.isPro=isPro;Object.defineProperty(exports,"isTransientLicenseError",{enumerable:true,get:function(){return _api.isTransientLicenseError}});Object.defineProperty(exports,"isWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.isWeekendFreePro}});Object.defineProperty(exports,"resolveAccountAccess",{enumerable:true,get:function(){return _accountAccess.resolveAccountAccess}});exports.setLicenseKey=setLicenseKey;Object.defineProperty(exports,"useAccountAccess",{enumerable:true,get:function(){return _hooks.useAccountAccess}});Object.defineProperty(exports,"useFeatureAccess",{enumerable:true,get:function(){return _hooks.useFeatureAccess}});Object.defineProperty(exports,"useIsPro",{enumerable:true,get:function(){return _hooks.useIsPro}});Object.defineProperty(exports,"useLicense",{enumerable:true,get:function(){return _hooks.useLicense}});Object.defineProperty(exports,"useProAccess",{enumerable:true,get:function(){return _hooks.useProAccess}});Object.defineProperty(exports,"useTier",{enumerable:true,get:function(){return _hooks.useTier}});Object.defineProperty(exports,"useWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.useWeekendFreePro}});var _LicenseManager=require("./LicenseManager.js");var _DeviceRegistrationModal=require("./DeviceRegistrationModal.js");var _hooks=require("./hooks.js");var _accountAccess=require("./accountAccess.js");var _api=require("./api.js");var _freeToken=require("./freeToken.js");var _weekendPro=require("./weekendPro.js");function _interopRequireWildcard(r,t){if("function"==typeof WeakMap)var u=new WeakMap,a=new WeakMap;return(_interopRequireWildcard=function(e,c){if(!c&&e&&e.__esModule)return e;var n,i,o={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return o;if(n=c?a:u){if(n.has(e))return n.get(e);n.set(e,o)}for(const s in e)"default"!==s&&{}.hasOwnProperty.call(e,s)&&((i=(n=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,s))&&(i.get||i.set)?n(o,s,i):o[s]=e[s]);return o})(r,t)}/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -15,4 +15,4 @@
15
15
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
16
16
  * including a free one (`npx buoy login`). Buy a key at
17
17
  * https://buoy.gg or use it free on Saturday and Sunday.
18
- */async function setLicenseKey(r){const{LicenseManager:t}=await Promise.resolve().then(()=>_interopRequireWildcard(require("./LicenseManager")));await t.initialize();return t.setLicenseKey(r)}function weekendPassActive(){const{isWeekendFreePro:r,weekendPassAppliesTo:t}=require("./weekendPro");const{LicenseManager:u}=require("./LicenseManager");return t(u.getTier(),r())}function isPro(){const{LicenseManager:r}=require("./LicenseManager");if(r.isPro())return true;return weekendPassActive()}function hasEntitlement(r){const{LicenseManager:t}=require("./LicenseManager");if(t.hasEntitlement(r))return true;return weekendPassActive()}
18
+ */async function setLicenseKey(r){const{LicenseManager:t}=await Promise.resolve().then(()=>_interopRequireWildcard(require("./LicenseManager")));await t.initialize();return t.setLicenseKey(r)}function weekendPassActive(){const{isWeekendFreePro:r,weekendPassAppliesTo:t}=require("./weekendPro");const{LicenseManager:u}=require("./LicenseManager");return t(u.hasAccountAccess(),r())}function isPro(){const{LicenseManager:r}=require("./LicenseManager");if(r.isPro())return true;return weekendPassActive()}function hasEntitlement(r){const{LicenseManager:t}=require("./LicenseManager");if(t.hasEntitlement(r))return true;return weekendPassActive()}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"ANONYMOUS_TIER_ENABLED",{enumerable:true,get:function(){return _config.ANONYMOUS_TIER_ENABLED}});Object.defineProperty(exports,"LicenseManager",{enumerable:true,get:function(){return _LicenseManager.LicenseManager}});Object.defineProperty(exports,"LicenseTransportError",{enumerable:true,get:function(){return _api.LicenseTransportError}});exports.hasEntitlement=hasEntitlement;exports.isPro=isPro;Object.defineProperty(exports,"isTransientLicenseError",{enumerable:true,get:function(){return _api.isTransientLicenseError}});Object.defineProperty(exports,"isWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.isWeekendFreePro}});exports.setLicenseKey=setLicenseKey;Object.defineProperty(exports,"useFeatureAccess",{enumerable:true,get:function(){return _hooks.useFeatureAccess}});Object.defineProperty(exports,"useIsPro",{enumerable:true,get:function(){return _hooks.useIsPro}});Object.defineProperty(exports,"useLicense",{enumerable:true,get:function(){return _hooks.useLicense}});Object.defineProperty(exports,"useProAccess",{enumerable:true,get:function(){return _hooks.useProAccess}});Object.defineProperty(exports,"useTier",{enumerable:true,get:function(){return _hooks.useTier}});Object.defineProperty(exports,"useWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.useWeekendFreePro}});var _LicenseManager=require("./LicenseManager.js");var _hooks=require("./hooks.js");var _config=require("./config.js");var _api=require("./api.js");var _weekendPro=require("./weekendPro.js");function _interopRequireWildcard(r,n){if("function"==typeof WeakMap)var o=new WeakMap,a=new WeakMap;return(_interopRequireWildcard=function(e,c){if(!c&&e&&e.__esModule)return e;var t,u,s={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return s;if(t=c?a:o){if(t.has(e))return t.get(e);t.set(e,s)}for(const i in e)"default"!==i&&{}.hasOwnProperty.call(e,i)&&((u=(t=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,i))&&(u.get||u.set)?t(s,i,u):s[i]=e[i]);return s})(r,n)}/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"LicenseManager",{enumerable:true,get:function(){return _LicenseManager.LicenseManager}});Object.defineProperty(exports,"LicenseTransportError",{enumerable:true,get:function(){return _api.LicenseTransportError}});exports.hasEntitlement=hasEntitlement;Object.defineProperty(exports,"isBuoyToken",{enumerable:true,get:function(){return _freeToken.isBuoyToken}});exports.isPro=isPro;Object.defineProperty(exports,"isTransientLicenseError",{enumerable:true,get:function(){return _api.isTransientLicenseError}});Object.defineProperty(exports,"isWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.isWeekendFreePro}});Object.defineProperty(exports,"resolveAccountAccess",{enumerable:true,get:function(){return _accountAccess.resolveAccountAccess}});exports.setLicenseKey=setLicenseKey;Object.defineProperty(exports,"useAccountAccess",{enumerable:true,get:function(){return _hooks.useAccountAccess}});Object.defineProperty(exports,"useFeatureAccess",{enumerable:true,get:function(){return _hooks.useFeatureAccess}});Object.defineProperty(exports,"useIsPro",{enumerable:true,get:function(){return _hooks.useIsPro}});Object.defineProperty(exports,"useLicense",{enumerable:true,get:function(){return _hooks.useLicense}});Object.defineProperty(exports,"useProAccess",{enumerable:true,get:function(){return _hooks.useProAccess}});Object.defineProperty(exports,"useTier",{enumerable:true,get:function(){return _hooks.useTier}});Object.defineProperty(exports,"useWeekendFreePro",{enumerable:true,get:function(){return _weekendPro.useWeekendFreePro}});var _LicenseManager=require("./LicenseManager.js");var _weekendPro=require("./weekendPro.js");var _hooks=require("./hooks.js");var _accountAccess=require("./accountAccess.js");var _api=require("./api.js");var _freeToken=require("./freeToken.js");function _interopRequireWildcard(n,u){if("function"==typeof WeakMap)var c=new WeakMap,a=new WeakMap;return(_interopRequireWildcard=function(e,i){if(!i&&e&&e.__esModule)return e;var r,o,s={__proto__:null,default:e};if(null===e||"object"!=typeof e&&"function"!=typeof e)return s;if(r=i?a:c){if(r.has(e))return r.get(e);r.set(e,s)}for(const t in e)"default"!==t&&{}.hasOwnProperty.call(e,t)&&((o=(r=Object.defineProperty)&&Object.getOwnPropertyDescriptor(e,t))&&(o.get||o.set)?r(s,t,o):s[t]=e[t]);return s})(n,u)}/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -15,4 +15,4 @@
15
15
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
16
16
  * including a free one (`npx buoy login`). Buy a key at
17
17
  * https://buoy.gg or use it free on Saturday and Sunday.
18
- */async function setLicenseKey(r){const{LicenseManager:n}=await Promise.resolve().then(()=>_interopRequireWildcard(require("./LicenseManager")));await n.initialize();return n.setLicenseKey(r)}function weekendPassActive(){const{isWeekendFreePro:r,weekendPassAppliesTo:n}=require("./weekendPro");const{LicenseManager:o}=require("./LicenseManager");return n(o.getTier(),r())}function isPro(){const{LicenseManager:r}=require("./LicenseManager");if(r.isPro())return true;return weekendPassActive()}function hasEntitlement(r){const{LicenseManager:n}=require("./LicenseManager");if(n.hasEntitlement(r))return true;return weekendPassActive()}
18
+ */async function setLicenseKey(n){const{LicenseManager:u}=await Promise.resolve().then(()=>_interopRequireWildcard(require("./LicenseManager")));await u.initialize();return u.setLicenseKey(n)}function weekendPassActive(){return(0,_weekendPro.weekendPassAppliesTo)(_LicenseManager.LicenseManager.hasAccountAccess(),(0,_weekendPro.isWeekendFreePro)())}function isPro(){if(_LicenseManager.LicenseManager.isPro())return true;return weekendPassActive()}function hasEntitlement(n){if(_LicenseManager.LicenseManager.hasEntitlement(n))return true;return weekendPassActive()}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getLicenseStorage=getLicenseStorage;const LICENSE_STORAGE_DIR="buoy-license";let _FileSystem=null;let _licenseStorage=null;const _memoryStore=new Map;function loadFileSystem(){if(_FileSystem)return _FileSystem;try{const e=require("expo-file-system/legacy");_FileSystem=e?.default||e;if(_FileSystem?.documentDirectory){return _FileSystem}_FileSystem=null}catch{}try{const e=require("expo-file-system");_FileSystem=e?.default||e;if(_FileSystem?.documentDirectory){return _FileSystem}_FileSystem=null}catch{}return null}function getLicenseStorageDir(){const e=loadFileSystem();if(!e?.documentDirectory)return null;return`${e.documentDirectory}${LICENSE_STORAGE_DIR}/`}function getLicenseFilePath(e){const n=getLicenseStorageDir();if(!n)return null;return`${n}${encodeURIComponent(e)}.json`}function loadAsyncStorage(){try{const e=require("@react-native-async-storage/async-storage");const n=e?.default||e;if(typeof n?.getItem==="function"&&typeof n.setItem==="function"&&typeof n.removeItem==="function"){return n}}catch{}return null}function hasLocalStorage(){try{return typeof localStorage!=="undefined"&&!!localStorage}catch{return false}}async function getLicenseStorage(){if(_licenseStorage)return _licenseStorage;const e=loadFileSystem();let n=null;if(e?.documentDirectory){_licenseStorage={async getItem(t){const r=getLicenseFilePath(t);if(!r)return null;try{const c=await e.getInfoAsync(r);if(!c.exists)return null;return await e.readAsStringAsync(r)}catch{return null}},async setItem(t,r){const c=getLicenseStorageDir();const o=getLicenseFilePath(t);if(!c||!o)return;try{const a=await e.getInfoAsync(c);if(!a.exists){await e.makeDirectoryAsync(c,{intermediates:true})}await e.writeAsStringAsync(o,r)}catch(a){console.warn("[Buoy] License storage write failed:",a)}},async removeItem(t){const r=getLicenseFilePath(t);if(!r)return;try{await e.deleteAsync(r,{idempotent:true})}catch{}}}}else if(n=loadAsyncStorage()){const t=n;_licenseStorage={async getItem(r){try{return await t.getItem(r)}catch{return null}},async setItem(r,c){try{await t.setItem(r,c)}catch(o){console.warn("[Buoy] License storage write failed:",o)}},async removeItem(r){try{await t.removeItem(r)}catch{}}}}else if(hasLocalStorage()){_licenseStorage={async getItem(t){try{return localStorage.getItem(t)}catch{return null}},async setItem(t,r){try{localStorage.setItem(t,r)}catch{}},async removeItem(t){try{localStorage.removeItem(t)}catch{}}}}else{_licenseStorage={async getItem(t){return _memoryStore.get(t)??null},async setItem(t,r){_memoryStore.set(t,r)},async removeItem(t){_memoryStore.delete(t)}}}return _licenseStorage}
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.getLicenseStorage=getLicenseStorage;const memory=new Map;const storage={async getItem(e){try{return localStorage.getItem(e)??memory.get(e)??null}catch{return memory.get(e)??null}},async setItem(e,t){memory.set(e,t);try{localStorage.setItem(e,t)}catch{}},async removeItem(e){memory.delete(e);try{localStorage.removeItem(e)}catch{}}};async function getLicenseStorage(){return storage}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.resolveTier=resolveTier;exports.tierAfterFatalError=tierAfterFatalError;var _config=require("./config.js");/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.isRecognizedAccount=isRecognizedAccount;exports.resolveTier=resolveTier;exports.tierAfterFatalError=tierAfterFatalError;var _config=require("./config.js");/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -14,4 +14,4 @@
14
14
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
15
15
  * including a free one (`npx buoy login`). Buy a key at
16
16
  * https://buoy.gg or use it free on Saturday and Sunday.
17
- */function resolveTier(r){const e=r.relationships?.policy?.data?.id;if(e===_config.KEYGEN_POLICIES.free)return"free";if(e===_config.KEYGEN_POLICIES.solo||e===_config.KEYGEN_POLICIES.business){return"pro"}const t=r.attributes?.metadata?.plan;if(t==="free")return"free";return"pro"}function tierAfterFatalError(r){return r==="EXPIRED"?"free":"anonymous"}
17
+ */function resolveTier(r){const e=r.relationships?.policy?.data?.id;if(e===_config.KEYGEN_POLICIES.free)return"free";if(e===_config.KEYGEN_POLICIES.solo||e===_config.KEYGEN_POLICIES.business){return"pro"}const t=r.attributes?.metadata?.plan;if(t==="free")return"free";return"pro"}function tierAfterFatalError(r){return r==="EXPIRED"?"free":null}function isRecognizedAccount(r){if(!r)return false;const e=r.relationships?.product?.data?.id;if(e)return e===_config.KEYGEN_CONFIG.productId;const t=r.relationships?.policy?.data?.id;return Object.values(_config.KEYGEN_POLICIES).some(o=>o===t)}
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.isWeekendFreePro=isWeekendFreePro;exports.useWeekendFreePro=useWeekendFreePro;exports.weekendPassAppliesTo=weekendPassAppliesTo;var _config=require("./config.js");var _react=require("react");/*!
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.isWeekendFreePro=isWeekendFreePro;exports.useWeekendFreePro=useWeekendFreePro;exports.weekendPassAppliesTo=weekendPassAppliesTo;var _react=require("react");/*!
2
2
  * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
3
  *
4
4
  * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
@@ -15,4 +15,4 @@
15
15
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
16
16
  * including a free one (`npx buoy login`). Buy a key at
17
17
  * https://buoy.gg or use it free on Saturday and Sunday.
18
- */function isWeekendFreePro(r=new Date){const e=r.getDay();return e===0||e===6}function useWeekendFreePro(){const[r,e]=(0,_react.useState)(()=>isWeekendFreePro());(0,_react.useEffect)(()=>{const s=setInterval(()=>{const t=isWeekendFreePro();e(n=>n===t?n:t)},60*1e3);return()=>clearInterval(s)},[]);return r}function weekendPassAppliesTo(r,e){if(!e)return false;if(!_config.ANONYMOUS_TIER_ENABLED)return true;return r!=="anonymous"}
18
+ */function isWeekendFreePro(t=new Date){const e=t.getDay();return e===0||e===6}function useWeekendFreePro(){const[t,e]=(0,_react.useState)(()=>isWeekendFreePro());(0,_react.useEffect)(()=>{const s=setInterval(()=>{const r=isWeekendFreePro();e(n=>n===r?n:r)},60*1e3);return()=>clearInterval(s)},[]);return t}function weekendPassAppliesTo(t,e){return e&&t}
@@ -13,4 +13,4 @@
13
13
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
14
14
  * including a free one (`npx buoy login`). Buy a key at
15
15
  * https://buoy.gg or use it free on Saturday and Sunday.
16
- */const b="buoy-license";let l=null;let h=null;const m=new Map;function R(){if(l)return l;try{const s=require("expo-file-system/legacy");l=s?.default||s;if(l?.documentDirectory){return l}l=null}catch{}try{const s=require("expo-file-system");l=s?.default||s;if(l?.documentDirectory){return l}l=null}catch{}return null}function T(){const s=R();if(!s?.documentDirectory)return null;return`${s.documentDirectory}${b}/`}function p(s){const e=T();if(!e)return null;return`${e}${encodeURIComponent(s)}.json`}function B(){try{const s=require("@react-native-async-storage/async-storage");const e=s?.default||s;if(typeof e?.getItem==="function"&&typeof e.setItem==="function"&&typeof e.removeItem==="function"){return e}}catch{}return null}function k(){try{return typeof localStorage!=="undefined"&&!!localStorage}catch{return false}}async function u(){if(h)return h;const s=R();let e=null;if(s?.documentDirectory){h={async getItem(i){const t=p(i);if(!t)return null;try{const r=await s.getInfoAsync(t);if(!r.exists)return null;return await s.readAsStringAsync(t)}catch{return null}},async setItem(i,t){const r=T();const n=p(i);if(!r||!n)return;try{const a=await s.getInfoAsync(r);if(!a.exists){await s.makeDirectoryAsync(r,{intermediates:true})}await s.writeAsStringAsync(n,t)}catch(a){console.warn("[Buoy] License storage write failed:",a)}},async removeItem(i){const t=p(i);if(!t)return;try{await s.deleteAsync(t,{idempotent:true})}catch{}}}}else if(e=B()){const i=e;h={async getItem(t){try{return await i.getItem(t)}catch{return null}},async setItem(t,r){try{await i.setItem(t,r)}catch(n){console.warn("[Buoy] License storage write failed:",n)}},async removeItem(t){try{await i.removeItem(t)}catch{}}}}else if(k()){h={async getItem(i){try{return localStorage.getItem(i)}catch{return null}},async setItem(i,t){try{localStorage.setItem(i,t)}catch{}},async removeItem(i){try{localStorage.removeItem(i)}catch{}}}}else{h={async getItem(i){return m.get(i)??null},async setItem(i,t){m.set(i,t)},async removeItem(i){m.delete(i)}}}return h}import{LICENSE_STORAGE_KEY as I,LICENSE_CACHE_DURATION as F,LICENSE_REVALIDATION_INTERVAL as G,LICENSE_LAUNCH_VALIDATION_TTL as z,LICENSE_TRANSIENT_RETRY_DELAYS as O,DEVICE_FINGERPRINT_STORAGE_KEY as _}from"./config.js";import{validateLicense as w,activateMachine as C,parseValidationResult as N,isFatalLicenseError as P,isTransientLicenseError as D}from"./api.js";import{generateUUID as Y,getDeviceMetadata as S,getDefaultDeviceName as x}from"./fingerprint";import{signCache as U,verifyCacheSignature as E}from"./cacheSignature.js";import{resolveTier as K,tierAfterFatalError as V}from"./tier.js";function A(s){if(s.tier)return s.tier;return s.isPro?"pro":"anonymous"}class q{state={isInitialized:false,isValidating:false,isPro:false,tier:"anonymous",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};listeners=new Set;revalidationTimer=null;cachedLicense=null;fingerprintPromise=null;initPromise=null;generation=0;retryTimer=null;retryAttempt=0;deviceRegistrationCallback=null;pendingRegistration=null;async initialize(){if(this.initPromise)return this.initPromise;if(this.state.isInitialized)return;this.initPromise=this._doInitialize();return this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;try{const e=await this.loadCachedLicense();if(e){const i=E(e);this.cachedLicense=e;this.state.licenseKey=e.licenseKey;this.applyTier(i&&this.isCacheValid(e)?A(e):"anonymous");this.state.expiresAt=e.expiresAt?new Date(e.expiresAt):null;if(e.licenseKey&&!(i&&this.isCacheValid(e)&&this.isCacheFresh(e))){this.validateInBackground(e.licenseKey)}}this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer()}catch(e){console.warn("[React Buoy] License initialization failed:",e);this.state.isInitialized=true;this.emit({type:"initialized",isPro:false})}}async setLicenseKey(e,i){if(!e||e.trim().length===0){this.state.error="License key is required";this.state.errorKind="verdict";return false}const t=e.trim().toUpperCase();const r=this.cachedLicense;if(!i?.force&&r&&r.valid&&r.licenseKey===t&&r.fingerprint&&E(r)&&this.isCacheValid(r)&&this.isCacheFresh(r)){this.applyTier(A(r));this.state.licenseKey=t;this.state.isValidating=false;this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.emit({type:"validated",isPro:this.state.isPro});return true}this.generation+=1;this.cancelRetry();if(i?.force&&!i.isRetry)this.retryAttempt=0;const n=this.generation;this.state.licenseKey=t;this.state.isValidating=true;this.state.error=null;this.state.errorKind=null;this.emit({type:"validating",isPro:this.state.isPro});let a;try{a=await w(t)}catch(c){const o=c instanceof Error?c.message:"Validation failed";if(n!==this.generation)return false;if(D(c)){this.state.isValidating=false;if(this.cachedLicense&&this.cachedLicense.licenseKey===t&&E(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)){this.applyTier(A(this.cachedLicense));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=this.cachedLicense.expiresAt?new Date(this.cachedLicense.expiresAt):null;this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=o;this.state.errorKind="transport";this.scheduleRetry(t);this.emit({type:"error",isPro:this.state.isPro,error:o});return false}this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}try{if(n!==this.generation)return false;const c=N(a);if(P(c.code)){this.applyTier(V(c.code));this.state.isValidating=false;this.state.error=c.detail;this.state.errorKind="verdict";await this.clearCachedLicense();this.emit({type:"error",isPro:false,error:c.detail});return false}if(!a.data){this.state.isValidating=false;this.state.error=c.detail||"License not found";this.state.errorKind="verdict";await this.clearCachedLicense();this.emit({type:"error",isPro:false,error:this.state.error});return false}const o=K(a.data);this.applyTier(o);this.state.isValidating=false;this.state.expiresAt=a.data.attributes.expiry?new Date(a.data.attributes.expiry):null;const y=a.data.id;const v=Date.now();let d=this.cachedLicense?.fingerprint;let f=this.cachedLicense?.deviceName;let L=false;if(!d){d=await this.getOrCreateDeviceFingerprint();f=x();L=true}let g=false;if(L){if(this.deviceRegistrationCallback){this.pendingRegistration={licenseId:y,licenseKey:t,fingerprint:d};this.deviceRegistrationCallback({fingerprint:d,defaultName:f});g=true}else{this.registerDeviceAsync(y,t,d,f)}}const M={licenseKey:t,licenseId:y,valid:true,isPro:o==="pro",tier:o,expiresAt:a.data.attributes.expiry??null,cachedAt:v,lastValidatedAt:v,fingerprint:g?void 0:d,deviceName:g?void 0:f};this.cachedLicense=await this.persistCache(M);this.retryAttempt=0;this.emit({type:"validated",isPro:this.state.isPro});return true}catch(c){const o=c instanceof Error?c.message:"Validation failed";if(n!==this.generation)return false;this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}}scheduleRetry(e){this.cancelRetry();const i=O[this.retryAttempt];if(i===void 0)return;this.retryAttempt+=1;const t=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(t!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},i);if(__DEV__){global.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}}cancelRetry(){if(this.retryTimer){clearTimeout(this.retryTimer);this.retryTimer=null}}async clearLicense(){this.generation+=1;this.cancelRetry();this.retryAttempt=0;this.state.licenseKey=null;this.applyTier("anonymous");this.state.expiresAt=null;this.state.error=null;this.state.errorKind=null;this.cachedLicense=null;await this.clearCachedLicense();this.emit({type:"deactivated",isPro:false})}applyTier(e){this.state.tier=e;this.state.tierSource=e==="anonymous"?"none":"key";this.state.isPro=e==="pro"}getTier(){return this.state.tier}isPro(){return this.state.tier==="pro"}hasEntitlement(e){if(e==="PRO"){return this.state.isPro}return this.state.isPro}getState(){return{...this.state}}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){this.deviceRegistrationCallback=e;return()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}const{licenseId:i,licenseKey:t,fingerprint:r}=this.pendingRegistration;const n=e.trim()||x();const a=S();try{await C(i,t,r,n,a)}catch(c){const o=c instanceof Error?c.message:String(c);if(o==="FINGERPRINT_TAKEN"||o==="MACHINE_LIMIT_EXCEEDED"){}else{console.warn("[Buoy] Device registration failed:",o);throw c}}if(this.cachedLicense){this.cachedLicense.fingerprint=r;this.cachedLicense.deviceName=n;this.cachedLicense=await this.persistCache(this.cachedLicense)}this.pendingRegistration=null}emit(e){const i=[...this.listeners];i.forEach(t=>{try{t(e)}catch(r){console.warn("[React Buoy] License listener error:",r)}})}isCacheValid(e){const i=Date.now();const t=i-e.cachedAt;if(t>F){return false}if(e.expiresAt){const r=new Date(e.expiresAt).getTime();if(i>r){return false}}return true}isCacheFresh(e){return Date.now()-(e.lastValidatedAt??0)<z}async persistCache(e){const i=U(e);const t=await u();await t.setItem(I,JSON.stringify(i));return i}async loadCachedLicense(){try{const e=await u();const i=await e.getItem(I);if(!i)return null;const t=JSON.parse(i);return t}catch(e){console.warn("[Buoy] Error loading cached license:",e);return null}}getOrCreateDeviceFingerprint(){if(!this.fingerprintPromise){this.fingerprintPromise=(async()=>{const e=await u();const i=await e.getItem(_);if(i)return i;const t=this.cachedLicense?.fingerprint||Y();await e.setItem(_,t);return t})()}return this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;try{const e=await u();await e.removeItem(I)}catch{}}registerDeviceAsync(e,i,t,r){const n=S();C(e,i,t,r,n).catch(a=>{if(a.message!=="FINGERPRINT_TAKEN"&&a.message!=="MACHINE_LIMIT_EXCEEDED"){console.warn("[Buoy] Device registration failed (non-blocking):",a.message)}})}validateInBackground(e){const i=this.generation;w(e).then(async t=>{if(i!==this.generation)return;const r=N(t);if(r.valid&&t.data){const n=K(t.data);this.applyTier(n);const a=Date.now();this.cachedLicense=await this.persistCache({...this.cachedLicense??{},licenseKey:e,licenseId:t.data.id,valid:true,isPro:n==="pro",tier:n,expiresAt:t.data.attributes.expiry??null,cachedAt:a,lastValidatedAt:a});this.state.expiresAt=t.data.attributes.expiry?new Date(t.data.attributes.expiry):null;this.emit({type:"validated",isPro:this.state.isPro})}else if(P(r.code)){console.warn("[React Buoy] Background validation: license is invalid -",r.code);this.applyTier(V(r.code));await this.clearCachedLicense();this.emit({type:"deactivated",isPro:false})}}).catch(t=>{console.warn("[React Buoy] Background validation failed:",t);if(D(t)&&i===this.generation&&!this.state.isPro){this.scheduleRetry(e)}})}startRevalidationTimer(){if(this.revalidationTimer){clearInterval(this.revalidationTimer)}this.revalidationTimer=setInterval(()=>{if(this.state.licenseKey&&!this.state.isValidating){this.validateInBackground(this.state.licenseKey)}},G);if(__DEV__){global.__LICENSE_MANAGER_TIMER__=this.revalidationTimer}}stopRevalidationTimer(){if(this.revalidationTimer){clearInterval(this.revalidationTimer);this.revalidationTimer=null}this.cancelRetry()}async forceReregister(){if(this.cachedLicense){this.cachedLicense.fingerprint=void 0;this.cachedLicense.deviceName=void 0}this.fingerprintPromise=null;await this.clearCachedLicense();try{const e=await u();await e.removeItem(_)}catch{}}}export const LicenseManager=new q;if(__DEV__){if(global.__LICENSE_MANAGER_TIMER__){clearInterval(global.__LICENSE_MANAGER_TIMER__)}if(global.__LICENSE_MANAGER_RETRY_TIMER__){clearTimeout(global.__LICENSE_MANAGER_RETRY_TIMER__);global.__LICENSE_MANAGER_RETRY_TIMER__=void 0}}
16
+ */import{getLicenseStorage as f}from"./storage";import{KEYGEN_CONFIG as U,LICENSE_STORAGE_KEY as R,LICENSE_CACHE_DURATION as S,LICENSE_REVALIDATION_INTERVAL as H,LICENSE_LAUNCH_VALIDATION_TTL as Y,LICENSE_TRANSIENT_RETRY_DELAYS as B,LICENSE_RATE_LIMIT_DEFAULT_WAIT as q,LICENSE_QUOTA_COOLDOWN as M,LICENSE_VERDICT_CACHE_DURATION as X,LICENSE_FLEET_MACHINE_THRESHOLD as J,LICENSE_QUIET_VALIDATION_TTL as Q,LICENSE_HOLD_STORAGE_KEY as I,DEVICE_FINGERPRINT_STORAGE_KEY as C}from"./config.js";import{validateLicense as W,activateMachine as k,parseValidationResult as j,isFatalLicenseError as $,isTransientLicenseError as Z,isAcceptedValidation as ee,isRateLimited as te,backoffAfter as ie,machineCount as se}from"./api.js";import{generateUUID as w,getDeviceMetadata as F,getDefaultDeviceName as N,isDevBundle as O}from"./fingerprint";import{signCache as b,verifyCacheSignature as g}from"./cacheSignature.js";import{isBuoyToken as re,verifyFreeToken as ae}from"./freeToken.js";import{resolveTier as ne,isRecognizedAccount as ce}from"./tier.js";import{resolveAccountAccess as he}from"./accountAccess.js";import{subscribeForeground as oe}from"./foreground";async function u(l,e){let t;try{return await Promise.race([l,new Promise(i=>{t=setTimeout(()=>i(e),15e3)})])}finally{if(t)clearTimeout(t)}}function m(l){if(l.tier==="pro"||l.tier==="free")return l.tier;return l.isPro?"pro":"free"}class le{state={isInitialized:false,isValidating:false,isPro:false,tier:"free",tierSource:"none",licenseKey:null,error:null,errorKind:null,expiresAt:null};listeners=new Set;revalidationTimer=null;cachedLicense=null;fingerprintPromise=null;initPromise=null;generation=0;persistence=Promise.resolve();verifiedAt=null;expiryTimer=null;removeForegroundListener=null;retryTimer=null;retryAttempt=0;deviceRegistrationCallback=null;pendingRegistration=null;async initialize(){if(this.initPromise)return this.initPromise;if(this.state.isInitialized)return;this.initPromise=this._doInitialize();return this.initPromise}async _doInitialize(){if(this.state.isInitialized)return;const e=this.generation;try{const t=await u(this.loadCachedLicense(),null);if(e!==this.generation){this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer();return}if(t&&(this.configuredKey===void 0||t.licenseKey===this.configuredKey)){const i=g(t);this.cachedLicense=t;this.state.licenseKey=t.licenseKey;if(i&&this.isCacheValid(t))this.applyTier(m(t));else this.lock();this.state.expiresAt=t.expiresAt?new Date(t.expiresAt):null;if(i&&this.isCacheValid(t))this.setVerifiedAt(t.cachedAt);if(this.configuredKey===void 0&&t.licenseKey&&!(i&&this.isCacheValid(t)&&this.isCacheFresh(t))){this.validateInBackground(t.licenseKey)}}this.state.isInitialized=true;this.emit({type:"initialized",isPro:this.state.isPro});this.startRevalidationTimer()}catch(t){console.warn("[React Buoy] License initialization failed:",t);this.state.isInitialized=true;this.emit({type:"initialized",isPro:false})}}async configure(e){if(e===void 0){await this.initialize();return this.hasAccountAccess()}const t=e.trim().toUpperCase();const i=++this.generation;this.cancelRetry();this.configuredKey=t||null;if(this.state.licenseKey!==this.configuredKey)this.lock();this.state.licenseKey=this.configuredKey;this.state.isValidating=!!t;this.emit({type:"validating",isPro:this.isPro()});await this.initialize();if(i!==this.generation)return false;if(!t){await this.clearLicense();return false}return this.setLicenseKey(t)}async setLicenseKey(e,t){if(!e||e.trim().length===0){this.state.error="License key is required";this.state.errorKind="verdict";return false}const i=e.trim().toUpperCase();const s=++this.generation;this.cancelRetry();if(!t?.isRetry)this.retryAttempt=0;if(this.state.licenseKey!==i)this.lock();this.state.licenseKey=i;this.state.isValidating=true;this.state.error=null;this.state.errorKind=null;this.emit({type:"validating",isPro:this.isPro()});if(re(i))return this.admitToken(i,s);if(!this.cachedLicense){const a=await u(this.loadCachedLicense(),null);if(s!==this.generation)return false;if(a?.licenseKey===i){this.cachedLicense=a;if(g(a)&&this.isCacheValid(a)){this.applyTier(m(a));this.state.expiresAt=a.expiresAt?new Date(a.expiresAt):null;this.setVerifiedAt(a.cachedAt);this.emit({type:"validating",isPro:this.isPro()})}}}const r=this.cachedLicense;if(!t?.force&&r&&r.valid&&r.licenseKey===i&&r.fingerprint&&g(r)&&this.isCacheValid(r)&&this.isCacheFresh(r)){this.applyTier(m(r));this.state.licenseKey=i;this.state.isValidating=false;this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);this.emit({type:"validated",isPro:this.state.isPro});return true}const c=await u(this.loadHold(),null);if(s!==this.generation)return false;const y=(c?.backoffUntil??0)-Date.now();if(y>0){return this.standDown(i,s,"License server is rate limited; retrying later.",y)}if(!t?.force&&c?.key===i&&c.verdictAt!==void 0&&Date.now()-c.verdictAt>=0&&Date.now()-c.verdictAt<X){this.lock();this.state.isValidating=false;this.state.error=c.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});return false}let n;try{n=await W(i)}catch(a){const o=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;if(Z(a)){if(te(a)){const d=Math.min(ie(a,M,q)*2**this.retryAttempt,M);this.retryAttempt+=1;await this.saveHold({...this.hold,backoffUntil:Date.now()+d});if(s!==this.generation)return false;return this.standDown(i,s,o,d)}this.state.isValidating=false;if(this.cachedLicense&&this.cachedLicense.licenseKey===i&&g(this.cachedLicense)&&this.isCacheValid(this.cachedLicense)){this.applyTier(m(this.cachedLicense));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=this.cachedLicense.expiresAt?new Date(this.cachedLicense.expiresAt):null;this.setVerifiedAt(this.cachedLicense.cachedAt);if(!this.isPro())this.scheduleRetry(i);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=o;this.state.errorKind="transport";this.scheduleRetry(i);this.emit({type:"error",isPro:this.state.isPro,error:o});return false}this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}try{if(s!==this.generation)return false;const a=j(n);const o=n.data?.relationships?.product?.data?.id;if((!o||o===U.productId)&&a.code==="EXPIRED"&&(ce(n.data)||this.cachedLicense?.licenseKey===i&&g(this.cachedLicense)&&this.isCacheValid(this.cachedLicense))){const L=Date.now();const x=await this.saveCache({licenseKey:i,licenseId:n.data?.id??"",valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:L,lastValidatedAt:L,fingerprint:this.cachedLicense?.licenseKey===i?this.cachedLicense.fingerprint:void 0},s);if(s!==this.generation||!x)return false;this.cachedLicense=x;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(L);this.emit({type:"validated",isPro:false});return true}if($(a.code)||!ee(n)){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License could not be verified";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();await this.saveHold({key:i,code:a.code,detail:this.state.error,verdictAt:Date.now()});return false}if(!n.data){this.lock();this.state.isValidating=false;this.state.error=a.detail||"License not found";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const d=ne(n.data);const A=n.data.id;const E=Date.now();const D=se(n)>=J;const P=O();const G=P&&!D;const z=d==="free"&&(D||!P);let _=this.cachedLicense?.fingerprint;let p=this.cachedLicense?.deviceName;let V=false;if(!_){_=await u(this.getOrCreateDeviceFingerprint(),w());if(s!==this.generation)return false;p=N();V=G}let v=false;if(V){if(this.deviceRegistrationCallback){this.pendingRegistration={licenseId:A,licenseKey:i,fingerprint:_};this.deviceRegistrationCallback({fingerprint:_,defaultName:p});v=true}else{this.registerDeviceAsync(A,i,_,p)}}const T={licenseKey:i,licenseId:A,valid:true,isPro:d==="pro",tier:d,expiresAt:n.data.attributes.expiry??null,cachedAt:E,lastValidatedAt:E,fingerprint:v?void 0:_,deviceName:v?void 0:p,quiet:z||void 0};const K=await this.saveCache(T,s);if(s!==this.generation||!K)return false;this.cachedLicense=K;this.applyTier(d);this.state.isValidating=false;this.state.expiresAt=T.expiresAt?new Date(T.expiresAt):null;this.setVerifiedAt(E);if(this.hold)await this.saveHold(null);if(s!==this.generation)return false;this.retryAttempt=0;this.emit({type:"validated",isPro:this.state.isPro});return true}catch(a){const o=a instanceof Error?a.message:"Validation failed";if(s!==this.generation)return false;this.state.isValidating=false;this.state.error=o;this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:o});return false}}scheduleRetry(e){this.cancelRetry();const t=B[this.retryAttempt];if(t===void 0)return;this.retryAttempt+=1;const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},t);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}}async admitToken(e,t){const i=ae(e);if(t!==this.generation)return false;if(!i){this.lock();this.state.isValidating=false;this.state.error="This key is not valid. Check that it was copied completely.";this.state.errorKind="verdict";this.emit({type:"error",isPro:false,error:this.state.error});await this.clearCachedLicense();return false}const s=Date.now();const r=this.cachedLicense?.fingerprint??await u(this.getOrCreateDeviceFingerprint(),w());if(t!==this.generation)return false;const c=await this.saveCache({licenseKey:e,licenseId:`token:${i.accountHash}`,valid:true,isPro:false,tier:"free",expiresAt:null,cachedAt:s,lastValidatedAt:s,fingerprint:r,deviceName:this.cachedLicense?.deviceName??N(),quiet:true},t);if(t!==this.generation||!c)return false;this.cachedLicense=c;this.applyTier("free");this.state.isValidating=false;this.state.expiresAt=null;this.setVerifiedAt(s);this.retryAttempt=0;this.emit({type:"validated",isPro:false});return true}standDown(e,t,i,s){if(t!==this.generation)return false;this.state.isValidating=false;const r=this.cachedLicense;if(r&&r.licenseKey===e&&g(r)&&this.isCacheValid(r)){this.applyTier(m(r));this.state.error=null;this.state.errorKind=null;this.state.expiresAt=r.expiresAt?new Date(r.expiresAt):null;this.setVerifiedAt(r.cachedAt);if(!this.isPro())this.scheduleRetryIn(e,s);this.emit({type:"validated",isPro:this.state.isPro});return true}this.state.error=i;this.state.errorKind="transport";this.scheduleRetryIn(e,s);this.emit({type:"error",isPro:this.state.isPro,error:i});return false}scheduleRetryIn(e,t){this.cancelRetry();const i=this.generation;this.retryTimer=setTimeout(()=>{this.retryTimer=null;if(i!==this.generation)return;if(this.state.isValidating)return;void this.setLicenseKey(e,{force:true,isRetry:true})},Math.max(1,Math.min(t,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)h.__LICENSE_MANAGER_RETRY_TIMER__=this.retryTimer}cancelRetry(){if(this.retryTimer){clearTimeout(this.retryTimer);this.retryTimer=null}}async clearLicense(){this.generation+=1;this.cancelRetry();this.retryAttempt=0;this.configuredKey=null;this.state.licenseKey=null;this.lock();this.state.expiresAt=null;this.state.error=null;this.state.errorKind=null;this.cachedLicense=null;this.pendingRegistration=null;this.state.isValidating=false;this.emit({type:"deactivated",isPro:false});await this.clearCachedLicense();if(this.hold?.verdictAt!==void 0){await this.saveHold(this.hold.backoffUntil?{backoffUntil:this.hold.backoffUntil}:null)}}applyTier(e){this.state.tier=e;this.state.tierSource="key";this.state.isPro=e==="pro"}lock(){this.state.tier="free";this.state.tierSource="none";this.state.isPro=false;this.verifiedAt=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null}getTier(){if(!this.hasAccountAccess())return"free";if(this.state.expiresAt&&Date.now()>=this.state.expiresAt.getTime())return"free";return this.state.tier}isPro(){return this.getTier()==="pro"}hasEntitlement(e){return this.isPro()}getState(){const e=this.getAccountAccess();const t=this.getTier();return{...this.state,tier:t,isPro:t==="pro",access:e}}getAccountAccess(){return he({initialized:this.state.isInitialized,validating:this.state.isValidating,key:this.state.licenseKey,tierSource:this.state.tierSource,verifiedAt:this.verifiedAt})}hasAccountAccess(){return this.getAccountAccess().status==="admitted"}setVerifiedAt(e){this.verifiedAt=e;if(this.expiryTimer)clearTimeout(this.expiryTimer);const t=e+S;const i=this.state.expiresAt?.getTime();const s=i&&i>Date.now()?Math.min(t,i):t;const r=s-Date.now();this.expiryTimer=setTimeout(()=>{this.expiryTimer=null;if(this.verifiedAt!==e)return;this.emit({type:"validated",isPro:this.isPro()});if(Date.now()<t)this.setVerifiedAt(e)},Math.max(1,Math.min(r,2147483647)));if(typeof __DEV__!=="undefined"&&__DEV__)h.__LICENSE_MANAGER_EXPIRY_TIMER__=this.expiryTimer}subscribe(e){this.listeners.add(e);return()=>this.listeners.delete(e)}onDeviceRegistrationNeeded(e){this.deviceRegistrationCallback=e;return()=>{this.deviceRegistrationCallback=null}}async completeDeviceRegistration(e){if(!this.pendingRegistration){console.warn("[Buoy] No pending device registration");return}const{licenseId:t,licenseKey:i,fingerprint:s}=this.pendingRegistration;const r=this.generation;const c=e.trim()||N();const y=F();try{await k(t,i,s,c,y)}catch(n){const a=n instanceof Error?n.message:String(n);if(a==="FINGERPRINT_TAKEN"||a==="MACHINE_LIMIT_EXCEEDED"){}else{console.warn("[Buoy] Device registration failed:",a);throw n}}if(r!==this.generation)return;if(this.cachedLicense?.licenseKey===i){const n=await this.saveCache({...this.cachedLicense,fingerprint:s,deviceName:c},r);if(r!==this.generation)return;if(n)this.cachedLicense=n}this.pendingRegistration=null}emit(e){const t=[...this.listeners];t.forEach(i=>{try{i(e)}catch(s){console.warn("[React Buoy] License listener error:",s)}})}isCacheValid(e){const t=Date.now();const i=t-e.cachedAt;if(!e.valid||!Number.isFinite(e.cachedAt)||i<0||i>=S){return false}return true}isCacheFresh(e){const t=this.isQuiet(e)?Q:Y;return Date.now()-(e.lastValidatedAt??0)<t}isQuiet(e){if(e.quiet!==void 0)return e.quiet;return m(e)==="free"&&!O()}async loadHold(){if(this.hold!==void 0)return this.hold;try{const e=await f();const t=await e.getItem(I);const i=t?JSON.parse(t):null;this.hold=i&&typeof i==="object"?i:null}catch{this.hold=null}return this.hold}async saveHold(e){this.hold=e;try{const t=await f();if(e)await t.setItem(I,JSON.stringify(e));else await t.removeItem(I)}catch{}}async persistCache(e){const t=b(e);const i=await f();await i.setItem(R,JSON.stringify(t));return t}saveCache(e,t){const i=this.persistence.catch(()=>{}).then(async()=>{if(t!==this.generation)return null;const s=await this.persistCache(e);return t===this.generation?s:null});this.persistence=i;return u(i,b(e))}async loadCachedLicense(){try{await this.persistence.catch(()=>{});const e=await f();const t=await e.getItem(R);if(!t)return null;const i=JSON.parse(t);return i}catch(e){console.warn("[Buoy] Error loading cached license:",e);return null}}getOrCreateDeviceFingerprint(){if(!this.fingerprintPromise){this.fingerprintPromise=(async()=>{const e=await f();const t=await e.getItem(C);if(t)return t;const i=this.cachedLicense?.fingerprint||w();await e.setItem(C,i);return i})()}return this.fingerprintPromise}async clearCachedLicense(){this.cachedLicense=null;const e=this.persistence.catch(()=>{}).then(async()=>{const t=await f();await t.removeItem(R)});this.persistence=e;await u(e.catch(()=>{}),void 0)}registerDeviceAsync(e,t,i,s){const r=F();k(e,t,i,s,r).catch(c=>{if(c.message!=="FINGERPRINT_TAKEN"&&c.message!=="MACHINE_LIMIT_EXCEEDED"){console.warn("[Buoy] Device registration failed (non-blocking):",c.message)}})}validateInBackground(e){void this.setLicenseKey(e,{force:true,isRetry:true})}refreshAccess(){this.emit({type:"validated",isPro:this.isPro()})}startRevalidationTimer(){if(!this.removeForegroundListener){this.removeForegroundListener=oe(()=>this.refreshAccess());if(typeof __DEV__!=="undefined"&&__DEV__)h.__LICENSE_MANAGER_FOREGROUND_OFF__=this.removeForegroundListener}if(this.revalidationTimer){clearInterval(this.revalidationTimer)}this.revalidationTimer=setInterval(()=>{if(!this.state.licenseKey||this.state.isValidating)return;const e=this.cachedLicense;if(e&&e.licenseKey===this.state.licenseKey&&this.isCacheFresh(e))return;this.validateInBackground(this.state.licenseKey)},H);if(typeof __DEV__!=="undefined"&&__DEV__){global.__LICENSE_MANAGER_TIMER__=this.revalidationTimer}}stopRevalidationTimer(){this.removeForegroundListener?.();this.removeForegroundListener=null;if(this.expiryTimer)clearTimeout(this.expiryTimer);this.expiryTimer=null;if(this.revalidationTimer){clearInterval(this.revalidationTimer);this.revalidationTimer=null}this.cancelRetry()}async forceReregister(){if(this.cachedLicense){this.cachedLicense.fingerprint=void 0;this.cachedLicense.deviceName=void 0}this.fingerprintPromise=null;await this.clearCachedLicense();try{const e=await f();await e.removeItem(C)}catch{}}}export const LicenseManager=new le;const h=globalThis;if(typeof __DEV__!=="undefined"&&__DEV__){h.__LICENSE_MANAGER_FOREGROUND_OFF__?.();h.__LICENSE_MANAGER_FOREGROUND_OFF__=void 0;if(h.__LICENSE_MANAGER_EXPIRY_TIMER__)clearTimeout(h.__LICENSE_MANAGER_EXPIRY_TIMER__);if(h.__LICENSE_MANAGER_TIMER__){clearInterval(h.__LICENSE_MANAGER_TIMER__)}if(h.__LICENSE_MANAGER_RETRY_TIMER__){clearTimeout(h.__LICENSE_MANAGER_RETRY_TIMER__);h.__LICENSE_MANAGER_RETRY_TIMER__=void 0}}
@@ -0,0 +1 @@
1
+ "use strict";import{LICENSE_CACHE_DURATION as t}from"./config.js";export function resolveAccountAccess(i,r=Date.now()){const e=i.verifiedAt!==null&&Number.isFinite(i.verifiedAt)&&i.verifiedAt<=r?i.verifiedAt+t:null;if(i.initialized&&i.key&&i.tierSource!=="none"&&e!==null&&r<e){return{status:"admitted",reason:null,validUntil:e}}if(e!==null&&r>=e){return{status:"locked",reason:"verification_expired",validUntil:e}}if(!i.initialized||i.validating){return{status:"initializing",reason:"checking",validUntil:e}}return{status:"locked",reason:e!==null&&r>=e?"verification_expired":"account_required",validUntil:e}}
package/lib/module/api.js CHANGED
@@ -1 +1 @@
1
- "use strict";import{KEYGEN_CONFIG as f}from"./config.js";const{accountId:l,productToken:h,apiUrl:T}=f;export class LicenseTransportError extends Error{isTransient=true;constructor(t,n){super(t);this.name="LicenseTransportError";this.status=n}}export function isTransientLicenseError(e){if(e instanceof LicenseTransportError)return true;if(e instanceof TypeError)return true;return typeof e==="object"&&e!==null&&e.isTransient===true}async function w(e){try{const t=await e.json();return t.errors?.[0]?.detail||`HTTP ${e.status}`}catch{return`HTTP ${e.status}`}}function u(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}function p(e){return{...u(),Authorization:`License ${e}`}}function N(){return{...u(),Authorization:`Bearer ${h}`}}export async function validateLicense(e){const t=`${T}/${l}/licenses/actions/validate-key`;const n={meta:{key:e}};let r;try{r=await fetch(t,{method:"POST",headers:u(),body:JSON.stringify(n)})}catch(i){throw new LicenseTransportError(i instanceof Error?i.message:"Network request failed",null)}if(!r.ok){throw new LicenseTransportError(await w(r),r.status)}try{return await r.json()}catch{throw new LicenseTransportError("License server returned an unreadable response",r.status)}}export async function activateMachine(e,t,n,r,i){const d=`${T}/${l}/machines`;const E={data:{type:"machines",attributes:{fingerprint:n,name:r,metadata:i||{}},relationships:{license:{data:{type:"licenses",id:e}}}}};let o=await fetch(d,{method:"POST",headers:p(t),body:JSON.stringify(E)});if(!o.ok){const a=await o.json();const s=a.errors?.[0]?.detail||"";const c=a.errors?.[0]?.code;if(s.toLowerCase().includes("authentication is not allowed by policy")){o=await fetch(d,{method:"POST",headers:N(),body:JSON.stringify(E)})}else if(c==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}else if(c==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}else{throw new Error(s)}}if(!o.ok){const a=await o.json();const s=a.errors?.[0]?.code;if(s==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}if(s==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}const c=a.errors?.[0]?.detail||`HTTP ${o.status}`;throw new Error(c)}return o.json()}export function parseValidationResult(e){const{meta:t,data:n}=e;return{valid:t.valid,code:t.code,detail:t.detail,metadata:n?.attributes?.metadata}}export function isFatalLicenseError(e){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(e)}
1
+ "use strict";import{KEYGEN_CONFIG as E}from"./config.js";const{accountId:f,productToken:N,apiUrl:T}=E;export class LicenseTransportError extends Error{isTransient=true;constructor(e,n,a=null){super(e);this.name="LicenseTransportError";this.status=n;this.retryAfterMs=a}}export function isRateLimited(t){const e=t?.status;return e===429||e===402}export function backoffAfter(t,e,n){if(t.status===402)return e;return t.retryAfterMs??n}function h(t){const e=r=>{try{return t.headers?.get?.(r)??null}catch{return null}};const n=e("Retry-After");if(n){const r=Number(n);if(Number.isFinite(r)&&r>=0)return r*1e3;const o=Date.parse(n);if(Number.isFinite(o))return Math.max(0,o-Date.now())}const a=Number(e("X-RateLimit-Reset"));if(Number.isFinite(a)&&a>0)return Math.max(0,a*1e3-Date.now());return null}export function isTransientLicenseError(t){if(t instanceof LicenseTransportError)return true;if(t instanceof TypeError)return true;return typeof t==="object"&&t!==null&&t.isTransient===true}async function m(t){try{const e=await t.json();return e.errors?.[0]?.detail||`HTTP ${t.status}`}catch{return`HTTP ${t.status}`}}function d(){return{"Content-Type":"application/vnd.api+json",Accept:"application/vnd.api+json"}}function p(t){return{...d(),Authorization:`License ${t}`}}function y(){return{...d(),Authorization:`Bearer ${N}`}}async function w(t,e){const n=`${T}/${f}/licenses/actions/validate-key`;const a={meta:{key:t}};let r;try{r=await fetch(n,{signal:e,method:"POST",headers:d(),body:JSON.stringify(a)})}catch(o){throw new LicenseTransportError(o instanceof Error?o.message:"Network request failed",null)}if(!r.ok){throw new LicenseTransportError(await m(r),r.status,r.status===429?h(r):null)}try{const o=await r.json();if(!o||typeof o!=="object"||typeof o.meta?.valid!=="boolean"||typeof o.meta?.code!=="string"||!o.meta.code)throw new Error("Missing license verdict");return o}catch{throw new LicenseTransportError("License server returned an unreadable response",r.status)}}export async function validateLicense(t){const e=typeof AbortController==="function"?new AbortController:null;let n;try{return await Promise.race([w(t,e?.signal),new Promise((a,r)=>{n=setTimeout(()=>{r(new LicenseTransportError("License verification timed out. Please retry.",null));e?.abort()},15e3)})])}finally{if(n)clearTimeout(n)}}export function isAcceptedValidation(t){if(!t.data)return false;const e=t.data.relationships?.product?.data?.id;if(e&&e!==E.productId)return false;if(t.meta.valid&&t.meta.code==="VALID")return true;return["OVERDUE","NO_MACHINE","NO_MACHINES","TOO_MANY_MACHINES","TOO_MANY_CORES","TOO_MANY_PROCESSES","FINGERPRINT_SCOPE_MISMATCH","HEARTBEAT_NOT_STARTED","HEARTBEAT_DEAD"].includes(t.meta.code)}export function machineCount(t){const e=t.data?.relationships?.machines?.meta?.count;return typeof e==="number"&&Number.isFinite(e)?e:0}export async function activateMachine(t,e,n,a,r){const o=`${T}/${f}/machines`;const l={data:{type:"machines",attributes:{fingerprint:n,name:a,metadata:r||{}},relationships:{license:{data:{type:"licenses",id:t}}}}};let i=await fetch(o,{method:"POST",headers:p(e),body:JSON.stringify(l)});if(!i.ok){const s=await i.json();const c=s.errors?.[0]?.detail||"";const u=s.errors?.[0]?.code;if(c.toLowerCase().includes("authentication is not allowed by policy")){i=await fetch(o,{method:"POST",headers:y(),body:JSON.stringify(l)})}else if(u==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}else if(u==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}else{throw new Error(c)}}if(!i.ok){const s=await i.json();const c=s.errors?.[0]?.code;if(c==="FINGERPRINT_TAKEN"){throw new Error("FINGERPRINT_TAKEN")}if(c==="MACHINE_LIMIT_EXCEEDED"){throw new Error("MACHINE_LIMIT_EXCEEDED")}const u=s.errors?.[0]?.detail||`HTTP ${i.status}`;throw new Error(u)}return i.json()}export function parseValidationResult(t){const{meta:e,data:n}=t;return{valid:e.valid,code:e.code,detail:e.detail,metadata:n?.attributes?.metadata}}export function isFatalLicenseError(t){return["NOT_FOUND","SUSPENDED","EXPIRED","BANNED","PRODUCT_SCOPE_MISMATCH"].includes(t)}
@@ -14,4 +14,4 @@
14
14
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
15
15
  * including a free one (`npx buoy login`). Buy a key at
16
16
  * https://buoy.gg or use it free on Saturday and Sunday.
17
- */export const KEYGEN_CONFIG={accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",productToken:"prod-4467c14b75b715e91884945cd3e69705846ccbce7dd5e380236a1ab3bc03139fv3",apiUrl:"https://api.keygen.sh/v1/accounts"};export const KEYGEN_POLICIES={free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"};export const LICENSE_CACHE_DURATION=30*24*60*60*1e3;export const LICENSE_REVALIDATION_INTERVAL=24*60*60*1e3;export const LICENSE_STORAGE_KEY="buoy-gg-license";export const DEVICE_FINGERPRINT_STORAGE_KEY="buoy-gg-device-fingerprint";export const LICENSE_LAUNCH_VALIDATION_TTL=60*60*1e3;export const LICENSE_TRANSIENT_RETRY_DELAYS=[5*1e3,20*1e3,60*1e3,5*60*1e3,15*60*1e3];export const ANONYMOUS_TIER_ENABLED=true;
17
+ */export const KEYGEN_CONFIG={accountId:"b0eba0e8-e904-4906-b644-38f9aab57bed",productId:"bf67cb43-eeef-40ca-b308-e6e1b22c0eaa",productToken:"prod-4467c14b75b715e91884945cd3e69705846ccbce7dd5e380236a1ab3bc03139fv3",apiUrl:"https://api.keygen.sh/v1/accounts"};export const FREE_TOKEN_PUBLIC_KEY="3b546fc717a62683f3236c70167899a271bee3ffc04df6ec1eea60a394a2f1e9";export const KEYGEN_POLICIES={free:"394e3351-1249-4f73-807a-703408604c0e",solo:"fa5d3c8f-5379-40f1-b63e-ab8a974b2f28",business:"690c2212-8e54-426f-b4b4-002ee1c0ae2b"};export const LICENSE_CACHE_DURATION=30*24*60*60*1e3;export const LICENSE_REVALIDATION_INTERVAL=24*60*60*1e3;export const LICENSE_STORAGE_KEY="buoy-gg-license";export const DEVICE_FINGERPRINT_STORAGE_KEY="buoy-gg-device-fingerprint";export const LICENSE_LAUNCH_VALIDATION_TTL=60*60*1e3;export const LICENSE_TRANSIENT_RETRY_DELAYS=[5*1e3,20*1e3,60*1e3,5*60*1e3,15*60*1e3];export const LICENSE_RATE_LIMIT_DEFAULT_WAIT=60*1e3;export const LICENSE_QUOTA_COOLDOWN=60*60*1e3;export const LICENSE_VERDICT_CACHE_DURATION=24*60*60*1e3;export const LICENSE_FLEET_MACHINE_THRESHOLD=50;export const LICENSE_QUIET_VALIDATION_TTL=LICENSE_CACHE_DURATION;export const LICENSE_HOLD_STORAGE_KEY="buoy-gg-license-hold";
@@ -1 +1 @@
1
- "use strict";import{Platform as r}from"react-native";export function generateUUID(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const t=Math.random()*16|0;const e=n==="x"?t:t&3|8;return e.toString(16)})}export function isSimulator(){if(r.OS==="ios"){const n=r.constants;if(n?.interfaceIdiom==="simulator"){return true}if("isTesting"in r&&r.isTesting){return true}return false}if(r.OS==="android"){const n=r.constants;const t=String(n?.Brand||"").toLowerCase();const e=String(n?.Model||"").toLowerCase();const i=String(n?.Fingerprint||"").toLowerCase();const o=t.includes("generic")||e.includes("sdk")||e.includes("emulator")||e.includes("android sdk")||i.includes("generic");return o}return false}export function getDeviceMetadata(){const n={platform:r.OS,osVersion:String(r.Version),isSimulator:String(isSimulator())};if(r.OS==="android"){const t=r.constants;if(t?.Brand)n.brand=String(t.Brand);if(t?.Model)n.model=String(t.Model);if(t?.Manufacturer)n.manufacturer=String(t.Manufacturer)}if(r.OS==="ios"){const t=r.constants;if(t?.systemName)n.systemName=String(t.systemName);if(t?.interfaceIdiom)n.interfaceIdiom=String(t.interfaceIdiom)}return n}export function getDefaultDeviceName(){const n=r.OS==="ios"?"iOS":r.OS==="android"?"Android":r.OS;const t=isSimulator()?" Simulator":"";return`My ${n} Device${t}`}
1
+ "use strict";import{NativeModules as s,Platform as e}from"react-native";export function generateUUID(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const t=Math.random()*16|0;const r=n==="x"?t:t&3|8;return r.toString(16)})}export function isDevBundle(){try{const n=s?.SourceCode;const t=n?.scriptURL??n?.getConstants?.()?.scriptURL;if(typeof t==="string"&&t.length>0)return/^https?:\/\//i.test(t)}catch{}return typeof __DEV__!=="undefined"&&__DEV__}export function isSimulator(){if(e.OS==="ios"){const n=e.constants;if(n?.interfaceIdiom==="simulator"){return true}if("isTesting"in e&&e.isTesting){return true}return false}if(e.OS==="android"){const n=e.constants;const t=String(n?.Brand||"").toLowerCase();const r=String(n?.Model||"").toLowerCase();const i=String(n?.Fingerprint||"").toLowerCase();const o=t.includes("generic")||r.includes("sdk")||r.includes("emulator")||r.includes("android sdk")||i.includes("generic");return o}return false}export function getDeviceMetadata(){const n={platform:e.OS,osVersion:String(e.Version),isSimulator:String(isSimulator())};if(e.OS==="android"){const t=e.constants;if(t?.Brand)n.brand=String(t.Brand);if(t?.Model)n.model=String(t.Model);if(t?.Manufacturer)n.manufacturer=String(t.Manufacturer)}if(e.OS==="ios"){const t=e.constants;if(t?.systemName)n.systemName=String(t.systemName);if(t?.interfaceIdiom)n.interfaceIdiom=String(t.interfaceIdiom)}return n}export function getDefaultDeviceName(){const n=e.OS==="ios"?"iOS":e.OS==="android"?"Android":e.OS;const t=isSimulator()?" Simulator":"";return`My ${n} Device${t}`}
@@ -1 +1 @@
1
- "use strict";export function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;const r=n==="x"?e:e&3|8;return r.toString(16)})}export function isSimulator(){return false}function a(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent.toLowerCase();const e=navigator.platform?.toLowerCase()||"";if(n.includes("electron")){if(e.includes("mac")||n.includes("mac")){return"electron-macos"}if(e.includes("win")||n.includes("win")){return"electron-windows"}if(e.includes("linux")||n.includes("linux")){return"electron-linux"}return"electron"}if(e.includes("mac")||n.includes("mac")){return"macos"}if(e.includes("win")||n.includes("win")){return"windows"}if(e.includes("linux")||n.includes("linux")){return"linux"}if(/iphone|ipad|ipod/.test(n)){return"ios-web"}if(n.includes("android")){return"android-web"}return"web"}function u(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent;const e=n.match(/Mac OS X ([\d_.]+)/);if(e){return e[1].replace(/_/g,".")}const r=n.match(/Windows NT ([\d.]+)/);if(r){const t={"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"};return t[r[1]]||r[1]}if(n.includes("Linux")){return"Linux"}return"unknown"}function c(){if(typeof navigator==="undefined"){return{name:"unknown",version:"unknown"}}const n=navigator.userAgent;const e=n.match(/Electron\/([\d.]+)/);if(e){return{name:"Electron",version:e[1]}}const r=n.match(/Chrome\/([\d.]+)/);if(r&&!n.includes("Edg")){return{name:"Chrome",version:r[1]}}const t=n.match(/Edg\/([\d.]+)/);if(t){return{name:"Edge",version:t[1]}}const o=n.match(/Firefox\/([\d.]+)/);if(o){return{name:"Firefox",version:o[1]}}const i=n.match(/Version\/([\d.]+).*Safari/);if(i){return{name:"Safari",version:i[1]}}return{name:"unknown",version:"unknown"}}export function getDeviceMetadata(){const n={platform:a(),osVersion:u(),isSimulator:"false"};const e=c();n.browser=e.name;n.browserVersion=e.version;if(typeof window!=="undefined"&&window.screen){n.screenResolution=`${window.screen.width}x${window.screen.height}`}if(typeof navigator!=="undefined"&&navigator.language){n.language=navigator.language}try{n.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return n}export function getDefaultDeviceName(){const n=a();const e=c();if(n.startsWith("electron")){const r=n.replace("electron-","").replace("electron","Desktop");return`${r.charAt(0).toUpperCase()+r.slice(1)} App`}if(e.name!=="unknown"){return`${e.name} Browser`}return"Web Browser"}
1
+ "use strict";export function generateUUID(){if(typeof crypto!=="undefined"&&crypto.randomUUID){return crypto.randomUUID()}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;const r=n==="x"?e:e&3|8;return r.toString(16)})}export function isDevBundle(){if(typeof __DEV__!=="undefined")return __DEV__;try{if(typeof navigator!=="undefined"&&/electron/i.test(navigator.userAgent))return true}catch{}return typeof process!=="undefined"&&process.env?.NODE_ENV!=="production"}export function isSimulator(){return false}function a(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent.toLowerCase();const e=navigator.platform?.toLowerCase()||"";if(n.includes("electron")){if(e.includes("mac")||n.includes("mac")){return"electron-macos"}if(e.includes("win")||n.includes("win")){return"electron-windows"}if(e.includes("linux")||n.includes("linux")){return"electron-linux"}return"electron"}if(e.includes("mac")||n.includes("mac")){return"macos"}if(e.includes("win")||n.includes("win")){return"windows"}if(e.includes("linux")||n.includes("linux")){return"linux"}if(/iphone|ipad|ipod/.test(n)){return"ios-web"}if(n.includes("android")){return"android-web"}return"web"}function u(){if(typeof navigator==="undefined"){return"unknown"}const n=navigator.userAgent;const e=n.match(/Mac OS X ([\d_.]+)/);if(e){return e[1].replace(/_/g,".")}const r=n.match(/Windows NT ([\d.]+)/);if(r){const t={"10.0":"10/11","6.3":"8.1","6.2":"8","6.1":"7"};return t[r[1]]||r[1]}if(n.includes("Linux")){return"Linux"}return"unknown"}function c(){if(typeof navigator==="undefined"){return{name:"unknown",version:"unknown"}}const n=navigator.userAgent;const e=n.match(/Electron\/([\d.]+)/);if(e){return{name:"Electron",version:e[1]}}const r=n.match(/Chrome\/([\d.]+)/);if(r&&!n.includes("Edg")){return{name:"Chrome",version:r[1]}}const t=n.match(/Edg\/([\d.]+)/);if(t){return{name:"Edge",version:t[1]}}const o=n.match(/Firefox\/([\d.]+)/);if(o){return{name:"Firefox",version:o[1]}}const i=n.match(/Version\/([\d.]+).*Safari/);if(i){return{name:"Safari",version:i[1]}}return{name:"unknown",version:"unknown"}}export function getDeviceMetadata(){const n={platform:a(),osVersion:u(),isSimulator:"false"};const e=c();n.browser=e.name;n.browserVersion=e.version;if(typeof window!=="undefined"&&window.screen){n.screenResolution=`${window.screen.width}x${window.screen.height}`}if(typeof navigator!=="undefined"&&navigator.language){n.language=navigator.language}try{n.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}catch{}return n}export function getDefaultDeviceName(){const n=a();const e=c();if(n.startsWith("electron")){const r=n.replace("electron-","").replace("electron","Desktop");return`${r.charAt(0).toUpperCase()+r.slice(1)} App`}if(e.name!=="unknown"){return`${e.name} Browser`}return"Web Browser"}
@@ -1 +1 @@
1
- "use strict";export{generateUUID,isSimulator,getDeviceMetadata,getDefaultDeviceName}from"./device-info";
1
+ "use strict";export{generateUUID,isDevBundle,isSimulator,getDeviceMetadata,getDefaultDeviceName}from"./device-info";
@@ -1 +1 @@
1
- "use strict";export{generateUUID,isSimulator,getDeviceMetadata,getDefaultDeviceName}from"./device-info.web.js";
1
+ "use strict";export{generateUUID,isDevBundle,isSimulator,getDeviceMetadata,getDefaultDeviceName}from"./device-info.web.js";
@@ -0,0 +1 @@
1
+ "use strict";import{AppState as i}from"react-native";export function subscribeForeground(e){const t=i?.addEventListener("change",r=>{if(r==="active")e()});return()=>t?.remove()}
@@ -0,0 +1 @@
1
+ "use strict";export function subscribeForeground(e){if(typeof window==="undefined"||typeof window.addEventListener!=="function")return()=>{};const n=()=>{if(!document.hidden)e()};window.addEventListener("focus",e);document.addEventListener("visibilitychange",n);return()=>{window.removeEventListener("focus",e);document.removeEventListener("visibilitychange",n)}}
@@ -0,0 +1,6 @@
1
+ "use strict";/*!
2
+ * PROPRIETARY — Buoy Pro license enforcement. NOT open source.
3
+ *
4
+ * Copyright (c) Buoy. All rights reserved. Licensed under the Buoy EULA
5
+ * (https://buoy.gg/terms), not an OSS license.
6
+ */import s from"tweetnacl";import{FREE_TOKEN_PUBLIC_KEY as f}from"./config.js";export const FREE_TOKEN_PREFIX="BUOY1";const l=1;const a=1;const A="buoy-free-token-v1:";const E=22;const F=64;const d=/^BUOY1-([A-Z2-7]+)-([A-Z2-7]+)$/;export function isBuoyToken(n){return d.test(n.trim().toUpperCase())}const i="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function y(n){let o="";let t=0;let e=0;for(const r of n){e=e<<8|r;t+=8;while(t>=5){o+=i[e>>>t-5&31];t-=5}}if(t>0)o+=i[e<<5-t&31];return o}function h(n){const o=[];let t=0;let e=0;for(const r of n){const c=i.indexOf(r);if(c===-1)return null;e=e<<5|c;t+=5;if(t>=8){o.push(e>>>t-8&255);t-=8}}return new Uint8Array(o)}function u(n){const o=n.trim().toLowerCase();const t=new Uint8Array(o.length/2);for(let e=0;e<t.length;e+=1)t[e]=parseInt(o.slice(e*2,e*2+2),16);return t}function p(n){let o="";for(const t of n)o+=t.toString(16).padStart(2,"0");return o}function T(n){if(typeof TextEncoder!=="undefined")return new TextEncoder().encode(n);const o=new Uint8Array(n.length);for(let t=0;t<n.length;t+=1)o[t]=n.charCodeAt(t)&255;return o}function m(n,o){const t=new Uint8Array(n.length+o.length);t.set(n,0);t.set(o,n.length);return t}function g(n){return m(T(A),n)}export function accountHashFor(n){return s.hash(T(n)).slice(0,16)}function x(n,o){const t=new Uint8Array(E);t[0]=l;t[1]=a;const e=Math.max(0,Math.min(4294967295,Math.floor(n)));t[2]=e>>>24&255;t[3]=e>>>16&255;t[4]=e>>>8&255;t[5]=e&255;t.set(o.slice(0,16),6);return t}export function mintFreeToken(n,o,t){const e=x(o/1e3,accountHashFor(n));const{secretKey:r}=s.sign.keyPair.fromSeed(u(t));const c=s.sign.detached(g(e),r);return`${FREE_TOKEN_PREFIX}-${y(e)}-${y(c)}`}export function publicKeyFor(n){return p(s.sign.keyPair.fromSeed(u(n)).publicKey)}let _=f;export function __setFreeTokenPublicKeyForTests(n){_=n??f}export function verifyFreeToken(n,o=_){const t=d.exec(n.trim().toUpperCase());if(!t)return null;const e=h(t[1]);const r=h(t[2]);if(!e||!r)return null;if(e.length!==E||r.length!==F)return null;if(e[0]!==l||e[1]!==a)return null;try{if(!s.sign.detached.verify(g(e),r,u(o)))return null}catch{return null}const c=(e[2]<<24>>>0)+(e[3]<<16)+(e[4]<<8)+e[5];return{tier:"free",issuedAt:c*1e3,accountHash:p(e.slice(6,22))}}
@@ -0,0 +1 @@
1
+ "use strict";export{validateLicense,isAcceptedValidation,isTransientLicenseError,LicenseTransportError}from"./api.js";export{resolveTier,isRecognizedAccount}from"./tier.js";export{isBuoyToken,verifyFreeToken,mintFreeToken,accountHashFor,publicKeyFor,__setFreeTokenPublicKeyForTests}from"./freeToken.js";export{resolveAccountAccess}from"./accountAccess.js";export{signCache,verifyCacheSignature}from"./cacheSignature.js";export{LICENSE_CACHE_DURATION,LICENSE_REVALIDATION_INTERVAL,LICENSE_LAUNCH_VALIDATION_TTL,LICENSE_TRANSIENT_RETRY_DELAYS,KEYGEN_CONFIG}from"./config.js";
@@ -14,4 +14,4 @@
14
14
  * Pro is $9/mo, and is free every weekend for anyone holding a key —
15
15
  * including a free one (`npx buoy login`). Buy a key at
16
16
  * https://buoy.gg or use it free on Saturday and Sunday.
17
- */import{useState as l,useEffect as d,useCallback as c}from"react";import{LicenseManager as n}from"./LicenseManager.js";import{useWeekendFreePro as a,weekendPassAppliesTo as u}from"./weekendPro.js";export function useLicense(){const[i,e]=l(n.getState());d(()=>{const s=n.subscribe(o=>{e(n.getState())});n.initialize().then(()=>{e(n.getState())});return s},[]);const r=c(async s=>{const o=await n.setLicenseKey(s,{force:true});e(n.getState());return o},[]);const t=c(async()=>{await n.clearLicense();e(n.getState())},[]);return{...i,setLicenseKey:r,clearLicense:t}}export function useTier(){const{tier:i,isInitialized:e}=useLicense();return e?i:"anonymous"}export function useFeatureAccess(i){const{isPro:e,isInitialized:r,isValidating:t}=useLicense();const s=e;const o=!r||t;return{hasAccess:s,isPro:e,isLoading:o}}export function useIsPro(){const{isPro:i,isInitialized:e,tier:r}=useLicense();const t=u(r,a());return e&&i||t}export function useProAccess(){const{isPro:i,isInitialized:e,tier:r}=useLicense();const t=e&&i;const s=u(r,a())&&!t;const o=t?"licensed":s?"weekend":null;return{isPro:t||s,isLicensed:t,isWeekendFree:s,reason:o}}
17
+ */import{useState as d,useEffect as l,useCallback as o}from"react";import{LicenseManager as n}from"./LicenseManager.js";import{useWeekendFreePro as a,weekendPassAppliesTo as u}from"./weekendPro.js";export function useLicense(){const[i,e]=d(n.getState());l(()=>{const s=n.subscribe(r=>{e(n.getState())});n.initialize().then(()=>{e(n.getState())});return s},[]);const c=o(async s=>{const r=await n.setLicenseKey(s,{force:true});e(n.getState());return r},[]);const t=o(async()=>{await n.clearLicense();e(n.getState())},[]);return{...i,setLicenseKey:c,clearLicense:t}}export function useAccountAccess(){return useLicense().access}export function useTier(){const{tier:i,isInitialized:e}=useLicense();return e?i:"free"}export function useFeatureAccess(i){const{isPro:e,isInitialized:c,isValidating:t}=useLicense();const s=e;const r=!c||t;return{hasAccess:s,isPro:e,isLoading:r}}export function useIsPro(){const{isPro:i,isInitialized:e,access:c}=useLicense();const t=u(c.status==="admitted",a());return e&&i||t}export function useProAccess(){const{isPro:i,isInitialized:e,access:c}=useLicense();const t=e&&i;const s=u(c.status==="admitted",a())&&!t;const r=t?"licensed":s?"weekend":null;return{isPro:t||s,isLicensed:t,isWeekendFree:s,reason:r}}