{"_id":"@nitida/sdk","_rev":"35-c9bd832f127318d0d4714afae4d77e36","name":"@nitida/sdk","dist-tags":{"latest":"0.36.3"},"versions":{"0.20.0":{"name":"@nitida/sdk","version":"0.20.0","keywords":["aquienpz","asset-management","cdn","cloudinary-alternative","multi-tenant","r2","cloudflare"],"license":"UNLICENSED","_id":"@nitida/sdk@0.20.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://github.com/espaciofuturoio/aquienpz/tree/main/packages/sdk","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"d68ffdfd60d6266b7d2187f7a16caec1787a0b79","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.20.0.tgz","fileCount":28,"integrity":"sha512-8sjNYsX8mLYVZ+iB/Ju+UHN0xu5lGu6hpSzM6hyvG65qtCsqvz30mxTJ6S4arlY84ZwK7gNT+1oBnyi7KjoY4Q==","signatures":[{"sig":"MEYCIQCsHE0lQLjOn2Gb3zRWBEKQc0WpFfiHRvwYBWR762w2swIhAKoPwyIQrHylDFKSRRNuywqdQ9wnBRWBffyQt/hm8jS7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":560950},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"5d43f73929cf06d2cc14694bfd212cd9c371a912","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.17.0","description":"Universal SDK for the aquienpz multi-tenant asset platform. Cloudinary-style asset management with slot bindings, presets, and Better Auth API keys.","directories":{},"sideEffects":false,"_nodeVersion":"26.4.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependenciesMeta":{"react":{"optional":true},"@aquienpz/asset-uploader-web":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@aquienpz/asset-uploader-expo":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.20.0_1786923347115_0.9122404492037433","host":"s3://npm-registry-packages-npm-production"}},"0.20.1":{"name":"@nitida/sdk","version":"0.20.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.20.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"cfd9e538d3abf02d593f169bdb3c571eea90a465","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.20.1.tgz","fileCount":28,"integrity":"sha512-eHlenilr/uYvPuNQMBa4/95ZeKKtfdQ7ASirw+3STSHCjvLe5Gntc7cX/INIkC+cvfS7DbUpFcUA5du4YTtUJA==","signatures":[{"sig":"MEQCIAWsoFBYbzuumvUMb2UNHNqXkNFdYo0nob83+bYRNq3BAiA14MNVgx1mk9NqekW9dsc1yfHMeeKQ195t9RTFvmDfMQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":561027},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"6c8684bdd60325f35c4a0488e85abc611c95e174","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.17.0","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"26.4.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependenciesMeta":{"react":{"optional":true},"@aquienpz/asset-uploader-web":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@aquienpz/asset-uploader-expo":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.20.1_1786923725506_0.6618105061253634","host":"s3://npm-registry-packages-npm-production"}},"0.21.0":{"name":"@nitida/sdk","version":"0.21.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.21.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"6a1b5ab10f6167133bca3a5df4452d9469605b8a","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.21.0.tgz","fileCount":28,"integrity":"sha512-kEtZ9K5+m6G+9uB5D4XoY7ETUfjovYLSWG3DLNsTjasul0XAdiW7xfakcJyE7Xt/ZaCE+F7fNXLOJ1z18Xlzjw==","signatures":[{"sig":"MEYCIQDfCjba3BSFbdLqT6pC4hlqRFcJ3YU9jN6xqBmIwcZplgIhAPyWYhMMQ7g8G9G6xdPMberKiz7Bd+kaJC3A8cjOXS0y","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":566760},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"1728923ea64068c25996bc3f545c36fdc3fe52e7","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.17.0","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"26.4.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependenciesMeta":{"react":{"optional":true},"@aquienpz/asset-uploader-web":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@aquienpz/asset-uploader-expo":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.21.0_1786925315092_0.10764434594751715","host":"s3://npm-registry-packages-npm-production"}},"0.22.0":{"name":"@nitida/sdk","version":"0.22.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.22.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"8bf75ef1cc9a934ff75c98c2d7d059b910bb81c6","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.22.0.tgz","fileCount":28,"integrity":"sha512-Pd5Z5j4xpmn5UiElyB+UIIMa5WvPCLkRrP60oRWyXkA0e/ivDOmeKjp1gJKJL/4Q5QhuLNOKBX/bNqx/vexDtw==","signatures":[{"sig":"MEUCIQCppKorh5giv4HBQifh4pSKBzNl9ZN1S4EwPlO6Z3yIIwIgPVP3neytt1dl+OLxL2o02AJn9ijga3fB184uc9zf2P0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":565168},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"7e582c8d1343cd87bf640b1938274a8f455e7e0b","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"11.17.0","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"26.4.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependenciesMeta":{"react":{"optional":true},"@aquienpz/asset-uploader-web":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@aquienpz/asset-uploader-expo":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.22.0_1786926444548_0.13745341846876302","host":"s3://npm-registry-packages-npm-production"}},"0.23.0":{"name":"@nitida/sdk","version":"0.23.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.23.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"8823a36c4c1f933706664c10ec6bb05a11de4b82","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.23.0.tgz","fileCount":28,"integrity":"sha512-Z9sXeza9Mr8Ma9Qhth73ODz8A2vrB3KC1JMrvQ5so1+1TQRh71aXE5gNtfwO5voCEjnzi8/2uBufON1puLBebg==","signatures":[{"sig":"MEUCIFR+rEhSq9GU7FnbPaRPTsbvUhyXCW9Unj4QhamPhZzyAiEAorolgcXZRWvDIgcp6pny2xQUarNZiV02/CBIHdWseE0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":573309},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"648d3f745332f52623e79bd8b64bdbb094263ce6","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.15.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.23.0_1786951454615_0.24365767477560163","host":"s3://npm-registry-packages-npm-production"}},"0.24.0":{"name":"@nitida/sdk","version":"0.24.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.24.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"1e7caefd7c802c025091d3aa42cb273ba6181a0a","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.24.0.tgz","fileCount":28,"integrity":"sha512-oR09/chnDEIrUDj2L+tFC5HYuU4t9I8iNVrO4GSfQpPnhFgVOCLv3aYIp6Ur/YZqHRmVINftDaOiLFJwFSZzXA==","signatures":[{"sig":"MEUCIHz+AXIoRZf4ZwEM6pjk91MQiAuUrfT7/nasRDcMjryjAiEA2BKziizWbk6KO6n/yUEC2NoJ61P15qBCXjdrQIePWFE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":573309},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"eb2be8b2bdacea72692d7a300766a186c72d4f6e","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.16.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.24.0_1786952473741_0.6706909369081946","host":"s3://npm-registry-packages-npm-production"}},"0.24.1":{"name":"@nitida/sdk","version":"0.24.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.24.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"cc288db906999c871bfcce2042a64857afd135b2","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.24.1.tgz","fileCount":28,"integrity":"sha512-NNa+7GSCZBjLuQgh7B3b4J7JtGW3CDAxspDja2okQqyqW+n+uKwWJdLaLribxH07V9VZYU8KUAbI3bmuvhuU4g==","signatures":[{"sig":"MEUCIQCXMx4AoTAyRkf41QzwagcoWB0E6UKmseqUvB3xCpSW3QIgZeWT5Yk1C6hmD6mx/abRdXZvq6uPkSTQoUjYD8PInLg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":587434},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"6d9a31fa3075eb9b3da70753a386305e2310a779","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.16.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.24.1_1787118007806_0.2921093863732791","host":"s3://npm-registry-packages-npm-production"}},"0.25.0":{"name":"@nitida/sdk","version":"0.25.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.25.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"264860f268e46cbdf5f4e2027a82dc07bd8b921a","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.25.0.tgz","fileCount":28,"integrity":"sha512-3O9lt5fEst1xB6KYv/wsE+WUSc8MfhMb8zdgGrfyB3LywMJ0c7bIdw025gDEmZ9blsGH2wTUa3KNIqIIVtD3ng==","signatures":[{"sig":"MEUCIGgCN2rRHsBRm3TvPS9qJvKP7mj3CSfj0ZCpgtcgEFu5AiEAhVRwZ34HPcb1EXd0pR75KleF3ZM0GdTvs+KPhdZxj08=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":594872},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"9c8499416d7a65297e90396b95d3653cd6ebdd07","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.16.3","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.25.0_1787256347547_0.4118197922570448","host":"s3://npm-registry-packages-npm-production"}},"0.25.1":{"name":"@nitida/sdk","version":"0.25.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.25.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"3bae02b88bdec368e7e850be292fed2fc59038d1","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.25.1.tgz","fileCount":28,"integrity":"sha512-dvU9D2t2lKXgh6/D5l/cIXOTMRSP4YAOe3N5ER7buVHcftzUYG0ZKbdVDm5e4IL4+OfqU0tpbTLzee6yksFz7w==","signatures":[{"sig":"MEUCIQD5cKNzodV8QL/Qo4bvbW/jOY4T700kMy86HfhB12URxQIgKLtwi1q96toSR/cp8+LZYWScnXc40/tB2PX/h4rDGSc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":595135},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"5494987689e7bdd56e21e3f70902e03e714cb1a9","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.16.3","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.25.1_1787256872547_0.3537478850172977","host":"s3://npm-registry-packages-npm-production"}},"0.25.2":{"name":"@nitida/sdk","version":"0.25.2","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.25.2","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://github.com/espaciofuturoio/aquienpz/issues"},"dist":{"shasum":"c24aab1ef5fb6489279ac7157bc74c2110900528","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.25.2.tgz","fileCount":28,"integrity":"sha512-dOSyObLWaHjZq8Iv6M3gv4ZYJi9sRsjEqYrKqla0NdrifU5Fkap4w/JtxVQBgHKAS4hBP6LPTqGNuBVXG/ETgA==","signatures":[{"sig":"MEQCIAxpFbakNzbuX9SFV4Z3RKAMR4uT9OaLvlQj0ae94HX6AiA9i6RkKJYLjlcvGrbTWL4yArrwVsz3BND8pt1PCAKMFQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":595170},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"14a18c0b21d0766bbdfce1adcab3fbd14143bf4d","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.16.3","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.25.2_1787257173302_0.15435400445487435","host":"s3://npm-registry-packages-npm-production"}},"0.25.3":{"name":"@nitida/sdk","version":"0.25.3","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.25.3","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"5e0d3edb4bf79f32f6860f3621974911c0b81630","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.25.3.tgz","fileCount":28,"integrity":"sha512-NIP5mJ+VHvltfv1eiqShn4ZDl3eAa1cU7vUHGw64PqQp5onu0ve1hI9VmlC+Vufy//hTV028QdulTIyh7V02xQ==","signatures":[{"sig":"MEYCIQC+NryMZM3hYLPN1jrGTFGAsxNaJxZHecEeJq8cgATXDAIhAKzqboLq3Y897+UAblLMHqhptJkopm9Uv4f8lPC3QkY4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":595320},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"fd30c208148b99111baccd9e2530f30c522fb057","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"repository":{"url":"git+https://github.com/espaciofuturoio/aquienpz.git","type":"git","directory":"packages/sdk"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.16.4","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.25.3_1787258170205_0.46877026154392","host":"s3://npm-registry-packages-npm-production"}},"0.26.0":{"name":"@nitida/sdk","version":"0.26.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.26.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"4b919faebe3006988ade188235e210c6f960b635","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.26.0.tgz","fileCount":28,"integrity":"sha512-RtOvgIKEjFmubrO3uAQNDJn8fuKPubElHmVkq1jGgeF37nJ8xTnhzLnclJJaqlvLfNDf1pvxP/XOpHHDeeZNKw==","signatures":[{"sig":"MEUCIQDSszzUq+xCP/MmzZwoLc5iFpoE6WFSSc1d5TNI3tkZoAIgX9uHkZTlzS8N7hwthR1K33UAoKkEQMq+D77XKaaxmwU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":624604},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"e3e55bffc8b0c6771f316a527d596c31b43dfa4b","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.17.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.26.0_1787371492637_0.8871518585755713","host":"s3://npm-registry-packages-npm-production"}},"0.27.0":{"name":"@nitida/sdk","version":"0.27.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.27.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"1471c1500849c8e2c10ca27f9d54026bccc26fda","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.27.0.tgz","fileCount":29,"integrity":"sha512-JCXlAHM4wFJwUYYzfw1WtILx4G29HEwdKUG+AoZBQcQsXRLQ5+pF2TqYK4EYZhQ0zlo3TZpU/8sVnTS9LVqeXg==","signatures":[{"sig":"MEYCIQC16vecRDzH+CGOGQto9bSWbznocwnwNhoE16HfINdJFgIhAOY24GaPyHDB8+iHb5nEHCqkDtEkhcc5iU2FZbYVSKXD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":663419},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"7db9992c6e4865a087cdfd772fed33738456d942","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.18.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.27.0_1787457004544_0.7686756874064198","host":"s3://npm-registry-packages-npm-production"}},"0.27.1":{"name":"@nitida/sdk","version":"0.27.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.27.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"93333e7475bf331173e621225e05545d44584efc","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.27.1.tgz","fileCount":29,"integrity":"sha512-gSRWE+4X6W+IpDZaHYySTrtfrk4QoCdk6Aq1/B3rMaYw1ROyaGST52nsBuP0ExYDobI+f8mBiZQfu4D34TWtBA==","signatures":[{"sig":"MEUCIC9WkZCoRujmx6r8uuWvZ1iV1PW+vRrCKlLi2pRKNy5fAiEA3jkNF0JjPGTiT+F/QeOIesqmyIskXX+YoiS4YFFSEco=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":669501},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"c9e1cd8a63670b337aa3529f7ae4e1b1f73d5198","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.18.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.27.1_1787521099826_0.27815309300742874","host":"s3://npm-registry-packages-npm-production"}},"0.28.0":{"name":"@nitida/sdk","version":"0.28.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"license":"UNLICENSED","_id":"@nitida/sdk@0.28.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"b99841b77d005e546c09a022437232eb7be70877","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.28.0.tgz","fileCount":29,"integrity":"sha512-nMnsy88oj5H7mRGKVBOo1ozI/AeyQFZQzyyawGvUWTn8SwLDxAWvM/7qiBLUWi2z0qG7e2aQcKXlZd3/jmXJmA==","signatures":[{"sig":"MEUCIFb1MdpxCL3+ASVSHgnk85YJAiABubPd0H/Vbx6S5pMeAiEAvbydyxKv47ktBQB0HoxGafKBMuWaxObAlIsX6NdhUfY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":683883},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"06bae2051b04341fe2751bfa378d94b9f4647554","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@aquienpz/asset-uploader-web":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@aquienpz/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.19.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.28.0_1787534271553_0.7575267054143406","host":"s3://npm-registry-packages-npm-production"}},"0.29.0":{"name":"@nitida/sdk","version":"0.29.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.29.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"59bac6fb0d4f7db0877952befe2e7f662c487ce7","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.29.0.tgz","fileCount":31,"integrity":"sha512-PLGSmVfZbb+aeqfrp81rxZ87YRd0WButCWIoNuOka2pT8BOrOlhYXu8QUrKVE+/1J7XWWa1ALwMzVdikLX/wlw==","signatures":[{"sig":"MEUCID87R+7iXllAwbjvtqjpiFD0usGUfEqCmDbX1INglWK+AiEAz4w/zthRHRszm/LdQNSdofIfCUWB6lwhfPNMT1h8A1w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":701139},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"77db8c59a9e0251b952f4d054b3adae04469d4d9","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.19.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.29.0_1787542587128_0.8250867471569336","host":"s3://npm-registry-packages-npm-production"}},"0.30.0":{"name":"@nitida/sdk","version":"0.30.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.30.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"5829e6de70340c6e7d395fa311a7b71acff990e2","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.30.0.tgz","fileCount":31,"integrity":"sha512-2/XGe1mTGv86Pom4ntpL7BjNvIOfhbdTNXhaATjvgGvFSJkkyvf09KXnSBCZGmw4915stA5ycoWV92bj8r5x5g==","signatures":[{"sig":"MEQCIFEFfLHWnAsYYy4g2WGlOz0MZS1p3QLrIpyW/N/zZfNNAiBxr49cpaKuXLL0TRurQYnpzxRl+t4oMC8wyyf5wSx+0Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":709871},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"307744adc4a3924cc928cb891625abb1baeb59d5","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.19.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.30.0_1787548812858_0.8582787978246424","host":"s3://npm-registry-packages-npm-production"}},"0.30.1":{"name":"@nitida/sdk","version":"0.30.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.30.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"d1e7997c91bd23c04314a4b90f17429269fd6506","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.30.1.tgz","fileCount":31,"integrity":"sha512-7n9FrCprlwI/MnKhVe5LiZLvAVjB4NU2yGene9O0JZ8q2y1KzrWJGieU518bsWmOGxj6lq2VpMrk04XoGYaFuw==","signatures":[{"sig":"MEUCIQCqOUd9OM6iIfe1jhHmVJl9oKThjMPw/z4QUvz1GXMEWwIgCjZYKGDuP43QFqsmFgqt6nQWLcsIUl8Sm1OzlmqvklE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":722703},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"831a776615699065e71df443e8a0fd4c78b47e3d","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.19.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.30.1_1787586416018_0.07152027219068335","host":"s3://npm-registry-packages-npm-production"}},"0.30.2":{"name":"@nitida/sdk","version":"0.30.2","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.30.2","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"a52da86e98648ec79f6b9812ecf26e056b9a9204","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.30.2.tgz","fileCount":31,"integrity":"sha512-OTQAzydJBE5H6WvVk8xalEfOCMU5iYIwO09LD7QMMISJYpmGZmjpdp0RRTODVnR4qNruwaYHe9vcr3brMokIAg==","signatures":[{"sig":"MEUCIQCoJ7wT0jvRZSovphVkYnlD1pPAB/L0NckT1KowVHnS/QIgHUM6qefwk06NOz/5prt23UcpHgyf/mdtXzALVVa/zHU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":723353},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"5331eb9e608c379ba09828b3753c1814c9ce42f7","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.19.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.30.2_1787588905630_0.7841154861469681","host":"s3://npm-registry-packages-npm-production"}},"0.31.0":{"name":"@nitida/sdk","version":"0.31.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.31.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"846c53eb487a3e4b8f1e8cb6d4b7015838f11d81","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.31.0.tgz","fileCount":31,"integrity":"sha512-dzeWvJiiI9urLAyBmPyCBzoh6EaezYUxFhiOcguPoOIpeDtytlS4zrzGmzGXAcUvvD6dOo554V9+pQia4jeqsA==","signatures":[{"sig":"MEYCIQDryRlPeDBb0fwQ5oaw4V3ZzneTPNV/NCwFGAkUeU+O6AIhAN+4IGYxBTgXnQt7eqalJOLBPDPCvuATZWQFdlhWvlWM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":724646},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"799969f9c108be3c7538bb010cf4a1f1fb95102b","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.31.0_1787596566350_0.8035644421441106","host":"s3://npm-registry-packages-npm-production"}},"0.31.1":{"name":"@nitida/sdk","version":"0.31.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.31.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"886869fbc7b4d59e0ef31b668ba8554ee286a2dc","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.31.1.tgz","fileCount":31,"integrity":"sha512-Eg9IKNu6upcXUwWMAHzXqm6CwUtCLwqu2r6m0lKe0sXXxCMofk+MV2z9+p/vRBsOGmWnj6rtruhnJwjod5nG1A==","signatures":[{"sig":"MEUCIG0ziB8ZyrJm8BhbNPmfcDwTujrjLhwYr7qg6JjJVbuQAiEAzdVHcL0c9Ge45H6DQwwC9vHrB/Vo448PHNDpbQwIGfI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":724758},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"cd6cfc9e75e91937cf3e0f1f05acff9d7d40de13","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.31.1_1787597839984_0.003535044970493395","host":"s3://npm-registry-packages-npm-production"}},"0.31.4":{"name":"@nitida/sdk","version":"0.31.4","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.31.4","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"d793e7372b0db5cde067278e14bf70b63d2543c1","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.31.4.tgz","fileCount":31,"integrity":"sha512-oKusuEQnJyNPCh85JlTgyaGs2RlmO5oYiWxOSsEoQUo3Yt2C0TjlY9Rd2H3//pYS3xLLRjdc5CtiX9eimJUjtQ==","signatures":[{"sig":"MEQCIHLL2zcTu6ICzqyoQ9cE9k+ebVFTm1nsQS5XjzNtZsYyAiAjnlyb5DkeqmP2SjjMIU20gQIv6Y2UBR3pOLvCgUc4Fw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":743674},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"664555934f3e2690c531f0c2e2a40d88b736738a","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.2","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.31.4_1787602107342_0.4195106994656508","host":"s3://npm-registry-packages-npm-production"}},"0.31.5":{"name":"@nitida/sdk","version":"0.31.5","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.31.5","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"f2cdc25215de9a269fbc6d36afed12e3e8576a6e","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.31.5.tgz","fileCount":31,"integrity":"sha512-3dvdzQY7Iblfy7+nSJC5x2G0h9ZohVPC920/ac1frWKwv3CghfQ9XUV1Efc6tvtZUwT8js1+r5nJlwSgSMmQig==","signatures":[{"sig":"MEUCIGCEkDOcl5v8CNqR5cNBUYU0VaDxfXbHXMxeaT5FGhuLAiEAitG+BB1pDjVUjlHThqrTKlmCgHf3W265iiWYzsuRWO4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":745472},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"d85b48a90a1da5ba0d6a4361dadd856b371c18f0","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.2","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.31.5_1787616236766_0.11927591450513741","host":"s3://npm-registry-packages-npm-production"}},"0.31.6":{"name":"@nitida/sdk","version":"0.31.6","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.31.6","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"7b2aa724f88fdba2d6b2293deeb0810c6449a2dc","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.31.6.tgz","fileCount":31,"integrity":"sha512-5ECQ8RNf11fEqQ4JB3GcXkveuhfHwPvrxUbSia2OWnE4UCl8nxpmp5SqHOi2HPpgc7ZSVyWjKy4enTbwqhMtZw==","signatures":[{"sig":"MEQCIEvLHfS219nhpasjQBLHwb09ryjhlg8yAf+oOGp5sVb+AiBy64wPF7l0fusjpojmYhBk2DstexSOC+abId9T/Lw7OQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":745678},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"0b6d4db82986e213b55ad03fa02f591789e80137","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.2","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.31.6_1787619761378_0.2949540888517692","host":"s3://npm-registry-packages-npm-production"}},"0.31.7":{"name":"@nitida/sdk","version":"0.31.7","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.31.7","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"23fee086068fc4189902cb9975d99c0d805d9c9a","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.31.7.tgz","fileCount":31,"integrity":"sha512-xyW+KDi3uh+Wlj0QKd1XkoAbrUVwLk0+hsXsWlboBQUkI2l+QEsjOL7nvajMt375CTwGdFOs3Zp8yl+z6H+wlg==","signatures":[{"sig":"MEUCIQCxZeIej6Xct/JtsL1pQa46o4r2EiihEdHE4BhrHu1vFQIgMqriRv1PQ+ZD5kZfpYAyUEd/Z3aSFExB64ArR0KyCKM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":749435},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"f2f5f5994bcd5ec74b3e7e85ef59eb7d4d3655cc","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.2","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.31.7_1787625638114_0.8755389138785783","host":"s3://npm-registry-packages-npm-production"}},"0.32.0":{"name":"@nitida/sdk","version":"0.32.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.32.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"c5299160c923ab8d8aa8594a448d4ebab3b39b93","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.32.0.tgz","fileCount":31,"integrity":"sha512-ngbopkEcYVtSZjVpoxfuM/rFevEvn6whk+7bvZq2+lcrHfu3uc7KYufgI3L/eVl1mXkaNU6zVM0yDLKjXyueOQ==","signatures":[{"sig":"MEYCIQCg5fzIIEKXyCJsFsQQIqB7uuK8BLoR8L7oHx1B/kmOcQIhAJg189ypBG/lbB9SlWFCxCDEr65Q0DGf+3eXsH3l83wZ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":762647},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"c02357d607dc1c7be38a8f26d4e98328e2adac3e","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.2","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.32.0_1787627789926_0.08447730764265882","host":"s3://npm-registry-packages-npm-production"}},"0.32.1":{"name":"@nitida/sdk","version":"0.32.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.32.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"30e8d864164283e9b5fae52c9794b547171d3623","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.32.1.tgz","fileCount":31,"integrity":"sha512-to5PliMztE64b0ypB3eggOdze/fTtq7xxK0mtPiNCogrwW6hhamJhxPAKq2YrTBWAJxVUKUfiDyyRS4vcSYjoQ==","signatures":[{"sig":"MEYCIQCBrKt0FVFE3D+z6bMshI1NSAiTcREJYnvwvq/zyfyDvwIhALwq5KSdDLTzaXoCkEAG/W7GO5SsTnk1e2xmwWMd3bIt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":769986},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"3b39561b43cae66cdd6a283fad6de09d578afa89","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.3","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.32.1_1787629164732_0.682489734339123","host":"s3://npm-registry-packages-npm-production"}},"0.32.2":{"name":"@nitida/sdk","version":"0.32.2","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.32.2","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"613cc2411cd77f28fa2df3619582c69df59c854e","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.32.2.tgz","fileCount":31,"integrity":"sha512-9AF+XO9MUD2tE0Cq8iUf2Qcydhy5SVzFVjEfT+Ks6E/vHlXpofCfBp31boNt4F0SZKFu01wLt3nkoOVQz1vWuw==","signatures":[{"sig":"MEUCIBD+/Wi7M132TmQSbRx9HOFPuEg2J//mWJC5MNFIH1KZAiEAwf6gaF9SSPD5mRzJfbKnzsNTASU6MK00n89qzTHmsmA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":774105},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"916e96e13f0d397e808ab37aedeb218b21c7ac07","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.3","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.32.2_1787630741717_0.5238916481542686","host":"s3://npm-registry-packages-npm-production"}},"0.32.3":{"name":"@nitida/sdk","version":"0.32.3","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.32.3","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"b244b4893b9f234f79316884124cdd7b2ba11dcd","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.32.3.tgz","fileCount":31,"integrity":"sha512-ij/Wz28nyoPrm7x45pUu5eW0zP7iAV8BgKiW84zYDN0FByAqrmBOeWCxcCnHPv1PzOrjovj9uIqwWxmpQygoJw==","signatures":[{"sig":"MEUCICAAR0NPS2akJUOBwWUVUHCGL8l3+TrrJM7J9RT4X7+7AiEA3NM66ctMwvketJFPEsWC8SgCHVV/uBFjRjovi0ZRoSY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":774105},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"535cd2cfbc68e90f06adeff8265aae21491cb4f7","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.20.4","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.32.3_1787635903324_0.8969903408322957","host":"s3://npm-registry-packages-npm-production"}},"0.33.0":{"name":"@nitida/sdk","version":"0.33.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.33.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"4814218e875e49d81ebf5a23ff70ff574d985ef6","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.33.0.tgz","fileCount":31,"integrity":"sha512-/h81OpcMpK9Mv/MNHRmtK46NDFkyhurN6oc2y3uk5ui8rCUTXztgsQTbzxt3/x/XRppYLmYXgZWjx+M/edl8aQ==","signatures":[{"sig":"MEQCIGrALnxYyKMzHCkJ3rW4DO01UUFbOkJ3SCm/tnvoLaxSAiApXqVA2CY7xO72B0PDyOWTd4n5vZjKDK2atOS2ihtxqQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":785545},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"b8a9a01d85302f907b2b9e6d3bd2b7530e6987a9","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.21.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.33.0_1787704925955_0.7748759649279766","host":"s3://npm-registry-packages-npm-production"}},"0.35.0":{"name":"@nitida/sdk","version":"0.35.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.35.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"b9ceb04f8e0cfdfc1a10d76557e18f7420920a78","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.35.0.tgz","fileCount":31,"integrity":"sha512-Z8HSu2pcDH2HnWpdh3dpcqLMEIXhok9+60qyW4/cAgbGrHq+LDiAenxRkO/NuDfQe2OFZqK9rgjDFkHwsBhggQ==","signatures":[{"sig":"MEUCIQCTWIgzbTOCIiUetwz2Hii+7yW3Kdr7fC2jGso3S7s6KgIgeJRYnxvFlx3hERFCrLltNkR1tJNrgPLzdYFB8Jw1pQc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIHEb366WiHqLlJo0xSARBJOGe25ScuwF1CS1u2A3xkY5AiAPeqWHzSWoNxp3w5FZ5hADLAv9WhZKXZq0yFEMHpWcFA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":802144},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"3e48e5ec87120fab84416dd50b66f4c29068355a","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.23.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.35.0_1788214426265_0.018934773464477583","host":"s3://npm-registry-packages-npm-production"}},"0.36.0":{"name":"@nitida/sdk","version":"0.36.0","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.36.0","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"47631a32d730880acd1a34cb78af0b44fa9801ac","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.36.0.tgz","fileCount":31,"integrity":"sha512-3m/zz6uUQfDKFDFFGznhDglQSy4vSAY6rJb4/OTnVbokBpJLnRC4TYTi4ysvyTmfmZwA9enxhi8JM6sEYvZQuw==","signatures":[{"sig":"MEYCIQDj5wFh807NXgJSFZPRVAm4u+vn9crFDRI+wVY/uFPZJwIhAOd6yUEH6NzHaMxn6oayKcwDo8bYjtnsi/DmXUMaAqIK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBggnAKq9DbvP+q2Y/fINkAE6a0BWSeISclxF+gNewtYAiEAnHYlJ55zpvtrLue9GHpRILGLv4KI9Np7egapAKVgWjg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":803799},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"c111f2f4b986dbd73b993113236d922737b59892","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.24.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.36.0_1788217801659_0.06758551405603885","host":"s3://npm-registry-packages-npm-production"}},"0.36.1":{"name":"@nitida/sdk","version":"0.36.1","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.36.1","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"8587be83157533084b0861559c5d87bdd80d971e","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.36.1.tgz","fileCount":31,"integrity":"sha512-3HAqd16Bgzx5mV4/ygfdwM4/hkfeWysRlbrQ+1Xqr5J0FDcOVok6eFO46cHfNkp9Cp+2jfoqGmRqYQQf+9Ubpg==","signatures":[{"sig":"MEUCIQDGbth17RBTfZlK66Xvd5hdVvLW/7Gns9+CnQ8GTm4OHwIgP1Tf/tJ2ocW6S4HZE8SYQtqd3cUDytno4xYhcGkcphA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIF7ooXmtht8dtqyxIF5TVMDZd339RY+qcZR1xkc257U8AiB2xKltNrfRNRYroTYoiYmZMvqF9YqyKyXJoI8MYoiBuQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":804591},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"69ef847bcb2da340f32afba196e0f8bf3e653d11","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"espaciofuturo","email":"dev@espaciofuturo.io"},"_npmVersion":"10.9.8","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"22.23.2","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"^6.0.3","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.24.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.36.1_1788222963255_0.07083944978397061","host":"s3://npm-registry-packages-npm-production"}},"0.36.2":{"name":"@nitida/sdk","version":"0.36.2","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","_id":"@nitida/sdk@0.36.2","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"homepage":"https://nitida.gofuture.space","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"f0fd97c0283a6e8182d7d537c2e52e54defc60f1","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.36.2.tgz","fileCount":31,"integrity":"sha512-HghEBjYINo4IgQtnUI6c5xxeMmiD983xVFW/VA4LfsE28wuyy4fJSotCxQ2bhJ5UETXwJRhFY+RGMpODGuqO0w==","signatures":[{"sig":"MEUCIG4riHUzrvAcZMJJtDUkRMhMyJJJswPM5bq8fM4DGeM5AiEAsPeeTKkbjYLhmHcugW+85xh2W3uwYqJmxgHJqJDTlRI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQDLcXG1sJs3MoVTOXKdAV91rrrFJLg+7xuKCV+zk46CTQIgYhnPbdho6LAPbRCp7rAUyKM+dEOMjzAB2vEHJk6JN0U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":811694},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"e920dfea41850ad6bbed0d07559dd48cbf3478c7","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:a5b09c99-73e5-4c6f-ad93-f3a6d7cff1f1"}},"_npmVersion":"11.19.0","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"24.20.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"npm:@typescript/typescript6@6.0.2","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.24.0","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.36.2_1789263339708_0.7614820882703222","host":"s3://npm-registry-packages-npm-production"}},"0.36.3":{"_id":"@nitida/sdk@0.36.3","bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"dist":{"shasum":"e30146bcaef129b27e74f6d63590386851439fb8","tarball":"https://registry.npmjs.org/@nitida/sdk/-/sdk-0.36.3.tgz","fileCount":31,"integrity":"sha512-msVPdJCC+gZPuN26uoKQEw8/TiID6nypbgKPrBqRlfPNzqUklXyq9ccZpvccLaAYqm+h0MSpKgodWXIJXkJMaw==","signatures":[{"sig":"MEYCIQCMyKrR9nfcwAEU3U1pIMkuZhihtfUdKXuHl3zEkIzfsgIhAIVme2nQDK+TBCbuShgqQx3mJdCa9mgzmzDn3D4r7eAC","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEAfjkXJqhH1f3ihQmk7TdGANi7JWQH0yo053KRnBhlAAiBgoblXrB//rOA67j1GK7598jZ3FUXLQwb43bvGtn/3eQ=="}],"unpackedSize":813474},"main":"./dist/index.js","name":"@nitida/sdk","type":"module","types":"./dist/index.d.ts","author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"./web":{"import":{"types":"./dist/web.d.ts","default":"./dist/web.js"}},"./expo":{"import":{"types":"./dist/expo.d.ts","default":"./dist/expo.js"}},"./react":{"import":{"types":"./dist/react.d.ts","default":"./dist/react.js"}},"./native":{"import":{"types":"./dist/native.d.ts","default":"./dist/native.js"}},"./server":{"import":{"types":"./dist/server.d.ts","default":"./dist/server.js"}}},"gitHead":"87383b0e876bcb1f82be099607b59fcaa64b4410","license":"MIT","private":false,"scripts":{"test":"bun test test/assets-gaps.test.ts test/upload-mime.test.ts test/presets.test.ts test/variant-assertions.test.ts","build":"tsup","test:e2e":"bun test test/e2e","type-check":"tsc --noEmit","build:watch":"tsup --watch","prepublishOnly":"bun run build"},"version":"0.36.3","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"a5b09c99-73e5-4c6f-ad93-f3a6d7cff1f1"}},"homepage":"https://nitida.gofuture.space","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"_npmVersion":"11.19.0","description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","directories":{},"maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"sideEffects":false,"//repository":"REMOVED 2026-08-21, deliberately. It pointed at espaciofuturoio/aquienpz, which is PRIVATE, so npm rendered a `Repository` link that answers 404 to everyone who clicked it. No repository field renders no link, which is the honest outcome. Nothing depends on it: the publish workflow does NOT pass --provenance (npm rejects provenance from private repos with E422), so this field was rendering a broken link and nothing else. `homepage` and `bugs` below both point at the docs site, which is the real destination. Restore it if the repo is ever made public.","_nodeVersion":"24.21.0","publishConfig":{"access":"public","provenance":false},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.5.1","react":"^19.2.6","@types/bun":"^1.3.14","typescript":"npm:@typescript/typescript6@6.0.2","@types/react":"^19","@nitida/asset-client":"workspace:*","@nitida/asset-uploader-web":"workspace:*","@nitida/asset-uploader-expo":"workspace:*","@nitida/asset-compressor-web":"workspace:*","@nitida/asset-compressor-native":"workspace:*"},"peerDependencies":{"react":">=18","@nitida/asset-client":"^0.24.1","@nitida/asset-compressor-web":"^0.6.1","@nitida/asset-compressor-native":"^0.2.1"},"peerDependenciesMeta":{"react":{"optional":true},"@nitida/asset-compressor-web":{"optional":true},"@nitida/asset-compressor-native":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.36.3_1791006145972_0.7701915618861181"}}},"time":{"created":"2026-08-16T23:35:46.999Z","modified":"2026-10-03T05:42:26.258Z","0.20.0":"2026-08-16T23:35:47.257Z","0.20.1":"2026-08-16T23:42:05.658Z","0.21.0":"2026-08-17T00:08:35.252Z","0.22.0":"2026-08-17T00:27:24.713Z","0.23.0":"2026-08-17T07:24:14.751Z","0.24.0":"2026-08-17T07:41:13.897Z","0.24.1":"2026-08-19T05:40:07.978Z","0.25.0":"2026-08-20T20:05:47.703Z","0.25.1":"2026-08-20T20:14:32.703Z","0.25.2":"2026-08-20T20:19:33.483Z","0.25.3":"2026-08-20T20:36:10.346Z","0.26.0":"2026-08-22T04:04:52.785Z","0.27.0":"2026-08-23T03:50:04.696Z","0.27.1":"2026-08-23T21:38:20.017Z","0.28.0":"2026-08-24T01:17:51.692Z","0.29.0":"2026-08-24T03:36:27.261Z","0.30.0":"2026-08-24T05:20:13.010Z","0.30.1":"2026-08-24T15:46:56.163Z","0.30.2":"2026-08-24T16:28:25.824Z","0.31.0":"2026-08-24T18:36:06.528Z","0.31.1":"2026-08-24T18:57:20.131Z","0.31.4":"2026-08-24T20:08:27.492Z","0.31.5":"2026-08-25T00:03:56.916Z","0.31.6":"2026-08-25T01:02:41.556Z","0.31.7":"2026-08-25T02:40:38.265Z","0.32.0":"2026-08-25T03:16:30.099Z","0.32.1":"2026-08-25T03:39:24.884Z","0.32.2":"2026-08-25T04:05:41.868Z","0.32.3":"2026-08-25T05:31:43.460Z","0.33.0":"2026-08-26T00:42:06.107Z","0.35.0":"2026-08-31T22:13:46.393Z","0.36.0":"2026-08-31T23:10:01.889Z","0.36.1":"2026-09-01T00:36:03.371Z","0.36.2":"2026-09-13T01:35:39.798Z","0.36.3":"2026-10-03T05:42:26.068Z"},"bugs":{"url":"https://nitida.gofuture.space/guides/troubleshooting/"},"author":{"url":"https://espaciofuturo.io","name":"Espacio Futuro LTD"},"license":"MIT","homepage":"https://nitida.gofuture.space","keywords":["media","upload","image","video","hls","cdn","transform","compression","webp","heic","resumable","multipart","multi-tenant","nitida"],"description":"nitida — the media SDK: browser and mobile upload with resume, client-side compression, on-the-fly transforms behind a CDN, video transcode, HLS ladders and AI proxies. Multi-tenant.","maintainers":[{"name":"espaciofuturo","email":"dev@espaciofuturo.io"}],"readme":"# `@nitida/sdk`\n\nUniversal SDK for the [nitida](https://nitida.gofuture.space) multi-tenant media platform.\nA Cloudinary-style asset manager with deterministic CDN URLs, content-addressed\ndedup, server-side variants (thumb / sm / md / lg / poster / video), and **slot\nbindings** — admin-managed names that resolve to assets at runtime.\n\n## One client, every environment\n\nThe whole SDK ships as **one `NitidaClient` class** behind environment-\nspecific subpath entries. Each subpath bundles the same client PLUS the\nhelpers safe for that runtime — same pattern as **Vercel Blob** (`@vercel/blob`\nvs `@vercel/blob/client`), **Better Auth**, **Uploadthing**, and the **Vercel AI\nSDK**. Stripe/Cloudinary's split into two separate npm packages is the legacy\nshape — modern bundlers tree-shake subpaths perfectly and a single version\neliminates type drift between server and client surfaces.\n\n### Two kinds of subpath, and the difference matters\n\n**COMPLETE entry points** carry the whole surface. Import one and you are done.\n\n| Where you run | Import | |\n|---|---|---|\n| Node 20+, Bun, Cloud Run, Lambda, Edge, agents, cron | **`@nitida/sdk/server`** | `NitidaClient` + **every** export of the root. **No browser-only code.** |\n| Browser, and React Native | **`@nitida/sdk/web`** | everything in `/server`, plus `compressImage` (HEIC→WebP). The one deliberate omission is `NitidaClientOptions`, the options type that carries `apiKey` — use `WebClientOptions`. |\n| Anywhere (the root) | `@nitida/sdk` | the full surface, runtime-agnostic. Prefer an explicit subpath in new code. |\n\n**ADDITIVE modules** are layered *on top* of one of the above. They carry only\ntheir own runtime-specific symbols — **you import a complete entry point as\nwell**:\n\n| For | Import | Carries |\n|---|---|---|\n| React hooks | `@nitida/sdk/react` | `NitidaProvider`, `useSlot`, `useSlots`, `useNitidaClient` — and nothing else |\n| RN image compression | `@nitida/sdk/native` | `compressImage` / `compressImages` for RN (`react-native-compressor`) |\n| Expo background uploads | `@nitida/sdk/expo` | `createExpoUploader` — `URLSession` / `WorkManager` sessions that survive backgrounding. ⚠️ **Needs a runtime key on the device** — see below |\n\n⚠️ **`/expo` is the one place a runtime key lives on the device.**\n`createExpoUploader` takes `apiKey` off the client and gives it to the native\nsession as its `authToken`, because the OS replays that upload from a background\ntask hours later and there is no BFF in that loop. It is the opposite call from\n`@nitida/sdk/web`, which hit the same constraint and chose *not* to expose its\nmultipart uploader at all. An `amk_rt_*` in an IPA/APK is readable by anyone who\nunzips it, and it is a write key to a paid platform. If background survival is\nnot worth that, build the client from `/web` against your own route and use\n`aq.upload(file)` — no key on the device, and the upload dies with the JS thread.\n\n⚠️ **React Native needs two imports**, and this table used to imply otherwise:\n`@nitida/sdk/web` for the client and every URL builder — it has no top-level\nbrowser imports, the compressor behind it is a dynamic `import()` — **plus**\n`/native` and/or `/expo` for the native pieces. `/native` alone gives you a\ncompressor and no way to build a URL.\n\nThat `/server` and `/web` really do mirror the root is **asserted in CI**, not\nmaintained by hand. It was not always true: before 2026-08-21 `/server` was\nshort 28 of the root's 72 exports and `/web` short 37.\n\nUploaders + compressors are **optional** peer deps (`@nitida/asset-uploader-{web,expo}`,\n`@nitida/asset-compressor-{web,native}`). Skip them if your app only resolves\nslots and reads assets — your bundle stays a few KB.\n\n### Quick decision tree\n\n- Server-side rendering, API routes, BFF, cron, agents → `@nitida/sdk/server`.\n- Browser components, build-time pre-resolution → `@nitida/sdk/web`.\n- Expo / React Native app → `@nitida/sdk/web` (the client and the URL builders)\n  **plus** `@nitida/sdk/native` and/or `@nitida/sdk/expo` for the native pieces.\n- React hooks (any env) → `@nitida/sdk/react` **plus** `/web` or `/server`.\n\n**Never ship the API key to the browser.** Whichever subpath you import,\nthe long-lived `amk_rt_*` key lives on the server. Browser flows hit a BFF\nroute that proxies to the nitida API with the real key.\n\n## Which subpath do I import from?\n\n| Context | Import | Notes |\n|---|---|---|\n| Browser (Next.js client component, SPA, Worker, web extension) | `@nitida/sdk/web` | **No `apiKey`** — your BFF injects it. Type omits the field; build error if you try. |\n| Node/Bun server (API route, Server Action, Cloud Run, Fly, BFF) | `@nitida/sdk/server` | Requires `apiKey` at construction. |\n| React Native / Expo | `@nitida/sdk/web` **plus** `/native` and/or `/expo` | Same BFF model as `/web` — keep keys server-side. `/native` and `/expo` are additive; on their own they carry no client. |\n| Universal React hook | `@nitida/sdk/react` **plus** `/web` or `/server` | The hooks read a client from context; something has to construct it. |\n\n### …and where does each HELPER live?\n\nThe table above answers *\"where do I get the client\"*. It did **not** used to\nanswer *\"where do I get `getHlsLadder`\"*, and that is the question that cost the\nmost time — an agent evaluating this SDK followed `AGENTS.md` to `/server`,\nimported `getHlsLadder` from there, and got a `SyntaxError` at runtime.\n\n**Now there is a one-line answer, and CI keeps it true:**\n\n> **`@nitida/sdk`, `/server` and `/web` all carry the same surface.**\n> Import any helper from whichever of the three you already use.\n\n| what you want | `@nitida/asset-client` | `@nitida/sdk` · `/server` · `/web` | elsewhere |\n|---|---|---|---|\n| URL builders — `getAssetUrl`, `getTransformUrl`, `getVideoTransformUrl`, `getAssetSrcSet`, `getTransformSrcSet`, `getHlsStreamingUrl`, `serializeTransform` | ✅ | ✅ | |\n| Signing — `signTransformUrl`, `getSignedTransformUrl` | ✅ | ✅ | |\n| Asset facts — `hasPreset`, `extractAssetSha`, `getAssetDimensions`, `computeVariantDimensions` | ✅ | ✅ | |\n| HLS — `getHlsLadder`, `hlsLadderAlignment`, `HlsRung` | ✅ | ✅ | |\n| Palette — `pickAmbientBackground`, `iteratePaletteSwatches`, `bestTextContrast`, `getAmbientGradient`, `getPaletteCssVars`, `getPaletteBlurBackground`, `getTextColorForBackground`, `contrastRatio`, `relativeLuminance` | ✅ | ✅ | |\n| Slots — `resolveSlot`, `resolveSlots`, `configureSlotResolver`, `invalidateSlotCache` | ✅ | ✅ | |\n| Constants — `TRANSFORM_WIDTHS`, `TransformWidth`, `PRESET_EXT`, `PRESET_LONG`, `PRESET_SHORT`, `PRESET_MAX_DIM` | ✅ | ✅ | |\n| Config — `setCdnBase`/`getCdnBase`, `setTenantId`/`getTenantId` | ✅ | ✅ | |\n| `NitidaClient` and its option/result types | | ✅ | |\n| Client-side compression — `compressImage`, `compressImages` | | `/web` only | `/native` (React Native) |\n| React hooks — `NitidaProvider`, `useNitidaClient`, `useSlot`, `useSlots` | | | `/react` only |\n| Expo resumable upload — `createExpoUploader`, `listResumableSessions`, `cancelResumableSession` | | | `/expo` only |\n\nThe single deliberate exception: **`NitidaClientOptions` is not on `/web`.** That\nis the options type that carries `apiKey`, and this subpath exists so the\napiKey-bearing shape is unreachable from browser code — use `WebClientOptions`.\n\nThis is not maintained by hand. `scripts/check-published-doc-symbols.ts` asserts\nthat `/server` and `/web` mirror the root, and that the one denial above still\nhas a written reason. Before 2026-08-21 it was not true: `/server` was short\n**28** of the root's 72 and `/web` short **37**, `getHlsLadder` among them.\n\n### Why subpaths, not a runtime flag\n\nIf you import `/server` in browser code, the bundler throws a build error.\nIf we used a runtime `{ mode: \"browser\" }` flag and you forgot it, your API\nkey would silently bundle into the client. Subpaths make security mistakes\nloud — same pattern as `@vercel/blob/client`, `better-auth/client`, AI SDK's\n`/edge` subpath.\n\n`@nitida/sdk/web` v0.17+ enforces this physically: the constructor type\nis `Omit<NitidaClientOptions, \"apiKey\" | \"signingKey\">`. Passing `apiKey`\nwon't compile, period.\n\n## BFF-proxy mode (browser → your route → nitida)\n\nBrowser code constructs the client against a **relative endpoint** that\npoints at your own route handler. The handler attaches the real bearer\ntoken and forwards to the nitida API. Same pattern Vercel Blob uses for\n`@vercel/blob/client.upload`.\n\n### Next.js — client component\n\n```tsx\n\"use client\";\nimport { NitidaClient } from \"@nitida/sdk/web\";\n\nconst aq = new NitidaClient({\n  endpoint:   \"/api/am\",              // OK: relative → same-origin BFF\n  tenantCode: \"acme-co\",\n  tenantId:   1,\n  // apiKey: ... ERROR: TS error: not assignable to WebClientOptions\n});\n\nexport function HeroPicker() {\n  return <input type=\"file\" onChange={async (e) => {\n    const file = e.target.files?.[0];\n    if (file) await aq.upload(file, { compress: true });\n  }} />;\n}\n```\n\n### Next.js — BFF route handler\n\n```ts\n// app/api/am/[...path]/route.ts\nimport { NextRequest } from \"next/server\";\n\nconst UPSTREAM = process.env.AQUIENPZ_URL!;        // server-only\nconst API_KEY = process.env.AQUIENPZ_API_KEY!;     // server-only\nconst TENANT  = process.env.AQUIENPZ_TENANT_CODE!; // e.g. \"acme-co\"\n\nasync function proxy(req: NextRequest, { params }: { params: { path: string[] } }) {\n  const search = new URL(req.url).search;\n  const url = `${UPSTREAM}/${params.path.join(\"/\")}${search}`;\n  const body = [\"GET\", \"HEAD\"].includes(req.method) ? undefined : await req.arrayBuffer();\n  return fetch(url, {\n    method:  req.method,\n    body,\n    headers: {\n      Authorization:    `Bearer ${API_KEY}`,\n      \"X-Tenant-Code\":  TENANT,\n      \"Content-Type\":   req.headers.get(\"content-type\") ?? \"application/json\",\n    },\n  });\n}\n\nexport { proxy as GET, proxy as POST, proxy as PUT, proxy as PATCH, proxy as DELETE };\n```\n\n### Bun / Elysia backend\n\n```ts\nimport { NitidaClient } from \"@nitida/sdk/server\";\n\nconst aq = new NitidaClient({\n  endpoint:   process.env.AQUIENPZ_URL!,\n  apiKey:     process.env.AQUIENPZ_API_KEY!,   // OK: required by ServerClientOptions\n  tenantCode: \"acme-co\",\n  tenantId:   1,\n});\n```\n\n### Expo\n\n```ts\nimport { NitidaClient } from \"@nitida/sdk/web\"; // same browser-safe type\n// Construct against your /api/am proxy; no apiKey in the app bundle.\n```\n\n### SSG storefront (build-time)\n\nUse `/server` at build time (Node/Bun) with the absolute nitida API URL —\nno proxy needed because keys never reach the browser bundle. Static\nHTML output references the CDN directly.\n\n## Install\n\n```bash\nbun add @nitida/sdk @nitida/asset-client\n# or\nnpm install @nitida/sdk @nitida/asset-client\n```\n\nOptional, only if you compress on the client before uploading:\n\n```bash\nbun add @nitida/asset-compressor-web      # browser: HEIC→WebP, resize\nbun add @nitida/asset-compressor-native   # Expo / React Native\n```\n\nPeer deps: `@nitida/asset-client` (URL builders + types) and `react` (only if\nyou use the `/react` subpath). Both compressors are optional and lazy — the\nSDK never imports them unless you call a compress path.\n\n> The multipart uploader packages (`@nitida/asset-uploader-web` / `-expo`) are\n> on npm since 2026-08-23. You do not need them for ordinary uploads:\n> `aq.upload()` covers a file in a single PUT and is what every consumer uses\n> today — see *Large uploads* below for where that ceiling actually is. Reach\n> for an uploader when you need **resume**: a 2 GB upload that must survive a\n> reload (web, IndexedDB) or the app being backgrounded (Expo, iOS URLSession\n> / Android WorkManager).\n\n## Quick start\n\n```ts\nimport { NitidaClient } from \"@nitida/sdk\";\n\nconst aq = new NitidaClient({\n  endpoint: \"https://api.nitida.gofuture.space\",\n  apiKey:   process.env.AQUIENPZ_API_KEY!,          // amk_rt_* runtime API key\n  tenantCode: \"your-tenant\",\n  tenantId:   42,                  // ⚠️ va en la URL en BASE36: 42 → \"16\". Ni decimal, ni hex.\n  cdnBase:    \"https://8ok.uk\",    // optional, defaults to https://8ok.uk\n});\n\n// Slots — the recommended way to reference brand assets in code.\n// Source never hardcodes a CDN URL; an admin rebinds it from the console.\nconst hero = await aq.slots.resolve(\"storefront.home.hero\");\n//   → { slot: { asset, preset, … }, preset: \"lg\", url: \"https://8ok.uk/16/v/<sha>-l.webp\" }\n\n// Bulk resolution in one round-trip.\nconst heroes = await aq.slots.resolveMany([\n  \"storefront.home.hero\",\n  \"storefront.home.tile-1\",\n  \"storefront.home.tile-2\",\n]);\n\n// Lower-level operations. `byHash` takes the full 64-hex sha256 that\n// `upload()` returns as `.sha256`, OR its 16-char prefix — the short form\n// that appears inside every CDN URL. Both resolve to the same asset.\nconst asset = await aq.assets.byHash(\"3c…<64 hex>…\");\nconst same = await aq.assets.byHash(\"3c8f1a20b7d94e05\"); // 16-char prefix ✓\nconst { assets, nextCursor } = await aq.assets.list({ limit: 50 });\n\n// Uploads — hash-deduped; returns the canonical v2 URL immediately.\nconst result = await aq.upload(file, { fileName: \"cover.jpg\" });\n// → { assetId, sha256, sha, mime, oext, cdnUrl }\n//   `sha` (16 hex), `mime` y `oext` existen desde 0.30.0 para que el resultado\n//   se pueda pasar DIRECTO a cualquier builder, sin volver a buscar el DTO:\n//     getAssetUrl(result, \"original\")   // → -o.jpg, no -o.bin\n//   Un objeto armado a mano con sólo { assetId, sha256, cdnUrl } NO sirve:\n//   los builders leen `sha`, no `sha256`, y `assertSha` lo rechaza.\n\n// Uploading raw bytes (Node/Bun, e.g. re-hosting a remote image)? A Uint8Array has no\n// inherent MIME, so give it one — otherwise it stores as kind:\"other\" (NO image variants):\nawait aq.upload(bytes, { fileName: \"cover.webp\" });              // MIME inferred from .webp ✓\nawait aq.upload(bytes, { contentType: \"image/webp\" });          // or be explicit ✓\n// And request the variants you'll render — `presets` DEFAULTS TO [\"original\"] (just the raw\n// bytes). ⚠️ Corrected 2026-08-25: a BARE sha does not 404 — it THROWS\n// (`assertSha`); and with the full object, a missing IMAGE preset does not\n// 404 either — it falls back to `/t/` and serves 200. What 404s is a\n// hand-built variant key. Ask for the ladder anyway when you want\n// materialised bytes instead of an on-the-fly transform:\nawait aq.upload(bytes, { contentType: \"image/webp\", presets: [\"thumb\", \"sm\", \"md\", \"lg\", \"xl\"] });\n\n// Bind a slot (admin operation).\nawait aq.slots.bind(\"storefront.home.hero\", {\n  assetId: result.assetId,\n  preset:  \"lg\",\n  description: \"Homepage hero — uploaded by admin on 2026-05-16\",\n});\n```\n\n## Client-side compression (browsers)\n\n`aq.upload(file, { compress: true })` runs the file through\ncompressorjs + heic2any before the PUT, saving the user's bandwidth.\nTypical result for an 8 MB iPhone HEIC photo: ~800 KB uploaded after\nHEIC → JPEG → WebP @ q=0.80, max-edge 3840 px.\n\n```ts\n// Default — uses DEFAULT_COMPRESSION_OPTIONS (webapp-tuned values)\nconst result = await aq.upload(file, {\n  compress: true,\n  presets: [\"thumb\", \"sm\", \"md\", \"lg\"],\n});\n\n// Custom tuning per call\nawait aq.upload(file, {\n  compress: { quality: 0.7, maxWidth: 2048 },\n});\n\n// Track progress for UI\nawait aq.upload(file, {\n  compress: {\n    onProgress: (stage) => console.log(stage),\n    // stage ∈ \"convertingHeic\" | \"compressing\" | \"compressingKeepingDimensions\"\n  },\n});\n```\n\n**Defaults** (tuned against a production photo-upload workload —\nphone cameras, listing covers):\n\n| Option | Default |\n|---|---|\n| `quality` | `0.80` |\n| `mimeType` | `\"image/webp\"` |\n| `maxWidth` / `maxHeight` | `3840` |\n| `convertSize` (PNG → JPEG threshold) | `5 MB` |\n| `strict` | `true` |\n\n**Caveats**:\n\n- Browser-only. In Node / Bun the call is a silent no-op (warns to\n  console) and the raw bytes upload as-is.\n- Non-image MIMEs (video, PDF) are passed through regardless of\n  `compress: true`. Safe to set blanket-fashion on mixed media batches.\n- Adds ~50 KB to the runtime bundle **only when used** — lazy-imported\n  from `@nitida/sdk/web`.\n- HEIC inputs go through heic2any first (additional ~200 KB lazy bundle).\n- Expo / React Native: the `/expo` subpath uses native\n  `expo-image-manipulator` instead (already wired in the uploader). The\n  `compress` option on `aq.upload` is web-only.\n- The original pre-compression size is recorded server-side, so the\n  savings show up in the admin usage dashboards.\n\nDirect access to the compressor (without going through `aq.upload`):\n\n```ts\nimport { compressImage, compressImages, DEFAULT_COMPRESSION_OPTIONS }\n  from \"@nitida/sdk/web\";\n\nconst { blob, originalBytes } = await compressImage(file, { quality: 0.85 });\nconst results = await compressImages([fileA, fileB, fileC]);\n```\n\n## Large uploads (web)\n\n`aq.upload()` is a single PUT: atomic, BFF-friendly, and the path this SDK\nsupports. It is what you should call.\n\n**Multipart is deliberately NOT exposed from `@nitida/sdk/web`.** A static\nimport of the uploader package broke every consumer of the subpath (the\nbundler resolves before the optional-peer check runs), and the `UploadTask`\nAPI needs a raw `authToken` that BFF-proxy mode does not hand out — so there\nis no `createWebUploader` export. Earlier drafts of this README described\none; it never shipped.\n\nWhere that leaves you:\n\n| file size | what to call |\n|---|---|\n| any size the browser can hold in memory | `aq.upload(file)` |\n| bigger, or you need resume across reloads | not covered by this SDK yet — talk to us |\n\nClient-side compression is the lever that keeps most media under the\nsingle-PUT ceiling; see *Client-side compression* below.\n\n## Large uploads (Expo / React Native)\n\nNative background uploads survive app suspend, low-memory kills, and\nnetwork blips. iOS uses URLSession's background config; Android uses\nWorkManager. Same JS API as the web flavor.\n\n```tsx\nimport { useEffect, useState } from \"react\";\nimport { Image } from \"react-native\";\nimport * as ImagePicker from \"expo-image-picker\";\nimport { NitidaClient } from \"@nitida/sdk\";\nimport {\n  createExpoUploader,\n  listResumableSessions,\n} from \"@nitida/sdk/expo\";\n\n// Background upload survival means a token DOES reach the native session — but\n// it must be a short-lived, per-user token your backend mints, NEVER a shared\n// platform amk_rt_* baked into the binary via EXPO_PUBLIC_* (that ships one write\n// key to the whole platform, readable by anyone who unzips the IPA/APK). Fetch it\n// at runtime from your own /session route and hand it to the client.\nconst { uploadToken } = await fetch(`${API}/session/upload-token`).then((r) => r.json());\n\nconst aq = new NitidaClient({\n  endpoint:   process.env.EXPO_PUBLIC_AQUIENPZ_URL!,\n  apiKey:     uploadToken, // short-lived, scoped, from YOUR backend — not EXPO_PUBLIC_*\n  tenantCode: \"your-tenant\",\n  tenantId:   42,\n});\n\nexport function UploadHeroScreen() {\n  const [progress, setProgress] = useState(0);\n  const [url, setUrl] = useState<string | null>(null);\n\n  // Offer to resume anything from a prior app launch on boot.\n  useEffect(() => {\n    listResumableSessions().then((sessions) => {\n      // …show a banner if sessions.length > 0\n    });\n  }, []);\n\n  async function pickAndUpload() {\n    const picked = await ImagePicker.launchImageLibraryAsync({\n      mediaTypes: ImagePicker.MediaTypeOptions.Videos,\n      allowsMultipleSelection: false,\n    });\n    if (picked.canceled || !picked.assets[0]) return;\n    const { uri, mimeType, fileName } = picked.assets[0];\n\n    const task = createExpoUploader(aq, {\n      file: {\n        uri,\n        mime: mimeType ?? \"video/mp4\",\n        name:  fileName ?? \"tour.mp4\",\n      },\n    });\n    task.on(\"progress\", ({ ratio }) => setProgress(ratio));\n\n    const { assetId } = await task.start();\n    // Bind to a slot so the storefront picks it up without a redeploy.\n    await aq.slots.bind(\"storefront.tour.video\", { assetId, preset: \"video\" });\n    const resolved = await aq.slots.resolve(\"storefront.tour.video\");\n    setUrl(resolved.url);\n  }\n\n  return /* …UI with pickAndUpload + progress bar + <Image source={{ uri: url }}/> */;\n}\n```\n\nℹ️ `@nitida/asset-uploader-expo` **is on npm** (`0.2.0`, MIT) and installs\nnormally. `aq.upload()` works on Expo without it; you want the uploader when you\nneed a **resumable, background** upload — the only way a transfer survives iOS\nsuspending the app. See the note above on when an uploader is worth adding.\n\n## Next.js App Router (Server Components)\n\nThe cheapest path: resolve slots at render time on the server. No client JS,\nno provider, no hook. The slot URLs ship as plain `<img>` markup.\n\n```tsx\n// app/page.tsx — Server Component\nimport { NitidaClient } from \"@nitida/sdk\";\n\nconst aq = new NitidaClient({\n  endpoint:   process.env.AQUIENPZ_URL!,\n  apiKey:     process.env.AQUIENPZ_API_KEY!, // amk_rt_* — server-only\n  tenantCode: \"your-tenant\",\n  tenantId:   42,\n});\n\nexport default async function Page() {\n  const heroes = await aq.slots.resolveMany([\n    \"storefront.home.hero\",\n    \"storefront.home.tile-1\",\n    \"storefront.home.tile-2\",\n  ]);\n\n  return (\n    <>\n      {heroes[\"storefront.home.hero\"].url && (\n        <img src={heroes[\"storefront.home.hero\"].url} alt=\"\" />\n      )}\n      {/* … */}\n    </>\n  );\n}\n```\n\nKeep the API key on the server — never expose `amk_rt_*` to `NEXT_PUBLIC_*`.\nUploads from Client Components should go through a thin BFF route handler that\nproxies `aq.upload()` server-side.\n\nFor images that benefit from `next/image`, use `aq.urlFor()` + `aq.srcSetFor()`\nto emit a static URL set; Next then handles its own optimization pipeline.\n\n## React hooks (Client Components / SPA)\n\nReactive resolution on the client. The provider holds the configured client;\neach hook subscribes to the in-process cache.\n\n```tsx\n// app/providers.tsx — Client Component\n\"use client\";\nimport { NitidaClient } from \"@nitida/sdk\";\nimport { NitidaProvider } from \"@nitida/sdk/react\";\n\n// NO apiKey in the browser. Reads and URL building (useSlot, urlFor, srcSetFor)\n// need no credential; writes go through a BFF route that calls aq.upload()\n// server-side with the real amk_rt_* key (see the warning above). Shipping\n// NEXT_PUBLIC_AQUIENPZ_API_KEY inlines a shared platform write key into every\n// bundle — readable by any visitor.\nconst client = new NitidaClient({\n  endpoint:   process.env.NEXT_PUBLIC_AQUIENPZ_URL!,\n  tenantCode: \"your-tenant\",\n  tenantId:   42,\n});\n\nexport function Providers({ children }: { children: React.ReactNode }) {\n  return <NitidaProvider client={client}>{children}</NitidaProvider>;\n}\n```\n\n```tsx\n// app/hero.tsx\n\"use client\";\nimport { useSlot } from \"@nitida/sdk/react\";\n\nexport function Hero() {\n  const { url, isLoading } = useSlot(\"storefront.home.hero\");\n  if (isLoading) return <Skeleton />;\n  if (!url) return <PlaceholderHero />;\n  return <img src={url} alt=\"\" />;\n}\n```\n\nWorks in any React 18+ host: Vite, CRA, Remix, Astro islands, Expo Router,\nReact Native — wherever `react-dom` (or `react-native`) runs.\n\n## Why slots?\n\nHardcoding `https://cdn.your-tenant.com/abc123.webp` in source code couples\ndeploys to brand decisions. With slots:\n\n| Without slots | With slots |\n|---|---|\n| Edit URL in code | Drag-drop a new asset in the admin console |\n| Commit + PR + deploy | Cache refreshes (60s default) |\n| 5-30 minute roundtrip | Instant |\n\nThe slot key (`storefront.home.hero`, `webapp.wizard.pool-type.icon-1`) is the\n**stable contract** between code and brand operations. Tenants own the bindings;\ncode is a passive consumer.\n\n## URL conventions — variants are tenant-scoped, transforms are not\n\nTwo delivery paths, **by design**:\n\n| Kind | Builder | URL shape | Tenant in path? |\n|---|---|---|---|\n| Variant / preset | `urlFor`, `srcSetFor`, upload `cdnUrl` | `<cdn>/<tenantId b36>/v/<sha>-<preset>.<ext>` | **Yes** — `/4/v/<sha>-l.webp` |\n| On-the-fly transform | `transform`, `transformSrcSet` | `<cdn>/t/<dsl>/<sha>.<ext>` | **No** — `/t/width=1280,.../<sha>.webp` |\n\nThe transform service is content-addressed by `sha` and resizes from the source on demand,\nso it carries **no tenant segment**. Hand-building a transform URL as `/<tenant>/t/...` **404s**.\n(Variants are stored per-tenant, so those DO carry the tenant prefix.) Always use the SDK\nbuilders rather than concatenating paths — and never prepend the tenant to a `/t/` URL.\n\n## Presets\n\nPresets are **platform-wide and fixed** — every tenant gets the same set,\ngenerated server-side by the asset-manager's variant pipeline. A tenant\ncannot define custom dimensions through the SDK; they pick which preset a\nslot defaults to and emit responsive `srcSet` for browser-side resizing.\n\n### Preset short codes — generated, do not edit by hand\n\nA variant URL carries the **code**, not the preset name (`/v/<sha>-l.webp`,\nnot `-lg.webp`). Copy the letter from here — `bun run gen:docs` regenerates\nthis table from the source, so it can't have the wrong one.\n\n<!-- BEGIN GENERATED: preset-codes · bun run gen:docs -->\n| Preset | Code |\n|---|---|\n| `thumb` | `q` |\n| `sm` | `s` |\n| `md` | `m` |\n| `lg` | `l` |\n| `xl` | `x` |\n| `original` | `o` |\n| `poster` | `p` |\n| `video` | `v` |\n| `aiproxy` | `a` |\n| `hls` | `h` |\n| `mp3` | `mp3` |\n<!-- END GENERATED: preset-codes -->\n\n### Image presets\n\n| Preset    | Code | Max-side           | Typical use |\n|-----------|------|--------------------|---|\n| `thumb`   | `q`  | 256×256 smart-crop | avatars, micro-tiles |\n| `sm`      | `s`  | 640                | mobile thumbs, list cards |\n| `md`      | `m`  | 1280               | desktop cards, modal previews |\n| `lg`      | `l`  | 1920 (≈2K)         | hero, full-bleed |\n| `xl`      | `x`  | 3840 (4K)          | print, 4K screens · a clean WebP base ≤ 3840 is reused as-is |\n\n**Defaults — what actually runs:**\n\n| Caller path                                           | Variants generated on upload |\n|-------------------------------------------------------|------------------------------|\n| `aq.upload(file)` (SDK, no `presets`)                 | `original` only              |\n| `POST /assets/upload-url` (HTTP direct, no `presets`) | `original` only (same as SDK) |\n| `presets: [\"original\"]` (either path)                 | `original` only              |\n| `presets: [\"thumb\",\"sm\",\"md\",\"lg\"]`                   | exactly the four listed      |\n\nOmitting `presets` is always equivalent to `[\"original\"]` — the platform\nnever auto-generates the responsive ladder. This keeps logo / SVG /\none-shot uploads cheap and avoids surprise storage writes (the ladder\nis 4× the source bytes). Apps that want responsive sizes pass them explicitly:\n\n```ts\nawait aq.upload(file, {\n  presets: [\"thumb\", \"sm\", \"md\", \"lg\"],   // four WebP variants\n});\n```\n\nOr add missing variants later without re-uploading:\n\n```ts\nawait aq.assets.regenerate(assetId, { presets: [\"thumb\", \"sm\", \"md\", \"lg\"] });\n```\n\nVariants are WebP `quality: 75–80`. Total stored bytes when generating\nthe full responsive ladder ≈ 4× source bytes.\n\n**Variants never upscale.** The pipeline clamps each preset's target to\n`min(presetMaxSide, sourceMaxSide)`. A 1080×720 photo asked for `xl`\n(3840) yields a 1080×720 `xl` variant, not a blurry 3840-wide stretch.\nThe preset is a **ceiling**, not a target.\n\n**`xl` reuses a ≤ 4K base byte-for-byte.** 4K is the cap for listing\nphotos. When the uploaded base is a clean WebP no larger than 3840 px\n(single frame, no EXIF orientation, no EXIF/XMP), the server stores it\nas `xl` unchanged: same sha256, no second lossy pass. Anything else (a\nlarger base, JPEG/PNG/HEIC, animated or EXIF-bearing WebP) is re-encoded\nto WebP q82 as before. The default `compressImage` output (3840 px WebP)\nqualifies. URLs, keys and response shapes do not change; `xl` is still\nits own object, the same size as the base. Already-stored assets keep\ntheir existing `xl`.\n\n### Non-image / passthrough\n\n| Preset    | Code | Purpose |\n|-----------|------|---|\n| `original`| `o`  | Raw uploaded bytes, no transformation. Used today for non-image MIMEs (PDFs, audio, etc.). |\n\n### Video presets\n\n| Preset    | Code | Purpose                |\n|-----------|------|------------------------|\n| `poster`  | `p`  | extracted poster WebP  |\n| `video`   | `v`  | original MP4           |\n| `aiproxy` | `a`  | low-res proxy for AI captioning / search (opt-in) |\n\n### ⚠️ What you can ASK FOR is not what a variant can BE\n\nTwo different sets, two different types, and confusing them is the most\nexpensive type error this package has shipped — three unknown agents evaluating\nthe SDK hit it independently in one afternoon.\n\n```ts\naq.assets.regenerate(id, { presets: [\"hls\"] });   // ← used to compile. HTTP 400.\naq.upload(file,          { presets: [\"mp3\"] });   // ← used to compile. HTTP 400.\n```\n\nBoth symbols are real. Neither is orderable.\n\n| | `RequestablePreset` — you may ask | `VariantPreset` — a variant may be |\n|---|---|---|\n| `thumb` `sm` `md` `lg` `xl` `original` `poster` `video` `aiproxy` | ✅ | ✅ |\n| `hls` — the adaptive ladder, built when a video transcodes | ❌ | ✅ |\n| `mp3` — emitted alongside an audio original **only when the original is not already universally playable** (i.e. NOT `audio/mpeg`, `audio/mp4`, `audio/aac`) | ❌ | ✅ |\n| `probe` — indexed stills (`-pr0.jpg`), never on the compact `presets` string | ✅ | ❌ |\n\nThe write methods (`upload`, `presignUploadUrl`, `regenerate`) take\n`RequestablePreset[]`, so all three lines above are now **compile errors**. The\nread helpers (`hasPreset`, `variants[].preset`, `PRESET_SHORT`) keep\n`VariantPreset`, because `hls` and `mp3` genuinely do exist on assets.\n\n`probe` was the same bug mirrored: the server has always accepted it and the\ntype forbade it. It is requestable now.\n\nThis is checked in CI against the server itself —\n`scripts/check-preset-contract.ts` reads the Elysia schemas of all four write\nroutes and asserts `RequestablePreset` still equals what they accept, so it\ncannot go stale the way a hand-written list would.\n\n### Per-upload preset selection\n\n**The SDK's default is `[\"original\"]`** — calling `aq.upload(file)`\nwith no `presets` option stores only the raw bytes. Add the\nresponsive ladder when you actually need it, or generate it later\nwith `aq.assets.regenerate()` (no re-upload required).\n\n```ts\n// Default: only the original variant lands on the CDN.\nconst { assetId, cdnUrl } = await aq.upload(logoFile);\n// asset.presets === \"o\"\n// cdnUrl = https://8ok.uk/<tid b36>/v/<sha>-o.svg   ← the tenant segment is not optional\n\n// Processing is asynchronous. `upload()` returns as soon as the bytes are\n// accepted; the variants are not on the CDN yet. Wait for them:\nconst ready = await aq.assets.waitReady(assetId, 90_000); // MILLISECONDS\n// ready.presets is the compact string (\"o\", \"lmoqs\", …), ALPHABETICALLY\n// sorted — not in the order you asked for.\n```\n\n**Responsive ladder (the old default — now explicit):**\n\n```ts\nawait aq.upload(heroFile, {\n  fileName: \"homepage-hero.jpg\",\n  presets: [\"thumb\", \"sm\", \"md\", \"lg\"],  // classic 4-step\n});\n```\n\n**4K hero with the full size ladder:**\n\n```ts\nawait aq.upload(heroFile, {\n  presets: [\"thumb\", \"sm\", \"md\", \"lg\", \"xl\"],\n});\n// asset.presets === \"qsmlx\"; aq.srcSetFor(asset) now emits an xl entry.\n```\n\n**Video without the AI proxy transcode:**\n\n```ts\nawait aq.upload(videoFile, {\n  presets: [\"poster\", \"video\"],  // skip aiproxy\n});\n```\n\n**Large video — bump the readiness timeout:**\n\n`aq.upload()` waits up to **5 minutes** by default for the asset to\ntransition to `ready`. Transcode time scales with input size and CPU,\nso videos ≥30 MB (especially HLS ladders) can blow past that. Opt in\nto a longer deadline via `timeoutMs`:\n\n```ts\n// Large video (>30MB): bump timeout to 15min\nawait aq.upload(file, { timeoutMs: 15 * 60_000 });\n```\n\nThe default is unchanged — existing call sites need no migration.\n\nVariants never upscale — each size preset is a **ceiling**, not a\ntarget. A 1080×720 source asked for `xl` (3840) yields a 1080×720 xl\nvariant.\n\n**Caveat (content-addressed dedup):** if someone already uploaded the\nsame bytes with different presets, `aq.upload()` returns the existing\nasset without re-processing. The result's `cdnUrl` will use whichever\npreset is actually available on that asset (the SDK picks `lg → md → sm\n→ thumb → xl → original` for images, `video → poster` for videos). To\nadd variants to an existing asset, use `aq.assets.regenerate()`.\n\n## Adding variants later (no re-upload)\n\nThe most common flow with the new default:\n\n```ts\n// Day 0 — upload original only.\nconst { assetId } = await aq.upload(logoFile);\n\n// Day 7 — peek at what's there.\nconst variants = await aq.assets.variants(assetId);\nconsole.log(variants.map((v) => v.preset));  // → [\"original\"]\n\n// Day 7 — need a thumb for an avatar slot. Generate it server-side,\n// merged with the existing variant set.\nawait aq.assets.regenerate(assetId, { presets: [\"thumb\"] });\n\nconst after = await aq.assets.variants(assetId);\nconsole.log(after.map((v) => v.preset));     // → [\"original\", \"thumb\"]\n```\n\n`regenerate()` merges — existing variants you didn't ask for stay put.\nYou can call it many times; it's idempotent per preset.\n\n### Source-byte lifecycle (why regenerate always works)\n\nYour bytes exist in two places with **very different lifetimes**:\n\n| Bytes | Role | Lifetime |\n|---|---|---|\n| The upload you PUT to the presigned URL | Read once to verify the SHA. Never CDN-served. | **Deleted ~24h after upload** |\n| The stored variants | The CDN-served files. The `original` variant is the permanent home of your source bytes. | **Permanent** — only deleted by an explicit DELETE on the asset or variant |\n\n⚠️ **That 24h is why you should ask for `original`.** Once the grace window\ncloses, the highest-fidelity bytes still on the platform are whatever variants\nyou asked for.\n\n`regenerate()` walks a fidelity-ordered fallback chain until it finds\nusable bytes — it **never fails on a still-present asset**:\n\n```\n1. original   ← permanent, your exact source (best)\n2. raw        ← the upload bytes, only during the 24h grace\n3. xl → lg → md → sm\n4. thumb      ← last resort: it is a smart-cropped square, so anything\n                derived from it inherits the thumb's crop\n```\n\nThe no-upscale clamp guarantees we never invent pixels: asking for\n`lg` (1920) from a 640 `sm` source yields a 640-side `lg` variant.\nThe result type's `sourceUsed` field tells you which fallback was\npicked so you can decide whether the quality is good enough:\n\n```ts\nconst result = await aq.assets.regenerate(assetId, { presets: [\"xl\"] });\nif (result.kind === \"image\" && result.sourceUsed !== \"original\" && result.sourceUsed !== \"raw\") {\n  console.warn(`xl was derived from ${result.sourceUsed} — quality degraded`);\n}\n```\n\n**Recommendation:** include `\"original\"` in the upload preset list\nwhen you want guaranteed lossless future re-derivation. The SDK's\ndefault (`[\"original\"]`) already does this for you.\n\n`aq.assets.variants(id)` and `aq.assets.regenerate(id, opts)` are\nfully typed — your editor autocompletes the preset names and the\nreturned shape gives you `{ preset, url, width?, height?, bytes }[]`.\n\n## On-the-fly transformations\n\nPre-generated presets (`thumb`/`sm`/`md`/`lg`/`xl`) cover the common cases.\nFor everything else — exact CSS pixel widths, art-directed crops, devicePixelRatio\nladders, square thumbs from rectangular sources — build a `/t/` URL.\n\n### `aq.transform()` or `getTransformUrl()`? Both, and the rule is which you have\n\nTwo agents evaluating this SDK picked different ones for the same task and both\nwere right, which is a documentation failure rather than a design one. They are\n**not duplicates**: `aq.transform()` is `getTransformUrl()` plus the client's\ncontext.\n\n| you have | use | why |\n|---|---|---|\n| a client (`aq`) | **`aq.transform(asset, opts)`** | it already knows your CDN base and tenant (⚠️ see the multi-tenant warning below), and it is the only one that can **sign** — `aq.transform(asset, opts, { sign: true })` returns a `?sig=` URL, the only way to an **arbitrary** width |\n\n> ⚠️ **THE TENANT IS ONE MODULE-WIDE GLOBAL, NOT PER-CLIENT STATE.**\n>\n> Constructing a `NitidaClient` calls `setTenantId()` — the same global the standalone\n> setter writes. **The last client constructed wins**, and every client made before it\n> silently starts emitting the other tenant's URLs. Measured:\n>\n> ```ts\n> const a = new NitidaClient({ …, tenantId: 15 });\n> a.urlFor(asset, \"md\");   // → https://8ok.uk/f/v/<sha>-m.webp   ✅\n>\n> const b = new NitidaClient({ …, tenantId: 4 });\n> a.urlFor(asset, \"md\");   // → https://8ok.uk/4/v/<sha>-m.webp   ❌ 404, no error\n> ```\n>\n> It affects everything that carries a tenant segment — `urlFor`, `srcSetFor`,\n> `getAssetUrl`, and the private `/a/{tenant}/…` tree. Public `transform()` has no tenant\n> segment, so it is unaffected.\n>\n> In a multi-tenant process (a BFF, a cron, a migration) use **one process per tenant**,\n> or call `setTenantId(n)` immediately before each block of URL building. Holding two\n> clients and trusting each to remember its own tenant does not work.\n| only a DTO — a component, a Server Component, a worker | **`getTransformUrl(asset, opts)`** | no client needed. Call `setCdnBase()` / `setTenantId()` once at module load first |\n\nSame builder underneath, same URL out. If you are holding a client, use its\nmethod — reaching for the standalone one there means passing the tenant twice\nand losing signing.\n\n```tsx\nimport { NitidaClient } from \"@nitida/sdk\";\n\nconst aq = new NitidaClient({ /* ... */ });\nconst asset = await aq.assets.byHash(sha256);\n\n// Single URL\n<Image\n  src={aq.transform(asset!, { width: 1280, format: \"auto\" })}\n  alt=\"...\"\n/>\n\n// Responsive — one transform URL per width, all other params shared\n<Image\n  src={aq.transform(asset!, { width: 1280 })}\n  srcSet={aq.transformSrcSet(asset!, [640, 960, 1280, 1920])}\n  sizes=\"(max-width: 768px) 100vw, 50vw\"\n  alt=\"...\"\n/>\n```\n\n### DSL params\n\n| Param | Values | Default |\n|---|---|---|\n| `width` | a **`TransformWidth`** — predefined ladder; off-ladder → compile error (see note) | — |\n| `height` | `1`–`7680` (`number`; aspect ratio derived from `width`) | — |\n| `fit` | `cover` / `contain` / `fill` / `inside` / `outside` | `cover` |\n| `gravity` | `auto` / `face` / `center` / `north` / `south` / `east` / `west` | `center` |\n| `format` | `auto` / `avif` / `webp` / `jpeg` / `png` | `auto` (→ `webp`) |\n| `quality` | `auto` / `1`–`100` | `auto` (source-complexity-adaptive) |\n| `dpr` | `1` / `2` / `3` | `1` |\n\n> **`width` is strongly typed.** `TransformOptions.width` is a **`TransformWidth`** — the\n> predefined CDN ladder below, exported as `TRANSFORM_WIDTHS`. An off-ladder width is a\n> **compile error**.\n\n<!-- BEGIN GENERATED: transform-widths · bun run gen:docs -->\n`96, 128, 160, 180, 240, 256, 320, 400, 480, 600, 640, 800, 960, 1080, 1200, 1280, 1440, 1600, 1920, 2560, 3840` — 21 widths.\n<!-- END GENERATED: transform-widths -->\n\n> ⚠️ **The type is narrower than the edge, on purpose.** The edge whitelists a\n> longer list (28 today — its own 400 response enumerates them, and `512`, `768`,\n> `1800`, `2160`, `2400`, `2700`, `2880` and `3600` all serve 200 unsigned). So a\n> width outside the TYPE is not automatically a 400; a width outside the EDGE's\n> list is. Signing is the only way to an **arbitrary** width — not to every width\n> outside `TransformWidth`. Need an arbitrary one? **Sign it** —\n> `aq.transform(asset, { width: 1490 }, { sign: true })` and `getSignedTransformUrl` take\n> `SignedTransformOptions` (where `width` widens to `number`); a valid `?sig=` earns the\n> edge-whitelist bypass.\n>\n> ⚠️ **Signed widths have two ceilings the edge does not announce** (measured\n> 2026-08-24):\n>\n> 1. **7680 is the hard cap.** `7680` → 200, `7681` → 400. Unsigned, the real\n>    cap is 3840 — so `3841…4320` is a dead band the old 400 message called\n>    \"in range\", and `4321…7680` works signed while that message called it\n>    impossible.\n> 2. **Above the source width it CLAMPS and still answers 200.** `/t/` never\n>    upscales. Ask for 5000 on an 800 px master and you get **800 px of bytes\n>    with HTTP 200** — no error, no warning. Read `x-transform-dsl` on the\n>    response (it names the width actually used) or size against the source, if\n>    the exact width matters. `transformSrcSet` / `getTransformSrcSet` deliberately keep\n> `number[]` because a responsive ladder may legitimately include DPR-row widths (e.g.\n> `2400`). `height` stays `number` — for the responsive path it's derived from `width`\n> by aspect ratio; only fixed-canvas crops / `genfill` set it explicitly.\n\n`format=auto` resolves to **WebP** by default. Our bench over 100 random\nproduction `lg.webp` samples showed AVIF was 4.5–9.8% **larger** than WebP in every\nsource-size bracket with virtually identical SSIM. The policy is re-evaluated as\nlibavif improves, so `auto` may resolve differently in the future — that is the\npoint of asking for `auto` instead of naming a format.\n\n`gravity=face` detects the highest-confidence face and crops to it with\nsensible padding (50 % of face dimensions on each side, clamped to source\nbounds, keeping the requested aspect ratio). When no face is detected it\nfalls back to saliency-based cropping. The response **always** carries\n`X-Transform-Face`, with one of two values: **`matched`** when a face was found,\n**`fallback`** when it saliency-cropped.\n\n⚠️ Check the VALUE, not the presence. The header is emitted **only for\n`gravity=face`** — with `center` or `auto` it is absent, and that absence does\nnot mean \"no face\". Code that tests for presence is right 0 % of the time on\nphotos that do contain a face. Cost to you:\n~10 ms warm; ~150 ms on the first request after a cold start.\n\n`quality=auto` adapts the per-format quality to source complexity\n(the luminance standard deviation of the source):\n\n| Bucket (stddev) | WebP | AVIF | JPEG |\n|---|---:|---:|---:|\n| simple (< 25) — logos, solids | 55 | 45 | 70 |\n| normal (25–55) — most photos | 70 | 60 | 80 |\n| complex (≥ 55) — busy textures | 72 | 65 | 82 |\n\nValidated on 100 random production `lg.webp` samples: **+15.4 %\nbytes saved vs fixed `quality=80` baseline, |ΔSSIM| 0.0011** (budget\n0.005). The bucket boundaries and the per-format table are server-side\npolicy and may be re-tuned; pass an explicit `quality=` when you need a\nnumber that does not move.\n\n### Canonicalization & caching\n\nURLs with the same params in different order share the same cache entry:\n\n```ts\naq.transform(asset, { width: 480, fit: \"contain\" })\n// → https://8ok.uk/t/fit=contain,width=480/<sha>.webp\n\naq.transform(asset, { fit: \"contain\", width: 480 })\n// → https://8ok.uk/t/fit=contain,width=480/<sha>.webp   (same URL)\n```\n\nThe server canonicalizes incoming DSL the same way the SDK does (sort keys\nalphabetically, lowercase string values, drop `undefined`) and hashes the\ncanonical string into the cache key — so even non-SDK URLs (e.g. typed\nby a developer in a browser bar) collapse onto the same cache entry as long\nas they specify the same params.\n\n### Signed URLs + strict mode (Phase 3)\n\nEvery tenant has an HMAC-SHA256 signing key — 32 random bytes, generated\non tenant creation.\n\n> **Where you get it: the response that created your project, once.**\n> `POST /admin/projects` returns `signingKey` next to the three API keys, and\n> the console shows it in the same panel. Save it with the keys — nothing else\n> hands it out. In particular `GET /admin/projects/:code` does **not** return\n> it, and neither does any tenant-scoped endpoint.\n>\n> **Your project already exists and you never saw a signing key?** Then you\n> never got one: projects created before 2026-08-23 were not handed it, and\n> there is no endpoint that shows you the current one. This is the exact wall\n> to hit, so here is the way through it:\n>\n> - **If you have not signed any URLs yet** — which is true of every project\n>   that has not shipped private assets — ask us to rotate. Rotation returns a\n>   key, and with nothing in flight it invalidates nothing. It is free.\n> - **If you already have signed URLs in circulation**, rotation kills them.\n>   Ask us for the current key instead; we can read it.\n>\n> Either way it is one request to us, because\n> `POST /admin/projects/:code/rotate-signing-key` needs the system-scope key\n> the platform operator holds — your own admin key answers\n> `403 SYSTEM_KEY_REQUIRED`.\n\nOptionally enable `strict_transforms = true` to reject unsigned URLs\nwith a 401 — useful when transform URLs leak from a private surface\n(internal admin, b2b portal) and you don't want third parties\ngenerating arbitrary crops.\n\n```ts\nconst aq = new NitidaClient({\n  endpoint:   process.env.AQUIENPZ_URL!,\n  apiKey:     process.env.AQUIENPZ_API_KEY!,\n  tenantCode: \"your-tenant\",\n  tenantId:   42,\n  // Handed to you once, by the response that created the project.\n  // do NOT ship to the browser.\n  signingKey: process.env.AQUIENPZ_SIGNING_KEY!,\n});\n\n// Async when { sign: true } is set — overload returns Promise<string>.\n// `expiresInSeconds` is REQUIRED: a signature with no expiry is a bearer\n// token with no expiry. 120 s minimum, 7 days maximum.\nconst signed = await aq.transform(\n  asset,\n  { width: 1280 },\n  { sign: true, expiresInSeconds: 3600 },\n);\n// → https://8ok.uk/t/width=1280/<sha>.webp?kid=<8-hex>&exp=<unix>&sig=<64-hex>\n\n// Responsive\nconst srcset = await aq.transformSrcSet(\n  asset,\n  [640, 960, 1280, 1920],\n  {},\n  { sign: true, expiresInSeconds: 3600 },\n);\n```\n\nSignature shape:\n\n```\nmessage = \"nitida/transform/v2\\n<tenantId base36>\\n<exp>\\n<canonical-DSL>/<filename>\"\nsig     = HMAC-SHA256(signingKey, message)      // hex\nkid     = HMAC-SHA256(signingKey, \"nitida/kid/v1\").slice(0, 8)\n```\n\nThe server canonicalizes the URL the same way the SDK does (sort keys,\nlowercase strings), so two URLs with the same params in different order accept\nthe same signature.\n\n`kid` names the key so a rotation does not kill URLs already in flight: the\noutgoing key keeps verifying for 14 days\n(`POST /admin/projects/:code/rotate-signing-key` returns the new key, its `kid`,\nand when the previous one retires). The rotation runbook lives in the private\nsource repository — ask the platform owner if you need it.\n\n> ⚠️ **A signature does NOT widen the ladder.** Off-ladder widths are 400 at\n> the edge whether or not the URL is signed. Until `@nitida/asset-client`\n> 0.22.0 a valid-looking `?sig=` skipped the edge whitelist entirely, so a\n> signature bought an arbitrary width up to 7680 px — one request measured at\n> 1 850 MB. What a signature buys now is IDENTITY: which tenant asked, proven\n> with its key, until `exp`. That is what `strict_transforms` and the\n> `effect=genfill` cost guard require.\n\n## Private assets — `visibility`\n\nEvery asset carries `visibility`, and the default is `\"public\"`.\n\n| | `\"public\"` | `\"private\"` |\n|---|---|---|\n| stored variants, raw, HLS ladder, transforms | served to anyone with the URL | **404**, to everyone |\n| how the bytes come back | the URL | a signed URL under `/a/{tenant}/…?exp&sig` |\n| expiry | none | mandatory |\n| edge caching | shared, effectively free | `private`, per-viewer |\n\n```ts\n// Flip it (write scope):\nawait fetch(`${endpoint}/assets/${assetId}/visibility`, {\n  method: \"PATCH\",\n  headers: { Authorization: `Bearer ${apiKey}`, \"X-Tenant-Code\": code,\n             \"Content-Type\": \"application/json\" },\n  body: JSON.stringify({ visibility: \"private\" }),\n});\n\n// Hand a viewer the bytes — ON YOUR BACKEND:\nimport { getPrivateAssetUrl, getPrivateTransformUrl } from \"@nitida/sdk\";\n\nconst url = await getPrivateAssetUrl(asset, \"lg\", signingKey, {\n  expiresInSeconds: 300,\n});\n// → https://8ok.uk/a/5/v/<sha>-l.webp?exp=…&sig=…\n\n// …or any width/crop/format, not just the materialised ones:\nconst resized = await getPrivateTransformUrl(\n  asset,\n  { width: 1280, format: \"webp\" },\n  signingKey,\n  { expiresInSeconds: 300 },\n);\n// → https://8ok.uk/a/5/t/format=webp,width=1280/<sha>.webp?exp=…&sig=…\n```\n\nNothing moves when you flip it: one row changes and the edge cache for that\nasset is purged, so a 1 GB video flips as fast as a thumbnail. It is the same\nsingle copy behind both doors.\n\n**Four things worth knowing before you rely on it:**\n\n1. **A 404 on a private asset is the feature, not a missing file.** Everywhere\n   else here a 404 means the object was never written. Check `visibility` on\n   the DTO before you check storage.\n2. **The SDK refuses instead of handing you a URL that 404s.** `getAssetUrl`,\n   `getAssetSrcSet`, `getTransformUrl`, `getTransformSrcSet`,\n   `getVideoTransformUrl` and `getHlsStreamingUrl` all throw when the value you\n   pass says `visibility: \"private\"` — with a message naming\n   `getPrivateAssetUrl`. Pass only `{ sha }` and there is nothing to check.\n3. **Revocation is \"within a minute\".** Flipping back to `private` really does\n   kill URLs already handed out — the edge is purged — but the CDN refreshes\n   its list of private assets on a 60-second TTL.\n4. **The signing key is a backend secret.** It mints URLs for every private\n   asset the tenant owns. It is a different claim from the transform `?sig=`\n   above, computed under a separately derived key, so a signature minted to\n   resize can never be replayed as one to enter.\n\n### ⚠️ Admin operations need the SYSTEM key, not the admin key in your triplet\n\nBoth are `amk_ad_*`, and that is the whole trap. The `admin` key issued with\nyour tenant is **tenant-scoped**: it manages your assets and cannot touch\n`/admin/projects/*`. Verified 2026-08-21:\n\n```\ntenant admin key  → GET /admin/projects → 403 SYSTEM_KEY_REQUIRED\n                    \"API key … is tenant-scoped; this endpoint requires a\n                     system-scope key\"\nsystem admin key  → GET /admin/projects → 200\n```\n\nThere is exactly one system-scope key and we hold it. **These calls are ours to\nrun, not yours** — ask, and we run them. They are documented here so you know\nwhat exists and can name what you want done, not so you can copy the `amk_ad_`\nout of your own triplet and get a 403 that reads like a broken credential.\n\n```bash\n# Rotate the signing key — invalidates every URL signed with the old one.\ncurl -X POST -H \"Authorization: Bearer <SYSTEM amk_ad_...>\" \\\n  https://api.nitida.gofuture.space/admin/projects/your-tenant/rotate-signing-key\n# → { ok: true, tenantId, code, signingKey: \"<64-hex>\" }\n\n# Flip strict mode on/off.\ncurl -X PATCH -H \"Authorization: Bearer <SYSTEM amk_ad_...>\" -H \"Content-Type: application/json\" \\\n  -d '{\"enabled\":true}' \\\n  https://api.nitida.gofuture.space/admin/projects/your-tenant/strict-transforms\n```\n\n**Rotation cost**: cached transform variants are NOT re-keyed by\nthe signature, so they keep serving the same bytes. Only the URLs your\nconsumers hold need re-signing. Coordinate the rotation with anyone who\npre-signs at build time (e.g. SSG / next-build).\n\n### Background removal (`effect=removebg`)\n\n```ts\n// Full-resolution transparent PNG cutout\nconst url = aq.transform(asset, { effect: \"removebg\" });\n// → https://8ok.uk/t/effect=removebg/<sha>.png\n\n// Cut out + resize in one call\nconst thumbUrl = aq.transform(asset, { effect: \"removebg\", width: 400 });\n// → https://8ok.uk/t/effect=removebg,width=400/<sha>.png\n\n// Or convert format alone (no resize / no effect) — useful e.g. to\n// force a JPEG copy of a WebP source for legacy email clients\nconst jpegUrl = aq.transform(asset, { format: \"jpeg\" });\n// → https://8ok.uk/t/format=jpeg/<sha>.jpg\n```\n\n`effect=removebg` runs on one of two server-side matting backends, chosen\nper deployment. What the caller sees:\n\n- **CPU matting** (default) — ~1-2 s warm, ~5-7 s cold. No per-image cost.\n- **GPU matting** — ~3-8 s, ~$0.001-0.005 per image, better edges on hair\n  and fine detail.\n\nEither way the contract is the same, and the first request is the only one\nthat pays. In both cases the route caches the PNG under the standard\n`<sha>-t<dslHash>.png` key, so subsequent identical requests are 302\nredirects to the CDN — no inference, no per-image cost. **Always\nforces `format=png`** because the entire point is preserving alpha.\n\nThe output is the same dimensions as the source. Chain with `width`\nto resize the cutout in a single request (cached as one entry per\ncanonical DSL).\n\nThe matting model is server-side and may be swapped for a better one\nwithout any change on your side — the URL, the PNG-with-alpha output and\nthe cache semantics are the contract.\n\n### Generative fill / aspect outpaint (`effect=genfill`)\n\n⚠️ **`genfill` only works on SIGNED URLs.** It is a cost guard: the effect runs\na generative model per unique tuple. Without `{ sign: true }` the edge answers\n`401 {\"error\":\"signature_required\"}` — whether or not your tenant has\n`strict_transforms`, and unlike `width=` or `effect=removebg`, which serve 200\nunsigned. You need the project's **signing key** (see *Signed URLs*); for a\nproject created before 2026-08-23, ask your operator — it cannot be recovered\nafterwards. Every example below therefore passes `{ sign: true }`.\n\nExtend a source image into a different aspect ratio without the\nawkward edge mirroring that classic content-aware fill produces.\nPrimary use case: building OG cards (1200×630) from portrait listing\nphotos, or 1:1 social tiles from 16:9 originals.\n\n```ts\n// 1200×630 OG card from a portrait listing cover — the gutters are\n// generated, the source is pasted centered.\nconst ogUrl = await aq.transform(\n  asset,\n  { effect: \"genfill\", width: 1200, height: 630 },\n  { sign: true },                       // ⚠️ sin esto: 401 signature_required\n);\n// → https://8ok.uk/t/effect=genfill,height=630,width=1200/<sha>.webp\n\n// 1:1 social tile from a landscape original\nconst tileUrl = await aq.transform(\n  asset,\n  { effect: \"genfill\", width: 1080, height: 1080 },\n  { sign: true },\n);\n```\n\n**Requires both `width` and `height`.** Without them the route returns\n422 — the effect needs an explicit target canvas to know what to\noutpaint. ⚠️ You only ever see that 422 **after** signing: unsigned, the 401\ncomes first, so a missing `{ sign: true }` looks like a different bug than it\nis.\n\n**Output defaults to WebP** at q=85 (~150KB for a 1200×630 OG card —\n12× lighter than the raw generated PNG). Honors `format=` for\nexplicit overrides:\n\n| Format | Bytes (typical 1200×630) | Use case |\n|---|---|---|\n| `format=webp` (default) | ~150KB | OG cards, social tiles, storefront cards |\n| `format=png` | ~1.7MB | Lossless — print, marketing fold-outs |\n| `format=avif` | ~120KB | Modern browsers, even better compression |\n| `format=jpeg` | ~180KB | Legacy email clients |\n\n**Real-estate caveat**: outpainting is mediocre when the target aspect\ndiffers heavily from the source (1:1 from horizontal photo → tiled\nartifacts because the model has to invent rooftops and floors).\nReserve `genfill` for SMALL aspect deltas (OG card 1200×630 from\nlandscape source ✓). For bigger crops, prefer `gravity=auto` smart-crop,\nwhich is deterministic and free — no generation, no invention.\n\n**What it costs you: ~$0.05 for the first request** per (sha, dsl, format)\n⚠️ **The signature guards GENERATION, not DELIVERY.** Once a signed transform\nruns, its result is written to `/{tenant}/v/<sha>-t<dslHash>.<ext>` and served\nthere **with HTTP 200 and no `?sig=`**. `<dslHash>` is `sha256(canonical DSL)`\ntruncated to 16 — **no secret in it**, so anyone who guesses the DSL derives the\nURL. Measured: a signed `width=641` (unreachable unsigned) went from 404 to 200\nat the derived path after a single signed GET.\n\nTwo consequences worth planning around: turning on `strict_transforms` does not\nun-publish anything already generated, and for `genfill` — whose entire cost\nguard is the signature — the result you paid for stays publicly readable. Treat\na signed transform as \"pay once, publish forever\", not as an access control.\n\ntuple. Subsequent identical requests are 302 redirects to the cached WebP —\nzero generative cost, forever. The model is server-side and may be swapped\nfor a better one without any change on your side; the DSL, the output and\nthe cache semantics are the contract.\n\n**Short-circuit**: when the source already matches the target aspect\nexactly (resized to fill the canvas with zero padding), the server\nreturns the resized PNG without generating anything — you don't pay\n$0.05 for an effective no-op.\n\n### Video transforms (`aq.transformVideo`)\n\nThe same DSL works for videos too — the server branches on the asset's\n`kind` column. Image params (`width`, `height`, `fit`) carry over;\nvideo adds `start` (seconds, decimal OK) + `duration` (seconds, 1..300).\n\n```ts\n// 16:9 source → 9:16 mobile clip, first 15 s, h.264 mp4\nconst portraitUrl = aq.transformVideo(asset, {\n  width: 1080,\n  height: 1920,\n  fit: \"cover\",\n  start: 0,\n  duration: 15,\n});\n\n// WebM output for bandwidth-conscious storefronts\nconst webmUrl = aq.transformVideo(asset, { format: \"webm\", width: 1280 });\n```\n\n**First request is async**. Cache miss → a background transcode runs\n(typically 5-30 s for short clips) → the output is stored. The route\nreturns **202 Accepted** with `Retry-After: 10` and a `Location`\nheader pointing at the eventual CDN URL. The response body has\n`{ status, message, retryAfterSec, outputUrl }`. Subsequent requests\nhit the cache → **302** to the CDN.\n\nConsumer pattern with Video.js v10 / `<video>`:\n\n```tsx\nconst src = aq.transformVideo(asset, { width: 1080, height: 1920 });\n// Pass directly to <video src={src} />. While the transcode runs the\n// browser sees 202 → retry; once cached, the 302 → CDN. Most players\n// retry transparently; if yours doesn't, poll `src` every 5 s until\n// `Response.redirected` is true or the body content-type starts with\n// \"video/\".\n```\n\n**Idempotent** — requesting the same DSL again while the first job is\nstill running does not start a second one, and does nothing at all once\nthe output is cached. Fire and retry freely.\n\n### Adaptive HLS streaming (`aq.streamingUrl`)\n\nFor long-form video — property tours, walkthroughs — point an\nHLS-aware player at the master playlist:\n\n```tsx\n<video\n  src={aq.streamingUrl(asset)}\n  controls playsInline\n  // Video.js v10 ships native HLS via @videojs/http-streaming —\n  // no plugin needed. Same with hls.js or iOS Safari.\n/>\n\n// Sub-clip (HLS ladder built only for the clipped range)\nconst teaser = aq.streamingUrl(asset, { start: 0, duration: 30 });\n```\n\nFirst request to a new HLS URL returns **202 Accepted** with\n`Retry-After: 20` while a background job builds the multi-rung ladder\n(typically 1-3 min for a 90 s source). Subsequent requests get\n**302** to the cached `master.m3u8`. The CDN layout:\n\n```\n<tid>/v/<sha>-hls<dslHash>/master.m3u8        ← entry point\n<tid>/v/<sha>-hls<dslHash>/240p/playlist.m3u8\n<tid>/v/<sha>-hls<dslHash>/240p/seg-000.ts\n<tid>/v/<sha>-hls<dslHash>/360p/...\n…\n<tid>/v/<sha>-hls<dslHash>/1080p/...\n```\n\nThe ladder shrinks to fit the source: a 480p source produces three\nrungs (240p / 360p / 480p), a 1080p source produces five, and a 4K\nsource goes up to 2160p.\n\n> ⚠️ **Clips under 18 seconds are the exception, and they are common.**\n> A short source is restricted to the 720p–1080p band on purpose, so an 8 s\n> 720p clip gets **one rung**, not four — the rung-switching a ladder exists\n> for cannot happen inside a clip that short, and building five of them just\n> burns transcode budget. Read `switchable` on the ladder rather than\n> `rungs.length`: it is `false` exactly when there is nothing to switch\n> between. A test asserting `rungs.length > 1` will fail on every short clip. The player picks the right rung on the fly\nbased on the current connection — a user on 3G starts at 240p and\nclimbs to 1080p as bandwidth improves, vs the monolithic MP4 that\neither loaded or timed out.\n\n### Billing model\n\nTransforms are billed as **storage**, not as \"transformations\" the way\nCloudinary does — one stored object per unique canonical DSL, then served from\nthe CDN cache forever (until manually invalidated). The cache key is\ndeterministic, so identical DSLs across deploys/tenants don't re-encode;\nmounting an existing CDN URL costs zero compute.\n\n## Palette + LQIP (compact placeholder UX)\n\nEvery successfully decoded image gets a palette extracted alongside\nthe upload — a tiny 7-color set you can use for ambient gradients,\nfallback backgrounds, or themed UI accents. It survives across all\npreset selections (yes, even `presets: [\"original\"]`), because\npalette is metadata derived from the source bytes, not from a\nspecific resized variant.\n\n```ts\nimport {\n  getPaletteBlurBackground,\n  pickAmbientBackground,\n  getAmbientGradient,\n  getTextColorForBackground,\n} from \"@nitida/sdk\";\n\nconst asset = await aq.assets.get(assetId);\n//   asset.palette = { d: \"#1a1a1a\", v: \"#c5a95e\", m: \"#8b7d4f\", ... }\n//   asset.blur    = \"data:image/webp;base64,UklGRhAA...\"  // tiny LQIP\n\n// Compact 4-stop gradient for hero / card backgrounds:\nconst bg = getAmbientGradient(asset.palette);\n//   bg = \"linear-gradient(135deg, oklch(...), oklch(...))\"\n\n// Auto-pick text color that contrasts with the chosen ambient:\n// ⚠️ `getTextColorForBackground` toma UN SWATCH, no la paleta entera.\n// Pasarle `asset.palette` tira `TypeError: … evaluating 'hex.replace'`.\nconst bg = pickAmbientBackground(asset.palette);   // PaletteSwatch | null\nconst fg = getTextColorForBackground(bg);\n//   fg = \"#fff\" | \"#000\" | similar\n\n// Or just the blurry LQIP for a CSS background placeholder:\nconst placeholder = getPaletteBlurBackground(asset.palette);\n```\n\nThe wire format is intentionally tight: `{d, v, m, dv, lv, dm, lm}`\n(dominant, vibrant, muted, dark-vibrant, light-vibrant, dark-muted,\nlight-muted) — **up to** 7 hex strings per asset, much smaller than a full\nbase64 LQIP but composing into nicer ambient UX.\n\n⚠️ **Only `d` (dominant) is guaranteed. Every other key is optional**, because\nonly the swatches the source actually had get extracted — measured across 30\nassets, palettes carry anywhere from 2 to 7 keys. Never index one directly:\n`palette.dv` on a 2-swatch palette emits\n`linear-gradient(135deg, #1a1a1a, undefined)`. Use the helpers\n(`pickAmbientBackground`, `getAmbientGradient`, `getPaletteCssVars`), which skip\nthe missing ones.\n\nWhen the image can't be decoded (SVG sources, exotic formats,\ndeliberately corrupted bytes), palette + blur silently come back\n`null`. The rest of the pipeline still succeeds.\n\nPer-slot default:\n\n```ts\nawait aq.slots.bind(\"storefront.hero\", { assetId, preset: \"lg\" });\n```\n\nPer-call override (the resolver respects this over the slot's default):\n\n```ts\nconst { url } = await aq.slots.resolve(\"storefront.hero\", { preset: \"md\" });\n```\n\nResponsive `<img srcSet>` across all available presets:\n\n```tsx\n<img\n  src={aq.urlFor(asset, \"lg\")}\n  srcSet={aq.srcSetFor(asset)}\n  sizes=\"(max-width: 768px) 100vw, 1280px\"\n  alt=\"\"\n/>\n```\n\nIf you need a dimension that doesn't exist, two options: use the closest\npreset and let the browser scale, or file an issue to add it to the\nserver-side pipeline (a platform-wide addition, not a per-tenant one).\n\n### ⭐ What happens when two tenants upload the SAME image\n\nDedup is **content-addressed and cross-tenant**: the sha is a hash of the bytes,\nso if you and another customer upload the same logo, the same stock photo or the\nsame placeholder, you share a candidate row. This is normal, not exotic.\n\nA `/t/…` transform URL names **content**, not a tenant — there is no tenant\nsegment in it. Three consequences follow, and all three are measured behaviour:\n\n**1 · A signed transform is resolved by the SIGNATURE, not by tenant id.**\nThe signature proves possession of one specific tenant's key, which is exactly\nthe identity the URL lacks. Before `2026-08-25` the lowest tenant id won, so a\ncorrectly signed URL could be verified against someone else's key and answer\n`invalid_signature`. Nothing to do on your side — just know the signature is\nwhat disambiguates.\n\n**2 · `strict_transforms` fails CLOSED across every tenant that shares the sha.**\nIf any tenant holding those bytes requires signed URLs, the unsigned request is\nrefused — because an unsigned request cannot say which tenant it belongs to, and\npicking the most permissive one would let a third party defeat your policy.\n\n> ⚠️ The cost, stated plainly: if you do **not** use `strict_transforms` but you\n> share content with someone who does, that sha needs a signed URL from you too.\n> The alternative — failing open — means your own strict setting is silently\n> cancelled by a stranger. A 401 you fix by signing is the cheaper mistake.\n\n**3 · Making an asset private does NOT unpublish another tenant's public copy.**\n`visibility: \"private\"` retracts **your** row. If another tenant uploaded the\nsame bytes and left them public, that copy keeps serving, and a `/t/` request\nresolves to it. No new information leaks — those exact bytes were already public\n— but do not read \"private\" as \"these bytes are now unreachable\". It means\n\"reachable through me only by signature\".\n\n> If that distinction matters for your content, the answer is not a flag: it is\n> not to share the bytes. Anything unique to you (a customer photo, a document,\n> a render) has a unique sha and never collides.\n\n### CDN URL format\n\n`<cdnBase>/<tenantId base36>/v/<sha16>-<presetCode>.<ext>`\n\nExample: `https://8ok.uk/f/v/<sha16>-q.webp` — the `thumb` preset of a 16-hex\nsha as WebP, for **tenant 15** (`15` in base36 is `f`).\n\n> `<sha16>` is a placeholder on purpose. A concrete sha pinned here rots: the\n> previous example pasted a **real tenant-4 URL with the prefix swapped to\n> `f`**, so it 404'd on every preset while the identical path under `/4/` served\n> 200. Substitute a sha from your own tenant — `upload()` returns it as `sha`.\n\n⚠️ **The tenant segment is not optional, and it is base36.** `/15/…` 404s;\nso does a bare `/<sha16>-q.webp` with no tenant at all. Nothing serves that\nshape — it is not a legac","readmeFilename":"README.md"}