{"_id":"@pixygon/subscription","name":"@pixygon/subscription","description":"Pixygon+ subscription management — shared across all Pixygon apps","license":"MIT","dist-tags":{"latest":"1.8.0"},"versions":{"1.0.0":{"name":"@pixygon/subscription","version":"1.0.0","license":"MIT","_id":"@pixygon/subscription@1.0.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"c25814d592ad2011f66f9afa3b85686176ca05f6","unpackedSize":70277,"fileCount":10,"integrity":"sha512-DYbIVdB1WECdGvGfijWsLS/+XYA6VU4BnoLQCyd+TbOd3i05MCMwxQnYWNwULmByN1z/EgSo78nVua6GknSyIA==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.0.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"}},"gitHead":"bfb32a4129d9bd509df663e9b575be80f5c816e9","scripts":{"dev":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.12.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"25.8.1","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.0.0_1774720862103_0.04910048376117904","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@pixygon/subscription","version":"1.1.0","license":"MIT","_id":"@pixygon/subscription@1.1.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"79e8cf05e7e5566d9f148ad67d92341884b37b8d","unpackedSize":71620,"fileCount":11,"integrity":"sha512-f/zCmh5z3e/QXCBNt39G/DZAFiYoOdQTBGNPcQyP+3arWjxNR6POJo60NaYJfefBzQ9Hn6xP/FuBPx2zQmG5UA==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.1.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"}},"gitHead":"2ccb589000d4f655526869595b0025302cd60440","scripts":{"dev":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.1.0_1784293933547_0.16026390369672416","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@pixygon/subscription","version":"1.2.0","license":"MIT","_id":"@pixygon/subscription@1.2.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"9a33c0b5b4598091273be171b5e447adf8201b62","unpackedSize":71540,"fileCount":11,"integrity":"sha512-HjwZGtQNatOQazc3vPXOjp8q1qFxPWsuE6KEzLrYIQ06xe5U00B7lLsrLO4JEFCy5boVW5905XVGC4aKv1fZJA==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.2.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"}},"gitHead":"91ea4f2872bd239e9ddc344a7df7dd2820dbfda6","scripts":{"dev":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.2.0_1784304855846_0.4890677205411409","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@pixygon/subscription","version":"1.3.0","license":"MIT","_id":"@pixygon/subscription@1.3.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"d49fabdc1e2fe596b46083afa246ff272f5f6d30","unpackedSize":75328,"fileCount":11,"integrity":"sha512-SH7LbaifeqqWXCj1AIXL6F+Qfj/mkG6+FnZqjHP+wHaO6qy4nBfW8kS2CDK/dC69vVRacTBUoaKIbWOEFKWMbg==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.3.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"}},"gitHead":"79dcab074689b4d3626bdc507281fff80a22ebea","scripts":{"dev":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.3.0_1784374200522_0.40194313464918263","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@pixygon/subscription","version":"1.4.0","license":"MIT","_id":"@pixygon/subscription@1.4.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"41e1cd24f43df645ba1cd335f9e1b3136f437a10","unpackedSize":103214,"fileCount":16,"integrity":"sha512-DMBPkNW2x9+cuzsaBKmmDmzTrgLmeKdziiQ/XsZLbzdop2CVHw4Px+tdDEZ8KIrL0BwEXRP2Ax/2uDoZGzaTeg==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.4.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"gitHead":"4cebe3699dd95612cd5cdd34fbd559ff71cc3102","scripts":{"dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.4.0_1784395234701_0.7268739270672944","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@pixygon/subscription","version":"1.5.0","license":"MIT","_id":"@pixygon/subscription@1.5.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"873e75278e6a263c4956ce4dccfb5e01c8fc1325","unpackedSize":104020,"fileCount":16,"integrity":"sha512-0yaIAsXr5prwA0Vy02yqznImrT71AqekGw0zs9gqagipASV57e+Xdyicba6x0h8QEDlJKVNGFmkVurnvKtcepQ==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.5.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"gitHead":"ad56622f693fbbde3c9c3091c805925f28859291","scripts":{"dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.5.0_1784870190237_0.8008728984630546","host":"s3://npm-registry-packages-npm-production"}},"1.5.1":{"name":"@pixygon/subscription","version":"1.5.1","license":"MIT","_id":"@pixygon/subscription@1.5.1","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"a2d75bd7bba4e5de26e2b0bc1d8d863036e2737c","unpackedSize":104212,"fileCount":16,"integrity":"sha512-hj9eVxViHHMEUPi7dcTRm+rYvibXRsxOLmTdZQ4wdtPT+F/S+dLeTDOMLXssD4T2EOcckW2xKwviYfOy1VAv2A==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.5.1.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"gitHead":"bcac5b8c320b26fa110b07013129d7fae1506731","scripts":{"dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.5.1_1784919128905_0.3590977886633462","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@pixygon/subscription","version":"1.6.0","license":"MIT","_id":"@pixygon/subscription@1.6.0","maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"dist":{"shasum":"12b3b3576d197c659601ab264ae8040c91c42fd8","unpackedSize":111452,"fileCount":16,"integrity":"sha512-SBnM7vk75BSyQg68CQmWIjhuGzyVrXxoKUZqFheb75QW+aiSIdNjti8Fe1nR1Es5Ei0ncFbMDWdtM5wUUxlrlw==","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.6.0.tgz"},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"gitHead":"bcac5b8c320b26fa110b07013129d7fae1506731","scripts":{"dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","typecheck":"tsc --noEmit"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"_npmVersion":"11.16.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","directories":{},"_nodeVersion":"26.2.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.3.0","@types/react":"^18.2.0","@pixygon/auth":"file:../@pixygon/auth","@types/react-dom":"^18.2.0"},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/subscription_1.6.0_1784927568623_0.29135963098252593","host":"s3://npm-registry-packages-npm-production"}},"1.6.1":{"name":"@pixygon/subscription","version":"1.6.1","description":"Pixygon+ subscription management — shared across all Pixygon apps","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"devDependencies":{"@pixygon/auth":"file:../@pixygon/auth","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","react":"^18.2.0","react-dom":"^18.2.0","tsup":"^8.0.0","typescript":"^5.3.0"},"scripts":{"build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","typecheck":"tsc --noEmit"},"license":"MIT","gitHead":"b4fe9ab4ff3105766ada4a8d2459f59407f61cec","_id":"@pixygon/subscription@1.6.1","_nodeVersion":"26.2.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-eeA5B8bUwDl1d21ARmwDJaQWtUzqvVHgi9XbWjWWCdpmHM24t/jdc4jfxmoFrJQGQgj8mYDJmeA2V3LF219dAg==","shasum":"d685d6ccb358961c1c16b8eec5e56ae69499c4aa","unpackedSize":111442,"fileCount":16,"tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.6.1.tgz"},"_npmUser":{"name":"imakestupidgames","email":"anders@pixygon.io"},"directories":{},"maintainers":[{"name":"imakestupidgames","email":"anders@pixygon.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/subscription_1.6.1_1784989958735_0.4352292931365196"},"_hasShrinkwrap":false},"1.7.0":{"name":"@pixygon/subscription","version":"1.7.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"devDependencies":{"@pixygon/auth":"file:../@pixygon/auth","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","react":"^18.2.0","react-dom":"^18.2.0","tsup":"^8.0.0","typescript":"^5.3.0"},"scripts":{"build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","typecheck":"tsc --noEmit","verify":"node verify.mjs"},"files":["dist","src","verify.mjs"],"license":"MIT","bin":{"pixygon-verify-subscription":"verify.mjs"},"dist":{"integrity":"sha512-VcKRXUnyhEq7h0apFkANrpS3Et4PvNbJPowyzdIrEa2bjid3EQLzUjtwyZmQ+AhsYc7de3+RwphxLHuSkU7u6Q==","shasum":"8e51ad8318a895797d3a5e52b8a673cdba4c78a7","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.7.0.tgz"},"readmeFilename":"README.md","_id":"@pixygon/subscription@1.7.0","_integrity":"sha512-VcKRXUnyhEq7h0apFkANrpS3Et4PvNbJPowyzdIrEa2bjid3EQLzUjtwyZmQ+AhsYc7de3+RwphxLHuSkU7u6Q==","_resolved":"/home/pixygon/handoff/npm-stage-2026-09-30-raptor3/pixygon-subscription-1.7.0.tgz","_from":"file:pixygon-subscription-1.7.0.tgz","_nodeVersion":"26.10.0","_npmVersion":"12.1.0"},"1.8.0":{"name":"@pixygon/subscription","version":"1.8.0","description":"Pixygon+ subscription management — shared across all Pixygon apps","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./pages":{"types":"./dist/pages/index.d.ts","import":"./dist/pages/index.mjs","require":"./dist/pages/index.js"},"./upsell":{"types":"./dist/upsell/index.d.ts","import":"./dist/upsell/index.mjs","require":"./dist/upsell/index.js"}},"peerDependencies":{"react":">=17.0.0","react-dom":">=17.0.0","@pixygon/auth":">=1.0.0"},"devDependencies":{"@pixygon/auth":"file:../@pixygon/auth","@types/react":"^18.2.0","@types/react-dom":"^18.2.0","react":"^18.2.0","react-dom":"^18.2.0","tsup":"^8.0.0","typescript":"^5.3.0"},"scripts":{"build":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --clean","dev":"tsup src/index.ts src/pages/index.ts src/upsell/index.ts --format cjs,esm --dts --watch","typecheck":"tsc --noEmit","verify":"node verify.mjs","test":"node --test test/*.test.mjs"},"files":["dist","src","verify.mjs"],"license":"MIT","bin":{"pixygon-verify-subscription":"verify.mjs"},"dist":{"integrity":"sha512-pEcw+QzUeVdQ36uL2kNypW504sBrHCcSX7Laxi8a/WoZ4VvgO/mybI02PsjTSNBz+3iCHs8tmYp7yd8RoXKXhg==","shasum":"2eac9eb250f661f855cd1b3cd3bc7904142f6a11","tarball":"https://ppm.pixygon.io/@pixygon/subscription/-/subscription-1.8.0.tgz"},"readmeFilename":"README.md","gitHead":"73ff464191e315e7dbaf3c81347cff3666c76cc7","_id":"@pixygon/subscription@1.8.0","_nodeVersion":"26.10.0","_npmVersion":"12.1.0"}},"time":{"1.0.0":"2026-03-28T18:01:02.248Z","modified":"2026-10-01T11:19:59.402Z","created":"2026-03-28T18:01:02.248Z","1.1.0":"2026-07-17T13:12:13.683Z","1.2.0":"2026-07-17T16:14:16.000Z","1.3.0":"2026-07-18T11:30:00.669Z","1.4.0":"2026-07-18T17:20:34.838Z","1.5.0":"2026-07-24T05:16:30.366Z","1.5.1":"2026-07-24T18:52:09.103Z","1.6.0":"2026-07-24T21:12:48.769Z","1.6.1":"2026-07-25T14:32:38.885Z","1.7.0":"2026-09-30T23:31:30.678Z","1.8.0":"2026-10-01T11:19:59.402Z"},"readme":"# @pixygon/subscription\n\nPixygon+ for every app — tier detection, per-app feature gates, hosted Stripe\ncheckout, billing portal, and the upsell growth loop. **7 repos** depend on it\n(Tastebud, Kartograf, CoreFeed, SoloBattle, pixygon.io, pixiel.ai, lonnlyst.no).\n\nOne Pixygon+ subscription unlocks the tier everywhere; each app decides what\n\"Plus\" *means* for it via its own `AppFeatureConfig`.\n\n⚠ This is **money code**. Static checks are not enough — see \"Verify\".\n\n---\n\n## Retrofitting it into an existing app (≈20 minutes)\n\n### 1. Install\n\n```bash\nnpm i @pixygon/subscription\n```\n\n`@pixygon/auth` is a **peer dependency** — the provider needs its access token\nand the user's tier. Install and mount auth first.\n\n### 2. Define what Plus means here\n\n```ts\nimport type { AppFeatureConfig } from '@pixygon/subscription'\n\nconst APP_FEATURES: AppFeatureConfig = {\n  appId: 'tastebud',          // lowercase app slug (also picks the /plus page palette)\n  features: {\n    // boolean = on/off · number = limit (-1 unlimited, 0 disabled)\n    aiRecommendations: { free: true,  plus: true },\n    aiWrapped:         { free: false, plus: true },\n    customPins:        { free: 3,     plus: -1   },\n  },\n}\n```\n\nGate the things that actually cost money (unmetered AI calls, storage), not\nthe top-of-funnel. If the **server** grants a free daily allowance, mirror it\nwith `free: true` — a client that hard-gates at zero while the server allows\nthree contradicts itself and kills the funnel.\n\n`family` is deprecated (the family plan was removed); it is still accepted for\nback-compat and resolves to the same as `plus`.\n\n### 3. Mount the provider — inside AuthProvider\n\n```tsx\n// src/providers/PixygonPlusProvider.tsx  — the estate pattern\nimport { SubscriptionProvider } from '@pixygon/subscription'\nimport { useToken, useUser } from '@pixygon/auth'\n\nfunction SubscriptionBridge({ children }: { children: ReactNode }) {\n  const { accessToken } = useToken()\n  const { subscriptionTier } = useUser()\n  return (\n    <SubscriptionProvider\n      config={{ features: APP_FEATURES }}\n      accessToken={accessToken}\n      userTier={subscriptionTier || undefined}\n    >\n      {children}\n    </SubscriptionProvider>\n  )\n}\n```\n\n⚠ **`accessToken` is not optional in practice.** Without it the provider never\nfetches the real subscription and `startCheckout()` throws *\"Not\nauthenticated\"* — that exact bug shipped in five apps at once. `userTier` is\nthe fast path so gates don't flicker to `free` while the API responds.\n\n### 4. Gate features\n\n```tsx\nimport { useSubscription, FeatureGate, PlusGate, UpgradePrompt, SubscriptionBadge } from '@pixygon/subscription'\n\nconst { tier, isPlus, canUse, getLimit, startCheckout, openPortal, cancelSubscription } = useSubscription()\n\nif (!canUse('aiWrapped')) return <UpgradePrompt />\nconst pinLimit = getLimit('customPins')      // 3 free, -1 plus\n\n<FeatureGate feature=\"aiWrapped\" fallback={<UpgradePrompt />}>\n  <WrappedReport />\n</FeatureGate>\n```\n\n### 5. Give people a way to buy\n\n```tsx\nimport { PixygonPlusPage } from '@pixygon/subscription/pages'\n\n<Route path=\"/plus\" element={<PixygonPlusPage currentApp=\"tastebud\" />} />\n```\n\nThe page adopts the host app's palette from `currentApp`, lists the live tiers\nfrom `GET /v1/stripe/pixygon-plus/tiers`, and calls `startCheckout` →\n**hosted Stripe Checkout** (redirect to `response.url`). Gates without a\n`/plus` route is a dead paywall.\n\n### 6. Wire the upsell loop (optional but this is the growth part)\n\n```tsx\nimport { PlusUpsellProvider, usePlusUpsell, handleUpgradeRequired } from '@pixygon/subscription/upsell'\n\n<PlusUpsellProvider\n  currentApp=\"tastebud\"\n  onEvent={(name, props) => track(name, props)}   // → @pixygon/analytics\n  onUpgrade={() => navigate('/plus')}\n>\n  <App />\n</PlusUpsellProvider>\n\n// data layer: turn a server 402 into the modal\nif (handleUpgradeRequired(error)) return\n// component: trigger it directly\nconst { showUpsell } = usePlusUpsell()\nshowUpsell({ feature: 'aiRecommendations', freeLimit: 3, used: 3 })\n```\n\n### 7. Verify it worked\n\n```bash\nnode node_modules/@pixygon/subscription/verify.mjs\n# or:\npearl verify subscription\n```\n\nChecks: package + `@pixygon/auth` installed, `<SubscriptionProvider>` mounted,\n**`accessToken` prop wired**, a real `AppFeatureConfig` (non-placeholder\n`appId`, non-empty `features`), an API base that isn't localhost, something\nactually gated, and a purchase path present. Exit 0 pass, 1 fail.\n\nAdd a live probe of the public pricing endpoint (no auth, no money):\n\n```bash\nnode node_modules/@pixygon/subscription/verify.mjs --url=https://api.pixygon.com/v1\n```\n\n**What verify cannot prove — and this matters here:** that a purchase\ncompletes. It never touches Stripe. Before trusting a subscription change,\nrun a real test checkout end to end (checkout → webhook → tier flips → gate\nopens) and confirm the app's Stripe env vars/price ids exist for *this* app.\nA solo \"looks fine\" sweep on money code has been overturned before.\n\n---\n\n## API\n\n| Export | From | Use |\n|---|---|---|\n| `<SubscriptionProvider config accessToken userTier>` | `.` | the mount |\n| `useSubscription()` | `.` | `tier, isPlus, subscription, isLoading, error, canUse, getLimit, getFeature, startCheckout, openPortal, cancelSubscription, reactivateSubscription, refetch` |\n| `<FeatureGate feature fallback>` / `<PlusGate>` | `.` | declarative gates |\n| `<UpgradePrompt>` / `<SubscriptionBadge>` | `.` | upsell UI bits |\n| `<PixygonPlusPage currentApp>` | `/pages` | the whole pricing page |\n| `<PlusUpsellProvider>`, `usePlusUpsell()`, `handleUpgradeRequired()`, `isUpgradeRequired()`, `triggerPlusUpsell()`, `subscribePlusUpsell()` | `/upsell` | the 402 → modal → /plus loop |\n| `SubscriptionApi` | `.` | imperative client (`/stripe/pixygon-plus/*`) |\n\n### Endpoints it calls\n\n```\nGET  /v1/stripe/pixygon-plus/tiers          (public)\nGET  /v1/stripe/pixygon-plus/subscription   (bearer)\nPOST /v1/stripe/pixygon-plus/checkout       (bearer) → { url } hosted checkout\nPOST /v1/stripe/pixygon-plus/portal|cancel|reactivate\n```\n\nDefault base `https://api.pixygon.com/v1`; override with `config.apiUrl`.\n\n## Gotchas\n\n- **No `accessToken` → \"Not authenticated\" on checkout.** The single most\n  common wiring bug in this pearl.\n- **Tier mapping is generous.** `plus`, `family`, `premium`, `pro`, `basic`,\n  `enterprise` all resolve to `plus`; anything unknown resolves to `free`.\n- **Gates without a `/plus` route** = users hit a wall with no door.\n- **Client gates are UX, not security.** The server must enforce the same\n  limits; the client gate only decides what to show.\n- **Don't invent per-app prices in the UI.** Read them from the tiers\n  endpoint — hard-coded prices have gone stale and misled users before.\n\n## Publishing\n\n```bash\nnpm run build && npm publish --access public\n```\n","readmeFilename":"README.md"}