{"_id":"@astratra/saas-kit","_rev":"14-d07c49f82498dfa651b61564c86de3f8","name":"@astratra/saas-kit","dist-tags":{"latest":"1.6.0"},"versions":{"0.1.0":{"name":"@astratra/saas-kit","version":"0.1.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@0.1.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"d2bb517abde01498752e0021ca4978a888e625d4","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-0.1.0.tgz","fileCount":14,"integrity":"sha512-8uLk9FV2W9vHFGufuaoHUQF2086ksg29hlUgCOtdwZ4ty/2stKbOI7jZKpwFp7E5Z/9YPxgKQXEMuGNYjQ5nOw==","signatures":[{"sig":"MEUCIARdA3m3DTOOK4Yr+6pn8In8fFDh5BW/L/cPD59mOTw8AiEAxmuA16LhTHG61QU8eaLR7y3f+16lMlM65ItD2ush7mI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22120},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","gitHead":"1e576a2e512d525705894c42f7269882b6a09a7f","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.5.1","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"22.18.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^0.1.0","jsonwebtoken":"^9.0.2","@astratra/core":"^0.1.0","@astratra/security":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_0.1.0_1786200651485_0.12339011861227833","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@astratra/saas-kit","version":"0.1.1","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@0.1.1","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"78b647f830157994f5c691bcb404b9d5f92e70ba","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-0.1.1.tgz","fileCount":14,"integrity":"sha512-O4vQRgXPrpQgqijXjVFlrxWWlwpfuT/jpo8VIyAeWw6KJ3GBJ7QLYbWVFetFKmzu3Ml3p3dlj8OJz1ctsUhrTg==","signatures":[{"sig":"MEQCICXRYueF5XbY3XnNPbs6wxDU0M8CbEbUkCb/or6gQTJ1AiAl/t0AM57QsbmhUTzTQ3TIhOjm1GOrXSOX/GHTUH+HKQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22911},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","gitHead":"3dfad5e70e112fe97862f776b0472f5e7f003815","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^0.1.0","jsonwebtoken":"^9.0.2","@astratra/core":"^0.1.0","@astratra/security":"^0.1.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_0.1.1_1786205086095_0.015453637704392564","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@astratra/saas-kit","version":"1.0.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.0.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"2ddcfd4f933439ad126c2e821ecce3ee0db08f94","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.0.0.tgz","fileCount":14,"integrity":"sha512-IWtHTjdavLrVnEzk8qmmTapWJ3t3xa1FOusNgaZcSCQCjeTT48nRz36l/gX+79FdDdDFrRK7E3mi0hN23z4zJg==","signatures":[{"sig":"MEUCIEE/uNUS9l9zTYPsSSrdyG9xGqM6TP5R7vudxo6tJg4UAiEA0HOGcKRNpSxZ5mNVjbZ4LPcBoQvtayQsktKxqK8Yh/4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24713},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","gitHead":"e4ba5847cd3342fd9398c867592b762f852a8ef8","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.0.0_1786210242837_0.7350841202075069","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@astratra/saas-kit","version":"1.0.1","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.0.1","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"c206489e18853714aa1b0ebd267c18b0986a7032","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.0.1.tgz","fileCount":14,"integrity":"sha512-VhyuFiVQ80pdajHrzrPOylOgzsEmNdhDs8MNA4IpTa28plY0XafFXJLM40BTRPfFbM5niF2/j/9odyc+z5vM+A==","signatures":[{"sig":"MEUCICZhC725sO/3V4MYG3q4QlcCglwPufUgO3f12rdKuSl2AiEAhJYidZq4/A31JTO0oRccU7/hK+hPA8s06aEuEkzE7fo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25812},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","gitHead":"84e6d3922bbfd6bba1a1fa386a44c6c83e733ade","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.5.1","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"22.18.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.0.1_1786212757157_0.4738807052269347","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@astratra/saas-kit","version":"1.0.2","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.0.2","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"7d49dfc7ec1fba2c6d66069d7369cfa23b3dabc6","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.0.2.tgz","fileCount":14,"integrity":"sha512-L/tqlng83AO6jip0E0omni6Pe3Tzkz4nQIj2TSNNWsfnee0yOjYQYcV2YMXXwbF36GosdKekBuPwul8VZyLWBg==","signatures":[{"sig":"MEYCIQDIvxKrO8nRcfLXhp89U+sRqB3eNUWA0HBXwic4mlYLYgIhAPDCcB+U33yRYikwdcY4XDWGRBwXIgRNFfhBwL/V+NGS","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25812},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","gitHead":"da1b28e8cf2c0c81fe409448d7d8b1abab02fa6e","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.0.2_1786282220828_0.40548914598795216","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@astratra/saas-kit","version":"1.1.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.1.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"08ec9962e62bcfa963aed6288f0ffa9d4818e91e","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.1.0.tgz","fileCount":14,"integrity":"sha512-AGIVHnvrii8NG7nyKa9mgXJUIoiAmlSESrWEpKUMZoEXpIZdJGGCR4nAXUUri0jnQJmnq1GjNh4hAOi1SCBgYA==","signatures":[{"sig":"MEYCIQCCIIm68+GNGV54rlBG60hlTy1hlJRXGqRo8pGmH89pzAIhAIxLT87E3C+kdTJdxIhzpAMPHPR6GFCYtCLCDxWlvM+7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31067},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","gitHead":"c3cb3a78991262c04fa4e02f4cdccba504768b2a","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.1.0_1786297069600_0.5725629350849759","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@astratra/saas-kit","version":"1.1.1","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.1.1","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"ea03dad456ec7f934c6ecb42681d09bc1bece8b1","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.1.1.tgz","fileCount":14,"integrity":"sha512-1/7G/HmHOhu3zwHtpFQE4888FKY1b0hpc9UM9M7WNlnm3DepRBMSmOd4LilyWDoE1NfG+pqXggZ7M0GuR52oDg==","signatures":[{"sig":"MEUCIQDMQJBzXfscadlFnXZ5/arjrxFLN63pdCsWKyI3voVYJQIgPo4FUTp5jKbDQyDW1fxyS/iZYMefEe57F/Lj57OKvik=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":31106},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"c0f1cf78836764168bbbeabdebb1574f2ec68543","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.1.1_1786297877331_0.4082242201168882","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@astratra/saas-kit","version":"1.2.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.2.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"75ed2051c8f64ab2d0c5bfa22a2e7ce24f852f98","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.2.0.tgz","fileCount":14,"integrity":"sha512-j7VyVBT8dRjYtDvYfI403zyhaYbn/FKEWuedfMFrc+J1AHEi1J+T6uMsgPOvGSYj95wSmWfwFbYygcW4FdcwGw==","signatures":[{"sig":"MEUCIQCZCSqKvgbKa0THv3jCLBeYzOcDIKXWj82zTQVpxNa7bQIgWfpV/31A3ZDy9OIYHd6GgD0lsrH+NzZEt83MI46UEGM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35312},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"72a778d3c75b7fc4bc7f9da64bb8ab6fd13c81f0","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.2.0_1786733846934_0.8904696160358785","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@astratra/saas-kit","version":"1.3.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.3.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"459ca24074509b207ee7d7d5d1412308b36d2ea1","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.3.0.tgz","fileCount":14,"integrity":"sha512-/Q0X3tyDLyITTCtU0LD5D4S1AWzvCjMJETqHu5R4dg9kYaIw/SeoWQEWDj1G+PyZl6GcyVfCGPwTvsMaQJ4TUQ==","signatures":[{"sig":"MEYCIQDBzD+tNDTKZnx/Ll9qAxzvi9SCKycoO5YrrxaGDZBMbAIhAJwtude7gHMVY6MVIvc6aAsZ+ap1ZhIUc1lXHUqN8xuO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":37099},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"7f7af2b1ed9f7fbcffa2c0a710885625f224d18b","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.3.0_1786735648710_0.7251122196114304","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@astratra/saas-kit","version":"1.4.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.4.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"ad0b8091dfe823cec3ce184b3b00e03a88679228","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.4.0.tgz","fileCount":14,"integrity":"sha512-OqcTjavUPpPSt9p9R6BuCNdBDIFIW488bZn3GzZIkZ7Kq9kB3DfjOrXRkvHR6jAzte0Ns11TDx50s8hNuU9YAw==","signatures":[{"sig":"MEQCIFr5zlU9yekLutkxEuj2WDOwU2aRR/3S9ieM/mg10Ci6AiA2EISaDFT7pctMIk9zxvubgbApHWSgG4tueeAJX2H+ew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38863},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"530705b0609c79552379ded37365aaac5b712707","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.4.0_1786739408760_0.5972148040012482","host":"s3://npm-registry-packages-npm-production"}},"1.4.1":{"name":"@astratra/saas-kit","version":"1.4.1","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.4.1","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"1404adb86c94a878fbed9a756a2052ee2f139f83","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.4.1.tgz","fileCount":14,"integrity":"sha512-6Gg/x3+jDIxePe92EcTfJJDsG55LgAoBi1wVZk9Tkr+NCwV/AcgWZg6KpOGP1VGlo1JIdkrCL4KquJD5oFowcA==","signatures":[{"sig":"MEUCIQC8MXjSsKY0MOzHAoPwFwNBnyOn61k4+e9LUGwQDTqSOAIgYK7UemelLOXr213A74+/3VguRefUt70fLyx76+aI2kc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38863},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"66cb6d0bbd26fba26cbe62c8f01756bf2c078afe","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.5.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.4.1_1786751030334_0.979660208451858","host":"s3://npm-registry-packages-npm-production"}},"1.5.0":{"name":"@astratra/saas-kit","version":"1.5.0","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.5.0","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"74ff0bc01112a94ae1ee4f699f1c7a866d2f9a05","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.5.0.tgz","fileCount":14,"integrity":"sha512-Th9dJ2AISobHU61WQD2Co8+jUEoxyp6+wrPT2cMf6etUovkiMj86Zc/LRloOJAQrvGclbDNcNqfZQDfScVylNQ==","signatures":[{"sig":"MEYCIQC7UHLYdo6VWgFzePCHgq4X3qNQJAIGITjSIFARcU6uJwIhAP6dfkfgiJxaxQgzYxK1cvGsh5EwF7RZD9tFIZ0nJ1Wk","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":42791},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"80411079da8516d644f2a47e5438e7a6d3678893","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.6.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.5.0_1787056063045_0.634007417182032","host":"s3://npm-registry-packages-npm-production"}},"1.5.1":{"name":"@astratra/saas-kit","version":"1.5.1","keywords":["astratra","saas","starter"],"license":"MIT","_id":"@astratra/saas-kit@1.5.1","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"dist":{"shasum":"af61d5ace793819d8493febeee3bd51c9bf0e234","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.5.1.tgz","fileCount":14,"integrity":"sha512-y/bWj6WE1trFaO46mfIL1Uqp5QNzll8rJPxxwXhiQDcYnXunCtWaMiRSbM8C7cBoswkR30+v96p1e8ZW71XbTA==","signatures":[{"sig":"MEUCIQC9RREfuihLGCGuWwMP7ni3nV2O5ON/bPaG+V+OmJ1rXwIgMb5yOmie31RDOqw/MCLt8G0QnPxnrFcdroGva2fwMp4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43382},"main":"src/index.js","type":"commonjs","types":"src/index.d.ts","engines":{"node":">=20"},"gitHead":"cfb638d1b0e952a580bed08236f60d0b57a02998","scripts":{"test":"node --test __tests__/*.test.js"},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"_npmVersion":"11.13.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","directories":{},"_nodeVersion":"24.16.0","dependencies":{"express":"^4.18.3","@astratra/ai":"^1.0.0","jsonwebtoken":"^9.0.2","@astratra/core":"^1.0.0","express-validator":"^7.3.2","@astratra/security":"^1.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"supertest":"^7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/saas-kit_1.5.1_1787216605107_0.7014950834752227","host":"s3://npm-registry-packages-npm-production"}},"1.6.0":{"name":"@astratra/saas-kit","version":"1.6.0","description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","engines":{"node":">=20"},"main":"src/index.js","types":"src/index.d.ts","type":"commonjs","scripts":{"test":"node --test __tests__/*.test.js"},"keywords":["astratra","saas","starter"],"license":"MIT","publishConfig":{"access":"public"},"dependencies":{"@astratra/ai":"^1.0.0","@astratra/core":"^1.0.0","@astratra/security":"^1.10.0","express":"^4.18.3","express-validator":"^7.3.2","jsonwebtoken":"^9.0.2"},"devDependencies":{"supertest":"^7.0.0"},"gitHead":"597c98161c5fc076a7575eaa0a3bd3cdfd5cb132","_id":"@astratra/saas-kit@1.6.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-d/fLsMqyZc44NDevFBXIX+RpQBAyRfP9UaYvpv0Z+ueEifgfbUmppBHde40Zm6ECWTl5i19D/qlcrvNl95MLqg==","shasum":"ae6307e192322849b8536ba70b0ae2e4c8bb0750","tarball":"https://registry.npmjs.org/@astratra/saas-kit/-/saas-kit-1.6.0.tgz","fileCount":16,"unpackedSize":60992,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHA2GZFQkK8G5kSidUl3KyrgBcNtwWlVg+5P/Emld2FRAiEAtV+jt65PH2G1BFRPMjyazu/9kxyPViZUGSIvQW4imcw="}]},"_npmUser":{"name":"emch99","email":"emchkongo@gmail.com"},"directories":{},"maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/saas-kit_1.6.0_1787768559474_0.9330879381520105"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-08T14:50:51.149Z","modified":"2026-08-26T18:22:39.858Z","0.1.0":"2026-08-08T14:50:51.623Z","0.1.1":"2026-08-08T16:04:46.262Z","1.0.0":"2026-08-08T17:30:42.980Z","1.0.1":"2026-08-08T18:12:37.299Z","1.0.2":"2026-08-09T13:30:20.972Z","1.1.0":"2026-08-09T17:37:49.758Z","1.1.1":"2026-08-09T17:51:17.489Z","1.2.0":"2026-08-14T18:57:27.089Z","1.3.0":"2026-08-14T19:27:28.880Z","1.4.0":"2026-08-14T20:30:08.909Z","1.4.1":"2026-08-14T23:43:50.498Z","1.5.0":"2026-08-18T12:27:43.189Z","1.5.1":"2026-08-20T09:03:25.252Z","1.6.0":"2026-08-26T18:22:39.638Z"},"license":"MIT","keywords":["astratra","saas","starter"],"description":"Reusable backend starter kit that assembles Astratra core, security, and AI packages.","maintainers":[{"name":"emch99","email":"emchkongo@gmail.com"}],"readme":"# @astratra/saas-kit\n\nStarter backend réutilisable pour démarrer une nouvelle API SaaS avec les\npackages Astratra.\n\n`createSaasApp(options)` retourne une app Express avec des routes\ngénériques auth, users, settings, notifications et dashboard. Il assemble :\n\n- `@astratra/core` pour les request IDs, le format de réponse API, le 404 et\n  la gestion d'erreurs.\n- `@astratra/security` pour les primitives JWT/RBAC, le rate limiting, une\n  CSP restrictive par défaut, le WAF heuristique et le service WebAuthn\n  optionnel.\n- `@astratra/ai` en dépendance du package pour qu'un projet puisse composer\n  des fonctionnalités IA à côté du starter, sans que le kit n'impose de\n  routes IA métier.\n\n## Démarrage rapide\n\n```js\nconst { createSaasApp } = require('@astratra/saas-kit');\n\nconst app = createSaasApp({\n  jwtSecret: process.env.JWT_SECRET,\n  jwtAlgorithms: ['HS256'],\n  jwtIssuer: 'mon-app',\n  jwtAudience: 'mon-api',\n  usersStore,\n  settingsStore,\n  verifyPassword: async (user, password) => passwordService.verify(user, password),\n  notify: async (userId, notification) => notificationService.send(userId, notification),\n  roles: {\n    adminRoles: ['owner', 'admin']\n  }\n});\n\napp.listen(3000);\n```\n\nÇa donne immédiatement à un nouveau projet une API fonctionnelle :\n\n- `POST /auth/login`\n- `POST /auth/logout`\n- `POST /auth/logout-all`\n- `GET /auth/me`\n- `GET /users`\n- `GET /users/:id`\n- `POST /users`\n- `PATCH /users/:id`\n- `GET /settings`\n- `PATCH /settings/:key`\n- `POST /notifications/send`\n- `GET /dashboard/summary`\n\nToutes les routes protégées suivent le même ordre de middlewares de\nsécurité que la mini-app de démo : request id, journal d'événements de\nsécurité (`options.securityAudit`, actif par défaut), parseur de cookies,\namorçage CSRF, CSP (`default-src 'none'` par défaut, adapté à une API JSON\n— surchargeable via `options.csp`), en-têtes de sécurité standard\n(`options.securityHeaders` — X-Frame-Options, X-Content-Type-Options,\nReferrer-Policy, Permissions-Policy, HSTS en production), parseur JSON, WAF\nheuristique, limiteur API, limiteur de login pour `/auth`, auth JWT (cookie\nou `Authorization: Bearer`) pour les modules protégés, CSRF pour les routes\nmutantes, puis 404 et gestion d'erreurs.\n\n`jwtAlgorithms` vaut `['HS256']` par defaut. `jwtIssuer` et `jwtAudience` sont\noptionnels, mais recommandes des qu'une app sort du simple developpement local.\n\n## Ajouter tes propres routes\n\n`createSaasApp()` termine sa propre pile de middlewares par un\n`notFoundMiddleware`/`errorMiddleware` avant de te rendre l'app. N'ajoute\ndonc **pas** tes routes avec `app.get(...)` / `app.use(...)` sur l'objet\nretourné — elles tomberaient systématiquement sur ce 404 interne, puisque\nExpress évalue sa pile dans l'ordre d'enregistrement. Passe plutôt\n`options.extendRoutes` : il s'exécute avant ce 404, avec les mêmes instances\n`authMiddleware`/`csrfMiddleware`/`authorizeAdmin` que les routes intégrées.\n\n```js\nconst app = createSaasApp({\n  // ...\n  extendRoutes: (app, { authMiddleware, csrfMiddleware, authorizeAdmin }) => {\n    app.get('/api/products', authMiddleware, listProducts);\n    app.post('/api/products', authMiddleware, authorizeAdmin, csrfMiddleware, createProduct);\n  }\n});\n```\n\nL'app retournée expose aussi directement `app.authMiddleware`,\n`app.csrfMiddleware` et `app.authorizeAdmin`, au cas où tu préfères les\nmonter toi-même après coup plutôt que via `extendRoutes`.\n\n## CORS\n\n`options.cors` active le CORS pour toute l'app en un seul champ de\nconfiguration — origines autorisées, credentials, headers/méthodes — sans\nmiddleware à écrire ni à monter toi-même. Astratra ne fixe pas de liste\nd'origines par défaut (chaque projet a la sienne), mais gère le montage :\n`createCorsMiddleware` (`@astratra/security`) est posé tout en premier,\navant absolument tout le reste, garantissant que les en-têtes CORS\ns'appliquent à chaque route — y compris la réponse de preflight `OPTIONS` :\n\n```js\nconst app = createSaasApp({\n  // ...\n  cors: { allowedOrigins: [process.env.WEB_ORIGIN] }\n});\n```\n\nS'applique aussi bien aux routes intégrées (`/auth`, `/users`, ...) qu'à\ncelles ajoutées via `extendRoutes`. Omets `options.cors` et rien ne change —\ncomme avant, à toi de gérer CORS si tu en as besoin.\n\n**Derrière un reverse proxy (nginx, un load balancer...)**, passe aussi\n`trustProxy` — sinon Express ignore `X-Forwarded-For` et voit l'IP du proxy\npour absolument tous les visiteurs, y compris dans les rate limiters\nci-dessous (`apiRateLimit`, `loginRateLimit`) : un seul client \"vu\", donc un\nseul quota partagé par tout le monde. Trouvé sur un projet consommateur\ndéployé derrière nginx, en production, via le monitoring d'erreurs — pas en\ndev, où il n'y a pas de proxy pour révéler le problème.\n\n```js\ncreateSaasApp({\n  // ...\n  trustProxy: 1 // fait confiance à exactement un saut de proxy (nginx)\n});\n```\n\nNon défini par défaut (comportement Express standard, inchangé) — dépend du\ndéploiement, Astratra ne peut pas le deviner à ta place.\n\n`apiRateLimit`/`loginRateLimit` sont transmis tels quels à\n`createApiLimiter`/`createLoginLimiter` (`@astratra/security`) : pour isoler\nleurs compteurs sur une même instance Redis, fournis un store namespacé via\n`createRedisRateLimitStore({ redisUrl, prefix })` :\n\n```js\nconst { createRedisRateLimitStore } = require('@astratra/security');\n\ncreateSaasApp({\n  // ...\n  apiRateLimit: {\n    store: createRedisRateLimitStore({ redisUrl, prefix: 'mon-app:rate:api:' })\n  },\n  loginRateLimit: {\n    store: createRedisRateLimitStore({ redisUrl, prefix: 'mon-app:rate:connexion:' })\n  }\n});\n```\n\nLe cookie CSRF (`astratra_csrf`) est amorcé automatiquement sur toute\nrequête sûre (GET/HEAD/OPTIONS) dès le démarrage de l'app — y compris tes\npropres routes `GET` ajoutées via `extendRoutes` — donc pas besoin de monter\n`csrfMiddleware` toi-même sur des routes qui ne font que lire.\n`csrfMiddleware` reste nécessaire sur tes routes mutantes (POST/PATCH/DELETE)\npour valider le token.\n\n## Session cookie HttpOnly, CSRF et révocation\n\n`POST /auth/login` pose toujours un cookie `HttpOnly` (`astratra_session` par\ndéfaut) en plus de renvoyer `{ token, user }` en JSON — le cookie sert les\nclients web, le token JSON sert les clients API/mobile. Le nom, `sameSite`,\n`secure`, `path`, `domain` et la durée de vie du cookie se configurent via\n`options.cookie` :\n\n```js\ncreateSaasApp({\n  // ...\n  cookie: { name: 'ma_session', sameSite: 'strict' },\n  csrf: { headerName: 'x-csrf-token' } // optionnel, défauts déjà sensés\n});\n```\n\nToutes les routes mutantes protégées (`/users`, `/settings`,\n`/notifications`, `/dashboard`, `/auth/logout(-all)`, `/auth/webauthn/*`)\nexigent un token CSRF (cookie non-`HttpOnly` `astratra_csrf` + header\n`x-csrf-token`) **sauf** pour les clients authentifiés par `Authorization:\nBearer` (mobile/API — non exposés au CSRF) et `POST /auth/login`\n(pas de session préexistante à protéger).\n\n`POST /auth/logout` invalide immédiatement le JWT courant (via un\n`revocationStore` en mémoire fourni par défaut — remplaçable par\n`options.revocationStore` pour une prod multi-instance, ex. Redis).\n`POST /auth/logout-all` invalide tous les JWT actifs de l'utilisateur, pas\nseulement celui de la requête courante.\n\n## Rester connecté, réinitialiser, notifier un téléphone\n\nTrois choses qu'une application mobile réclame et qu'une application web n'a\npas toujours. Les trois sont **éteintes par défaut** ou montées seulement quand\ntu fournis ce qu'il faut : une app fraîchement générée démarre sans\nconfiguration.\n\n### Rafraîchissement de session\n\n```js\ncreateSaasApp({\n  refreshTokens: { enabled: true, ttlMs: 30 * 24 * 60 * 60 * 1000 }\n});\n```\n\n`/auth/login` renvoie alors un `refreshToken` en plus du `token`, et\n`/auth/refresh` l'échange contre un couple neuf. Le mécanisme est celui de\n`@astratra/security` : rotation à chaque usage, empreinte en base, et un rejeu\nrévoque toute la chaîne issue de cette connexion.\n\nÉteint, la route `/auth/refresh` **n'existe pas** — le client web sur cookie\n`HttpOnly` n'en a pas besoin, et lui donner un identifiant à longue vie qu'il\nn'utilise jamais ne ferait qu'élargir la cible.\n\nSe déconnecter révoque aussi la chaîne : révoquer le seul jeton d'accès\nlaisserait la session revenir au prochain renouvellement.\n\n### Mot de passe oublié\n\n```js\ncreateSaasApp({\n  hashPassword: async (password) => bcrypt.hash(password, 12),\n  passwordReset: {\n    send: async ({ user, token }) => mailer.send({\n      to: user.email,\n      subject: 'Réinitialiser votre mot de passe',\n      text: `https://app.exemple.cd/reset?token=${token}`\n    })\n  }\n});\n```\n\nSans `send`, les routes ne sont **pas montées du tout** : accepter des demandes\nqui ne partent nulle part en répondant « c'est envoyé » est le pire des deux\nmondes.\n\n`/auth/forgot-password` répond **toujours pareil**, adresse connue ou non.\n« Aucun compte avec cet e-mail » transforme l'écran en annuaire : on lui donne\nune liste, il dit gratuitement lesquelles ont un compte ici.\n\n`/auth/reset-password` consomme le lien (usage unique — consommer **supprime**)\net **révoque toutes les sessions** de la personne. C'est l'étape qu'on oublie :\nquelqu'un qui réinitialise son mot de passe est peut-être en train de reprendre\nun compte volé, et laisser vivre les sessions du voleur rend l'opération vaine.\n\n### Enregistrement des téléphones\n\n```js\ncreateSaasApp({ devicesStore });   // adaptateur mémoire par défaut\n```\n\n`POST /notifications/devices`, `GET /notifications/devices/:installationId`,\n`DELETE /notifications/devices/:installationId` — le contrat qu'attend\n`@astratra/native` côté application.\n\nCes routes sont **avant** le garde d'administration du module : enregistrer son\npropre téléphone n'est pas un acte d'administration, c'est ce que fait toute\napplication mobile au démarrage. Chacune est bornée à `req.user.id`, jamais à\nl'identifiant de l'URL — un identifiant d'installation se devine.\n\n## Validation des entrées\n\n`POST /auth/login`, `POST /users`, `PATCH /settings/:key` et\n`POST /notifications/send` valident leur payload via\n`validateMiddleware` (`@astratra/core`) et `express-validator` avant\nd'appeler ton store — email au bon format, champs requis réellement présents\n(pas juste \"truthy\"), longueurs raisonnables sur les champs texte libres\n(titre, message). Une entrée invalide renvoie `400` avant même de toucher\n`usersStore`/`settingsStore`/`notify`. Le kit ne valide que les champs qu'il\nconnaît lui-même — le reste du payload (champs propres à ton store) passe\ntel quel, sans schéma imposé.\n\nÇa ne couvre que les routes intégrées ci-dessus. Pour tes propres routes\n(via `extendRoutes`), voir « Anti-injection Mongo » juste en dessous —\nappliqué automatiquement, lui, à toute la surface de l'app.\n\n## Anti-injection Mongo (par défaut, y compris `extendRoutes`)\n\n`createMongoSanitizeMiddleware` (`@astratra/security`) est monté\nautomatiquement, sans configuration, sur `req.body`/`req.query`/\n`req.params` — retire toute clé `$...` (opérateur Mongo) ou contenant un\n`.` avant qu'elle n'atteigne une route, **y compris les tiennes** ajoutées\nvia `extendRoutes`. Trouvé sur un projet consommateur réel : une route\npersonnalisée passait `req.query.date` tel quel dans un filtre Mongoose, et\n`?date[$gt]=` (notation crochet du parseur `qs` d'Express) devenait un\nopérateur Mongo choisi par l'appelant plutôt qu'une simple chaîne — la\n« Validation des entrées » ci-dessus ne protège que les routes intégrées,\npas le code que tu ajoutes toi-même.\n\n```js\ncreateSaasApp({\n  // ...\n  mongoSanitize: false // désactive complètement, si besoin\n});\n```\n\n## Adapters requis\n\nUne vraie application en production doit injecter ses propres adapters. Le\nkit ne choisit ni base de données, ni algorithme de hash de mot de passe, ni\ncanal de notification, ni rôles spécifiques à un produit.\n\n```js\nconst usersStore = {\n  findByEmail(email) {},\n  findById(id) {},\n  create(userData) {},\n  list({ role, limit, offset }) {},\n  update(id, patch) {}\n};\n\nconst settingsStore = {\n  get(key) {},\n  set(key, value) {},\n  getAll() {}\n};\n```\n\n`verifyPassword(user, password)` est également injecté, pour que\nl'application consommatrice garde la main sur le hashing et les règles de\ncredentials. `notify(userId, { title, message, channel })` est injecté pour\nque la livraison puisse être un email, un push, une notification in-app, ou\ntout autre canal.\n\nLes routes WebAuthn ne sont montées que si `webauthnStore` est fourni. Le\nstore est transmis au service WebAuthn de `@astratra/security`.\n\n## Stores mémoire — développement uniquement\n\nLe package exporte :\n\n```js\nconst {\n  createMemoryUsersStore,\n  createMemorySettingsStore\n} = require('@astratra/saas-kit');\n```\n\nCes stores servent uniquement au développement local, aux démos et aux\ntests. Les données restent en mémoire process, ne sont pas persistantes, et\nsont perdues au redémarrage. À remplacer avant toute utilisation en\nproduction.\n\nSi `usersStore` ou `settingsStore` sont omis, `createSaasApp` utilise ces\nstores mémoire dev-only pour que le starter démarre immédiatement.\n`verifyPassword` et `notify` sont toujours injectés par l'app\nconsommatrice ; le kit ne fournit ni algorithme de mot de passe ni\ncomportement de livraison de notification.\n\nSi `revocationStore` est omis, `createSaasApp` utilise de la même façon\n`createMemoryRevocationStore()` de `@astratra/security` (pas mémorisé entre\nprocess, ni partagé entre instances). Pour une prod multi-instance, fournis\nton propre store implémentant la même interface (Redis, etc.) via\n`options.revocationStore`.\n\n## Tableau de bord\n\n`GET /dashboard/summary` retourne uniquement des stats génériques de\nplateforme :\n\n```json\n{\n  \"userCount\": 2,\n  \"roleBreakdown\": {\n    \"owner\": 1,\n    \"member\": 1\n  }\n}\n```\n\nLes KPI spécifiques au projet doivent être ajoutés par l'app consommatrice,\nen dehors de ce kit.\n\n## Tests\n\n```bash\nnpm test --workspace @astratra/saas-kit\n```\n\nLes tests d'intégration utilisent `node --test` et exercent l'app Express\nsans ouvrir de vrai listener réseau, ce qui les rend exécutables dans des\nsandboxes restreintes.\n","readmeFilename":"README.md"}