{"_id":"storage-mixin","_rev":"310-f0b4765d93457f81668f36abb616741a","name":"storage-mixin","dist-tags":{"experimental":"0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18","latest":"5.1.5","next":"0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d"},"versions":{"0.0.1":{"name":"storage-mixin","version":"0.0.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.0.1","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"bb55797ade8e1f6a39653baef9734f4fc772d7b4","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.1.tgz","integrity":"sha512-vO9W10yTAMYnON1M6d5GFMJy7HnSx0zqkI/Rs7b9vr8igY0QHUQi/ZXVH91CPIKCw7wU9AeNOahZ3RmnTpmy+Q==","signatures":[{"sig":"MEYCIQDh1pS56xKNSMzk/2Libb1D7HCrCA1hdQ2YlgKpjqJgEwIhAIGj+TL/0vG4YQdRbICJJT6z57U3T+8LSd06V1Gfgi4U","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"bb55797ade8e1f6a39653baef9734f4fc772d7b4","gitHead":"a13802979f76387d30566d341041270fc213a09e","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"}},"0.0.2":{"name":"storage-mixin","version":"0.0.2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.0.2","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"976fa9a17ebe7b7a251691f5e7f27f5b7dc87bf3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.2.tgz","integrity":"sha512-Kwgk2ypMPrdLWVty5gO2qccLGGSgITAz35uB6HEShiGEt6Mvs25SHbcFYziErxngSDWn4LculMcmKgTR0Q+Jaw==","signatures":[{"sig":"MEQCIBCqol3KPql9Y9Je9FaScrKMdszsqGwnePk2YJHQ3TN5AiBA+K5N93BlcEtgdtycGuk9+IJGb36zyKVturbjeqA5Ig==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"976fa9a17ebe7b7a251691f5e7f27f5b7dc87bf3","gitHead":"4b3ce7b0b6e503780b2e49e0d49a0b7ef2b1086f","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"}},"0.0.3":{"name":"storage-mixin","version":"0.0.3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.0.3","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"7e5a562bc9a95c7e8998de6f66228217ad98b9ef","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.3.tgz","integrity":"sha512-IM3sLm2Bzy2NiNXdh0c6FORQRiu9DZ3A7cl2XqfjYwhzs/miSVmbE/VG9wrEh205PegZPU+K/Y/jo8yGnTrS9g==","signatures":[{"sig":"MEYCIQDqfXQKgNykcwgiVlcja0xB8OrjrQxcy2mCJrFtYMxZRwIhAP71SKTweHW07UGvI4q/TzlTm6NHuuSFTxFoKAWJXLxC","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"7e5a562bc9a95c7e8998de6f66228217ad98b9ef","gitHead":"f1d8f69a7589e2ab7d5be8fa7f9c2a45b9f8a26e","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"}},"0.1.0":{"name":"storage-mixin","version":"0.1.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.1.0","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"f05d168061489ec9fcf2217789c1dd3fa1a493fb","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.1.0.tgz","integrity":"sha512-6uCpEH9FyO2NemmEECzLq7o7EGsdpKjooS02YDTXsyINE/Q4WJW24Yiq/4FHGtgMplaLOWuL9dMez/rrYXQgbw==","signatures":[{"sig":"MEUCIQDXP1WtuMv+pai3nbXt6IszKEjH85Me/fXl192k3KNgNgIgMa/cJtp0ReViB08rZBzjo9VM2324zC5j4aWClsOXgBc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"f05d168061489ec9fcf2217789c1dd3fa1a493fb","gitHead":"de6414bdc05a6ba23fd6606604df1512c6b0a71f","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"}},"0.2.0":{"name":"storage-mixin","version":"0.2.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.2.0","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"3df03a81a657fdd6a559394938e322a073008442","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.2.0.tgz","integrity":"sha512-3hjDmoqLqEIVDL19z3AKqTwRYJJGid1P/MNjTnUQPKfr9dCVM3IJfDUgAZ36t8c+JJBEWkGvKE/hil4PjlaRQg==","signatures":[{"sig":"MEYCIQC0/62Jhf13iJpZxOfbEzdKWbbDJSaAuzTPON0k8IucCAIhAKRgFT4CSNJRYgmBQ7LBTvtBRH3I/WDchNcLA6G29VdK","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"3df03a81a657fdd6a559394938e322a073008442","gitHead":"7b6b52f7e68929c3986a715e700bf83be07b6690","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","keytar":"github:mongodb-js/node-keytar#compass-production","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"}},"0.2.1":{"name":"storage-mixin","version":"0.2.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.2.1","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"5b51818c94ad08ddfe7dffe928eb233ff808fa21","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.2.1.tgz","integrity":"sha512-/bm8Pl/Vw0t0q3aoy8MsefsRcNgf4TX/MruLkRSwaFfJd6YZhvE25oXtBBRVwH7YBi3cDqhr/efQWau8zx/UoQ==","signatures":[{"sig":"MEQCIC4JUDw6Sh8/jlNKKJrxbl86LGOLNPA50pwXdiyJUHmYAiBDmNAC4qwtYYVuZLNJbx3i+W4crCm+/ciyHuij5ik5oQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"5b51818c94ad08ddfe7dffe928eb233ff808fa21","gitHead":"3c596841cf2aa5d0730031555373f5eb7f8dd016","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","keytar":"^3.0.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"}},"0.3.0":{"name":"storage-mixin","version":"0.3.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.3.0","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"8069fc36322bc73dba8b58695114144c03cc9567","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.3.0.tgz","integrity":"sha512-bUq9BbEWuxRuQi8VRA7KGtuWF/xI4kuyWTXLdXIsE81hbmM7ytB2ILOMNUKIKUZS9SdJRdAWMCzos9ltgpnyzw==","signatures":[{"sig":"MEQCIEIGwsR8+31QAJxukSBhsUNwQPDdZydxZZnDmfLuwUO4AiBio9VmTLKWmTtGdhTWND+j7BYcbDPVkccNiLCDqCpdWg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"8069fc36322bc73dba8b58695114144c03cc9567","gitHead":"7d15cea5fe165e47c59de55972215fed99e3baec","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"}},"0.3.1":{"name":"storage-mixin","version":"0.3.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.3.1","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"d7070d4efdddb6371e83685adb9f4394ae6afe60","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.3.1.tgz","integrity":"sha512-QtZbhW4sMF3bHuEz0j2dL0QFgRYYxS5Ar5SK1mSUlPgo8+sOQ1yAUsBPhL1PSgakwWfa+/AX584ZCycSWOiHeg==","signatures":[{"sig":"MEUCIQD/bjc7sNNnQnzceptaFd50LMPKFlaYl04hketH3rB6pgIgAOZbBp43PXcIjKrlj/Yho0b7Prp3uRsvALNR7iXIopM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"d7070d4efdddb6371e83685adb9f4394ae6afe60","gitHead":"de2e8ba08244956072d0b75aac37f6662a47d821","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"}},"0.4.0":{"name":"storage-mixin","version":"0.4.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.4.0","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"3f4ffef4ec10b02a44b42c159c8603020dd7a836","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.4.0.tgz","integrity":"sha512-J09B8MIH5f1+wDfy9aUXdQpJscCpI1XuHw/4ga8FzFTtSjl2pCRSLVmriLveqliKqXRJOJrFBV61TLITb1f/3g==","signatures":[{"sig":"MEYCIQD9n/Ko66tMOIaTB7Qd86ddoEEtx5igKCkXSnxfvrXSBAIhAKVNweECN24V4KbvEeGDhfYXGd5MVO2P468MEOkzyOX9","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"3f4ffef4ec10b02a44b42c159c8603020dd7a836","gitHead":"82f9ff77fcae151ca9fe319bdbca31aba51dc4a5","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"}},"0.5.0":{"name":"storage-mixin","version":"0.5.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.5.0","maintainers":[{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"a463a634adf362b580da285a2e58bcfc42dc04a0","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.5.0.tgz","integrity":"sha512-frlgES3v1rouUymiPUS2tRbI8IWgG9ZCL9gbWQQJf9C+3c8UbZzBFAaqPaQbwtK8WgLyK3idhJVVrMlA8TELVw==","signatures":[{"sig":"MEQCIHC/Hq0A9OWaEE5ihd1tu7YiyP8ISq6X3f58/2Sam0IuAiBm3ql3f0fXdn7VdjfCnHFXBZ/Z02+3CXIvzooVw7B+sQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"a463a634adf362b580da285a2e58bcfc42dc04a0","gitHead":"7fed23e141eb7af4a8e9df398e41b3065b16f7b5","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"}},"0.5.1":{"name":"storage-mixin","version":"0.5.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.5.1","maintainers":[{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"c46204e75c9db3df5bf2e7fddd5ab3169a010efb","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.5.1.tgz","integrity":"sha512-muuvZxFjhzpKX3Ykd+45XiCsWcN3zLhSLTU8Wu+V7XDiII8jQatJJquE0KU+9bdpIRc5CGGvj/+cAmfFaBG3Sw==","signatures":[{"sig":"MEUCIElHInhLLplOc+wSyTFQ6J0f0r28l3a2Xqg1UpLU0xOHAiEAuEEvf+/EDe0Ei1lWKj5Xk/yjpPyccRVtmqSOO5Gc19s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"c46204e75c9db3df5bf2e7fddd5ab3169a010efb","gitHead":"2c9c9f1ff6166cefd3460e1b1b6ae47c9eb835c0","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.5.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"4.2.2","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"}},"0.6.0":{"name":"storage-mixin","version":"0.6.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.6.0","maintainers":[{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"51ff720df0a81773817b85e0f3e938164115be68","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.6.0.tgz","integrity":"sha512-WWAE7TqGAmivpGYFjaDYJ4OaV/RzGArW3ouIxS42vPqIktk181pFbU9iXHERApCz7LwEr6dFqFiGpmWXc2j2Ew==","signatures":[{"sig":"MEUCIQDIkWD4Zudb1B0JeOQI7/tWZiP0VWewSKm/gKxC9rwGwQIgTkPJ/U1sTCFS7qCNxtgX+/jzh5La9I0vKwKn3ZbSSBc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"51ff720df0a81773817b85e0f3e938164115be68","gitHead":"1cd1247896232d531d7790a4609064b3a0202d42","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.6.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"5.7.0","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.6.0.tgz_1461549042893_0.9715508464723825","host":"packages-12-west.internal.npmjs.com"}},"0.6.1":{"name":"storage-mixin","version":"0.6.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.6.1","maintainers":[{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"7fb843e079b13ac801f97e955b74ae289cc516f2","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.6.1.tgz","integrity":"sha512-yZa6/CuY+vMl8u1Nrr9fP9lCPpZPNya2ztb7DdrIY+w22i31Knsb9eneEw0eWgOpwjQsUbCA2afl4T4umUTgfw==","signatures":[{"sig":"MEUCIQDZFuOeGA4W7JKmHrNGAV8gNYFvn5jWNeaKOr+1vHvfEwIgGsTya3YSzgJTB+/xSTd+tSB+sxEUcMx2BJrmPnLg0lM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"7fb843e079b13ac801f97e955b74ae289cc516f2","gitHead":"a876caf1eefd2e61183d58654ba1dfc885f679c8","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.6.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"5.7.0","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.6.1.tgz_1461802627421_0.6538054919801652","host":"packages-12-west.internal.npmjs.com"}},"0.6.2":{"name":"storage-mixin","version":"0.6.2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.6.2","maintainers":[{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"3572242f4d15907cd113b8835ac0867fbd1d7be6","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.6.2.tgz","integrity":"sha512-Rr+50MPNxHQRNbtFZLskv8/Eex38kGb449i2fG2DnBHOt5mAseOCWYAda8nN17TSAdu7oS6j3gmYkD/UsV+QJw==","signatures":[{"sig":"MEQCIHp/iceMODOmGlorpsF887ZiY4fNMdhdUAWEOgAUXIJAAiA6OX6HSYhwGnZn/BK9GZfBiy5WjGWA2g2dAVvCp35ETg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"3572242f4d15907cd113b8835ac0867fbd1d7be6","gitHead":"4c79c00161ac8a1d26f4d8485bbb512ef8080c44","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.6.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"5.7.0","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^3.10.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.6.2.tgz_1466186039263_0.7575269981753081","host":"packages-16-east.internal.npmjs.com"}},"0.7.1":{"name":"storage-mixin","version":"0.7.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.7.1","maintainers":[{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"0a834be31877f35b053a601dc265bd66ed1d4eab","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.7.1.tgz","integrity":"sha512-LOcHET+j8xeOazg0+LvkP+P0avBCYas2TjB1wA8SecicAI5mkALVg61zdidH/23833gQOfp2CHPm/JKb36Jx5Q==","signatures":[{"sig":"MEYCIQD64PPo55OCszxINMgaX4FXM0Rl24MS1LkhHeC5HlDSVwIhALAo0U6z8yDHzDTL9715TJBVjTdxP9IUvHOF9V/G6mDZ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"0a834be31877f35b053a601dc265bd66ed1d4eab","gitHead":"fe265fcd8e2da5e347d17609fd73bb5acfd5bba2","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.8.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"5.11.1","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.7.1.tgz_1467050816686_0.48809685558080673","host":"packages-12-west.internal.npmjs.com"}},"0.7.2":{"name":"storage-mixin","version":"0.7.2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.7.2","maintainers":[{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"6903db96b90054a9851aecbdcfbb5ba3b0cac7be","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.7.2.tgz","integrity":"sha512-pCnxWKjwblegiGPWnG66Sij5OvEgepHlMAk9YWYD2ArtM6VdDSEg6fgHUBY0zK/F66hD/qjh+Nd9x2hAF287Gw==","signatures":[{"sig":"MEQCICwd+lM7IDZexwTTIZe7qyXqwXWGAcAWgKtzoXFjjRWLAiB/p5JUx68f5XcKt5JXS9tJpD0kBNEl8+KnGCJlHsVibA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"6903db96b90054a9851aecbdcfbb5ba3b0cac7be","gitHead":"dc6fbf3e2864ed2b9fe69340850d20124cc64938","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.8.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"5.11.1","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^0.6.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^0.34.3","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.7.2.tgz_1467051139938_0.5942023587413132","host":"packages-12-west.internal.npmjs.com"}},"0.8.0":{"name":"storage-mixin","version":"0.8.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.8.0","maintainers":[{"name":"durran","email":"durran@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"100922b4e46e7bca248792342f3cbbb1a3c0f746","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.8.0.tgz","integrity":"sha512-eJdfhZ0+HoI/9Ufdx3Eha//72kSc5xkaYDq8tH//IZ1kH8PkhcthlYxmhOqfEfXVmN2q7pvkYNinGntj4nLfwA==","signatures":[{"sig":"MEUCIBuoRoRnWZLEcIVAB1044doRbKXe+7H2rS1K2tEz0KnzAiEAtrAO9RF/rVYxd9FErDsyvPS1obtV2n3MZ6jiZwokBmU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"100922b4e46e7bca248792342f3cbbb1a3c0f746","gitHead":"7ae83723f7a53bf0f5f16b8c70ce22e4cf7b39c4","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.8.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"5.12.0","dependencies":{"async":"^1.5.0","debug":"^2.2.0","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^2.3.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^1.2.8","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^1.0.5"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.8.0.tgz_1469526586006_0.9968738430179656","host":"packages-16-east.internal.npmjs.com"}},"0.8.1":{"name":"storage-mixin","version":"0.8.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@0.8.1","maintainers":[{"name":"durran","email":"durran@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"mongodb-js-user","email":"lucas.hrabovsky+mongodb-js@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"3605a2c7ac115683279a8395cacca9fc5e99dbc2","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.8.1.tgz","integrity":"sha512-tIWwwj9Xav+mWX12hr0khpU2xrI7sHTcczZXm07zsnUMhZVMjzeVNLPZ+NHle9ujDU+oNDbzvEUFquCV/OYgkg==","signatures":[{"sig":"MEUCIQDG8UDjTSJJ6UuVlCGmgraS17DZTawKozkxg+gikPX0SwIgCCVOIZLoFLM2x1poMIcGqwcOI+9s5GrNiO5XoRi8dbE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","_shasum":"3605a2c7ac115683279a8395cacca9fc5e99dbc2","gitHead":"888d42d76b1680c54a3921be571e415390ed132c","scripts":{"ci":"npm run check && npm test","fmt":"mongodb-js-fmt ./*.js ./test/*.js","test":"electron-mocha --renderer && mocha","check":"mongodb-js-precommit"},"_npmUser":{"name":"rueckstiess","email":"thomas@rueckstiess.net"},"precommit":["check"],"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"3.10.3","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"6.3.1","dependencies":{"async":"^1.5.0","debug":"github:mongodb-js/debug#v2.2.3","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"devDependencies":{"mocha":"^2.3.3","pre-commit":"^1.1.2","electron-mocha":"^2.3.1","mongodb-js-fmt":"^0.0.3","electron-prebuilt":"^1.2.8","mongodb-js-precommit":"^0.2.5","eslint-config-mongodb-js":"^2.2.0"},"dependency-check":{"ignore":["keytar"]},"peerDepdendencies":{"keytar":"^3.0.0"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin-0.8.1.tgz_1479876159867_0.6803499313537031","host":"packages-12-west.internal.npmjs.com"}},"1.0.0-beta.1":{"name":"storage-mixin","version":"1.0.0-beta.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@1.0.0-beta.1","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"d7daeeb6fca774981d6229961543f090bd41b61c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-1.0.0-beta.1.tgz","fileCount":23,"integrity":"sha512-PuiEM6TaLfW2ekclH5b1op0ftk9NI0V+MqIW513ltNuZgIFpIdhcqZ0ApGBCVhy1o3bY/czbYd/Ce2E1hAr10A==","signatures":[{"sig":"MEYCIQDmin1DIfeUcEuO8Y6u9dQSPGT1JMvzSkzPizEs+Iq4TwIhAM0RxhINnmoI37LVxGHsM+y3gOr1C2KlOePKMVcMi0eA","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":69934,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcAFmJCRA9TVsSAnZWagAA1+4QAIjdZU39GpyOA7SnXgum\neEw0Zko78+SfJSl1Pn6Br9SjETx1d0ga9LcZQ3AnXnG76+t1fOF87AFLV1oN\nLaKu9Lmx/3kUGFOY/r0Ls13LuRJImg72upjs2fO4qFtHyt+3HujcTCuHC2wB\ne9qeFNOVkpK14w8vlFHE65SLlyEjNOFDTleBrHYQeIY64DlCTTvveIBjdlLo\na5HmonLdJ4ccAaCdO5Luz18Au2VrcGr7ck4nSOQQ3nwZTWdmi3kLaKMyGBA3\nvx8Lz7hzIcOnKRuv5gbHX/bGxGtsbasbshb9RvkwFfcAapogmBJ5r5tiWaAi\nL38GiHKNLDkXyB87TwAFjaqARdK2CjiFTzqWMSmhR/6s9as62P0AbczzS7ls\nTKSeh6iBGeG6weO4jjWvt7AcPnKcyjRxI47QRR8P4pH+EfF/TxtgfPPb8veQ\nw/GUZKgVk/68tXZmMNjD6gVnWyCxsrveJWq87nOxLnAZEKrKRCjVEeFqofWj\njpnM5yp34Y+jDIirhW2q78rlyI+Tl/8H19GTnFgAka8AfTj1JzVQnpZ/ORhY\n/LKoIcq72VswpasuPci2aSl8DRNzJJgC4KM/2A2wTJUtqRUaqLOQzJZGw7EP\nhKuGpqtn+KYXn8090Vzjs4eMNFINB9AaEyzYMv3StzzqWPYhqXxBUmtaCfJQ\n4X3m\r\n=rFq5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"718796e75bde4fda76731284ba439aceec75d0c3","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha ./test/secure.test.js","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha test/secure.test.js","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.4.0","dependencies":{"async":"^1.5.0","debug":"^4.1.0","keytar":"^4.3.0","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^3.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_1.0.0-beta.1_1543526792537_0.7940750695839944","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"storage-mixin","version":"1.0.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@1.0.0","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"89c1bf6b88dc22c08cad62c5e26fd14f300a56a0","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-1.0.0.tgz","fileCount":23,"integrity":"sha512-/hKcoa++CBHz1Q5IbWtz21Fo5rpXscAxu0oTDtathmdZTkSfHSj6fiqTg+ykrOVGGpOS1grcjvrlfaP4wmBjuQ==","signatures":[{"sig":"MEUCIQCm8/iZ7fccmKns7o2l3EOh19OetCUVnQv9/HfA86ZHewIgJio217Ax4nPB0aca98FZQylBtuSjykmM7Bod0sHABOI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":70797,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcBpIgCRA9TVsSAnZWagAAGgwP/jN/fmcGSF1P/BN5Y8lO\n9o5sl1XqwIRQjIasGT5tVifU5GyguL5SoPNTMBHWWN6VsdV+gsVG8O3OVK2+\nL2KgGgkO/LiUpU/Mrc57Q5tsFCJG3QnrBvF86TExb8Tk9hp7ZOzy6DGuSY+Q\npvfs4NerIdDhtJBc1H4d3v0+AjlpT79gpSe4mgSPjdghP4p3xdhI6nZgMP0D\n5amsAGIEp+Pei9E1daxH8J/odCR3HAVyTmZ7Zw8ziG61fe8amKyhcuWFA+Ky\nPdpYcNSGNASV+Q8pcGXV33AxLHs4KZZqzVOum0+nIbFLzwoRCJ8LMkgHwarr\nwcN2aYzWBlfDhYVczCamd+/Tv4GRsGOrWlEyoKr9rcrvK+owJ7EKqq5zCTxq\n3Y94rQOxSnok7YwZo1x8kR2ZdBl5sbAREpvaZ/2jq0lfftU3djarBPCocULP\nYrqrOpNAFXSMyQzWCj0Kcg893rbJWd0luCo5rp9HoRU3KnFmYQlU5ZFIwTpH\nGwYwh9hluFtYl002sPOeVkD5rKN/ZZ++s0WyLMC+4SUEfHrwR8zm4h7xF59P\nCXaUExOMXzO36s5qza+TKfQlEn3E3Gz955DgkTEkYByg+r7XYCg83N5yIeQa\nokzY1wwTY+cdAtNzGbiIyynkykmxdSVSI38PfW0JKjh4cYKIw+hG0WMqRMjS\nVPis\r\n=Y8dJ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"f06ef7cb51290357e6684a155839002db8603c31","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.4.0","dependencies":{"async":"^1.5.0","debug":"^4.1.0","keytar":"^4.3.0","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^3.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_1.0.0_1543934495811_0.1215573293609733","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"storage-mixin","version":"2.0.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@2.0.0","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"1552e177eed83a6453332eb53df707550ac5ada6","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-2.0.0.tgz","fileCount":23,"integrity":"sha512-fdVUPiLHpRGfimbp9oll2RBo0eDbag86neD6xdYOsb1C0Bn6cSQ1usAP314w4ARHpdlsH9337Q9ZgjNEPPdvjw==","signatures":[{"sig":"MEUCIQDbw5XRwHOiYdAg3AGu9Q3ToO2ciqMzHqlSUudUhqr8pAIgRBv5G1V4Bhddr/vS+oiMLwD+zDRbxtNgjOdHd5Zif74=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":70962,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcc8mYCRA9TVsSAnZWagAA2kgP/1KiAJvKxAqBYN5btySx\n4/RYQuUdSBds7uc3ebbGNa+nfglkv/Od6ZAKFfhYUXpmeHWJJ+/2xeMctJBE\nCQOHbgvV014r+5ui6tbtG5D/UElIcSv2kR6ZG8pUPklQAvQYpRR7R+wDzI2j\nUvISGf/IZmo2Lrcq1mlCBAoNeAGbWyBgHv+e1UdROP+cTzUrf6vc5/eFM1Uw\nEOHWIHrXafJobagGf29ryl4wO5j5EnnxotZbWd2KCZT1C4NUj3xvlCji/n0B\nrBkeRDmXdeLmlsEDuXnU3uTKEqQUVdt8rWpmqQ5GlkEf4T0fkFMbbaMfdvSB\nlx3xg9wPdMYTK95fxUY6Bzx/lnpy/iIM3a2fJ+LgtmMGW7gQgzSJpvqMxIAU\nwb+q93P4MyMFYz2FM35RVxYocBz0q8guFxQ+8DAXPoNBe4Px8VVl6ddXNezR\nZ3dvsQXefUrkwitwf2tOvhsNeaN0eA8e4xjncDk2zh+7hk4M6Ih6iRRTG7wt\n0GbLtnnShlMju5h+eCf3FawHTaGCC7FijH37c0/Xog7VSu86s/HODVdm630A\nvnQCXTC9VCYx9T51lGeP7KcegXSv+KX1m+JLJ8nkq1XpvUUHBVF0Wyl+5nUu\nmD2dVSyzYiuK0T6BxKTwahEkja04GKXBTNap3YTAzuYlozF8S44jsL/3AuDP\nGFqK\r\n=m8/8\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"b62d2e42ba794c2a13614df46fbae3e2970f1629","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"async":"^1.5.0","debug":"^4.1.0","keytar":"^4.3.0","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^3.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_2.0.0_1551092119483_0.10722086989433754","host":"s3://npm-registry-packages"}},"3.0.0":{"name":"storage-mixin","version":"3.0.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.0.0","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"2e51a014cf8c95608cc416b52b18142ac2a09230","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.0.0.tgz","fileCount":23,"integrity":"sha512-Nogiz+nzir4hJBMCOAqwvydHdR5323C2fo8ZWncNGtzjq/vB+eEy7TL/gTKCUG+C8675JgH1YJRfIxKym5QKAw==","signatures":[{"sig":"MEQCIDdebL3/iSRFwHgyYqmhT0YUyTRN7d/wyi9unfFFxZw/AiBn7o8yfhuFRHw67kgmw+tQgukCZIc8+2yM1VcSDQVC8A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":70962,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcmNGbCRA9TVsSAnZWagAAtQYP/3GXk+Rk4phaOQjEHzHw\nBN7JGWK8LJ2oV8HaOb8HtgCnFoWHK8gfAsXtpuqtZHtKeRjcHOMMZk4W5UCP\nAzub6CYd7RvVcEiVL3Grkh7onlwvSO0stHOOCvW1HvM3oXtokGzhvzezoLjb\nYke9iATBoVjcj3pOrms2waLGkkrDqkTLeMVxItP580Vt3dTxg2uL/bTLlwGx\nKBeMKmQCCvHdwITtfJKdpqMthgPBcWQ6yxV6cU4bIlUyetdjrCRyZB5+sI1K\nH2f9OlyKTikLZSmUIadbfdpg0QaeoYa98ibvbnUoOjnn5fbUSrk1RXd5OTGM\n0ZRjvpY266NfWamUbVUEzaToGx7nbUyeA9iDD7JE37/OE2ldQZxQQB6jS68k\nef9MAJhJ8F1Xb7Xqu5J1TScXSPFM/23QpC3MC4EA6p9h7eqjBMzrmoIjDPjd\nCMbSu1mvN+o8PKNyp0+cfGseJHGEvbqPQa5oVe/sZjNncjrwQjhjWVjvhI/r\nSNfbbRQT4NUwtd3SSgZRvGL8h/SLF1taLe8TdZ6Ah75TwXHy387GZp6q+skr\n41x/P0Fy2USwkW+lvI0UucWwKCVtdaVTQezks8qh4ZOOrFYjK8aBmH2MNcNp\n9irOwK7+Fp7nhA2g6YIVNGub+sCDCF4TQarwsPnn3Obae8kEAYg+mH7J2VTE\nLvmU\r\n=DUW2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"1f8c26e6db4738f6f502a9a3286d114364fe9ed8","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.7.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.0.0_1553519002467_0.8806374590049768","host":"s3://npm-registry-packages"}},"3.1.0":{"name":"storage-mixin","version":"3.1.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.1.0","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"8ef721398c7c3edc4693f88ee5f0ceeb60d6db81","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.1.0.tgz","fileCount":25,"integrity":"sha512-PzQ5EfwaKxWBHUOnvG+YUcWbvJ9yfx6JTMtRThekVBLKZwnnjloYhUIMLcKERoeIZVpIYFhh3hfGn/YXqfa0VQ==","signatures":[{"sig":"MEUCIFMg8MZZ02E+mXU6QEKUPOuvrLmEWSjsix0VU2mUQn0CAiEA9zIB6UBW1wHG5gp2/cYsJGUIU0mXYR9fxD6Fe5EOVnk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82733,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdXp2bCRA9TVsSAnZWagAA80wP/1uUuasl1ECRlPoSajMJ\nIAh602heP2hnKyEogfF4EwqMQhaFJwdt4Zb2RMAWDjq0mZ1QsxcEu7bMKhXB\ngxHAOk8IXJj3Wl9JLDry3jtyn5lliCXpiNsYJIjFcUy8gJkKGnxZHsSFPLkv\nAPCIvrW+gpJ4MNowIjMgTAWl8WwuaaGqrgdX41/ZLDekG/ysvHv7sB5XBt4w\nm86VDxeJ0/IMOena3gg+JTbufPSyx2+KW1uiC/Vnq6cX5xNooniZwEKBMCfs\nHocU7mdP/UBn4bwgtY0UcO0QPhEyZ61yQKmfP1riMu4OBX4vvI1JCjR111fn\nZaZVwV85qyK4AsPxzKit/1P9RKG5qNww/AT6g6IUCVN5rUvyP6dKjL3u42li\n8QlPwjQok9GpiJYOEpvsLmcaiZZchjjQTKmZwyG39NQSdTuVeqMbXY3FgLJL\n7GIJZelVGNwMSNFwyTUhakdsJMpYijTSMJV364JdBTw3NHxyvrgiCFfjV+8K\nIiN/IiDPlkEClFgdlgexKME7gmYDckvyMmzVxmEkx0C4hH0iwLERvDRRTbSh\nUlmBel0OoUQD2IZMi9yeNL2aXCz85NXaTO7x9v8S3wHaDKKwTBOx1O8u3lCM\nIBC8fiS57LgogawAVjRmC+plRPbokTgQieMPc1YKZUvkHEYqxCbKqvoYT+2R\ncCTC\r\n=vTot\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"ac8b76dda3d6981e46ac3e13ae0a64ccf67747f5","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.1.0_1566481818475_0.5244801248042554","host":"s3://npm-registry-packages"}},"3.1.1":{"name":"storage-mixin","version":"3.1.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.1.1","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"5b3ffbab9152e1a2962ff489ee16dfd39093f53b","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.1.1.tgz","fileCount":25,"integrity":"sha512-7NVAaufQyHeKCv+nwcdmHjassJr38JwKYaX4X8xoQ76ASPtZlm4qrMUgO7JnGYvSBJl1PHJoieNgLQ1771+Ikg==","signatures":[{"sig":"MEUCIAmP6Lih8Up8b3rTGhy9xmggdAaPMhL6DUy8PEFBbaAwAiEAvFwXS84UofHllUSDZ0qjgQYAr7wYIQHg1CjbUQkaR30=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82884,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdYv4nCRA9TVsSAnZWagAAEmUP/2MsgbwueQtgJOZc93rY\nIIRdT1Y2JiFowC87WuuSjI8qxJnie5eln+v9QyjPREM5pjPPaGr5Y5K9TmN1\nnqd0B/veO+l9T7Wg/GJh09TR97lDS15F7Q0px0uPy+WRM2gf+r4zNA1y3SUX\nUKp5HZ7/lwGRiDK70QZ+aO1FMLEaUhUzL/sS2rE8103kkucZLN+Nc7GQV70a\nzS+4jeja60Je4k8m4eHRmcApTMXXa7TGpy4XMz/zAWU7hDojrkmV1S82XAV5\netjraAP+r7N5UDUoCp8xhxV9OXNyh8Z7e2KTI+CpmSplrpLEg5mqFmzIdDpc\nhWsLGTfMe1LBeUjwz3kU75y9It/MZ/yThyZMQ/vE7PieKAcEpjA3zMUlmOJR\noKAFjXvzrT8eFwgLNiqVYlXuCBML1Tgngds1mYzin4ItfKBcAek48EVi5M6I\n6Mewf4y9c/Us07Wv6M/GXTh/rS8W6UmjQoVh5+uxkdfbz5AjzEY/hN+a2PXL\nuHH91BfFMJjQUcEcoo10kWXi4RwPzt+EF1l+bUAsZGbn9dbKqILPHZjGzNJ8\nyUJeYQVVF1qNc39Jkef7i9GANc9l26VdoO9CRIeC2L0glIj+7wwYwSYyNTYf\ndFAki+1mqlmXnDTdg3VL9ecjADXRQzMMVK6Rh2PVOtMc60VsvtA7S5XMy24P\nVE50\r\n=ufGn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"45a8f7f2b635638c18e57ae0a4e9de2b1a01c633","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.1.1_1566768679069_0.19312008026992467","host":"s3://npm-registry-packages"}},"3.2.0":{"name":"storage-mixin","version":"3.2.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.0","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"0002d692f705bf2dce1a01a5af810d7284e5bc80","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.0.tgz","fileCount":28,"integrity":"sha512-4dKDqLsrkzRfD7GF8gghcenk8FjmQwJVyrMAAjTHPz1vYDiNt8M4+pa+NqWqy7SweRy/yezPQu7KvamFB8ZG7Q==","signatures":[{"sig":"MEUCIQDnjFTk9VkJ+0V0QGtEwnIiriRNTvKDM2Br6ySFyz4UWAIgBQLAA3B/7wHd6wRCiCGfGVisHdZ0rGR2MovmglluZFQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95309,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJddmX+CRA9TVsSAnZWagAAgcQP/j/rIJQ/EhvXB6pJXABv\nzJXee9IAI3fZmMmRlUEc68sM5Le16zoHDgzcgeIiaUgo405JJqqBgKHWZ2hL\nySGmUMrblGCG9VID/5mnLkm2oNrvw44IJgq+/6srUvJXNICestAqdMLFv0fA\nNeLpY639jzZwifqFn/kdm9Gq3DcqiEm9PZb3VpAacz+r2guaOMv2qWxwduNL\nbmIXScV2F4OJeYndeaLrGqJoiD0NaWfJI9ppM9VGWxziNduSI2G0G2uNkjX7\nQGr8nxj769xz1IFObmRtia3QfOX2v9pdJvmZLNUp2/1kxh2hpQUsurYGWDyX\ndrCg71HY3hkb7qLOVvX0TADjvbhwPYptwOzxkQBAWyRGqfIbJBSRPPqwNQpC\nMCKO+owXNgBlnYUodxRk4sXje899G0un4P67YWWpeUB6ey81Cf96cHHyC5Ry\nXee8bDfY8ArvimGV3LAGQShUcFk4pUS1IdoQZsxs9Dq7Qn4mB2AyJ8Wpnm8q\n2r8LwFcYWjlkZQtzbJf0pOlm0TZwP4roQNZtZ3b42zfclRyhOauP50Glz5W5\nZTIcNbZ435t4mPJMIUKNnzKSn6Oi6Um8Lp0Yl6Z5TFslVCrj/SYB/fXIM1Oi\ngXaz5HBpGM5MfVtHgG8VQluH0oS3nsgdsw2/SWyuYeivwkGg+L/OLlhnCJiX\n2XqI\r\n=G3qr\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"75e8dacf3ff03e77e083020a4f3a895bbed31ae0","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.0_1568040445399_0.6296084293088158","host":"s3://npm-registry-packages"}},"3.2.1":{"name":"storage-mixin","version":"3.2.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.1","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"3e37f2337efd37b1a2657a98f03a678a73a1f4f1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.1.tgz","fileCount":28,"integrity":"sha512-r60r72DOpmpaUPU8z44N3Ox4WA2BsRGJ/CjGh+Aj5NqefniI9pq5pa6kYkp3wFZv1EeZwKW38xnGk8s9ULMvUg==","signatures":[{"sig":"MEUCIQDKebgmyWLeVhzsBep+CGZ0oXSJ4Of5W0c3SJUXUKxJzgIgKpqyc4uWSVOjUYZRH6W3l41WY1Y6489apU+Unqwbz+o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95348,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdd3UqCRA9TVsSAnZWagAA3aEP/i3MaCTpfbneofeYQIv4\n5giMtPf5Pu28oSh7l1hRrL6Y5EZngZkdxiKEfz7BLK2KbYDQjNTagYYCQsuu\n+85dlLf4YDqtq7rJxmoafXW+/QKEKPeF0qpn6LfEblrAZHYt4kOlh2SUXcHh\nk+4NuLNGDb8h7tfn+5lkQ3RBA7gOeREInBKflAjhBstrqWugzx8EFw/t7+B3\nHGPmoXRIDciUrD7OBtBh+KOGH8KJgpotoYzrRy1kxs2EUi2Wbjqu+BvBx0QW\nZc4RpkPw9lwSnz2VetVJADrIDmZMUDzzyDxVwO1GBe1/UQvw7873Fl1mmxeZ\njobY1cae0H4JofgICgM3hhE3yb23q3e2g+KaAS4Z7AynyQenqYjwWWlGRSdK\njtnXEkZIsZfTRXS+OJWsBA7L7Qjnu93qUq/FdeUgAlFm4WDP5VJFi+RuzcJ8\ni1IPpOpNVHYbatCNBOoMon5aXxDYq33wyXZY+w3esXu4Czx2/EWrKrlnw0L0\nS8Z0L8UVwI4M6M2qAPx6CUvH6rLWImKA7TmTOXm70S/LTY5h8Xsdx3Ky672H\nRlwHvRIQBKsuoSnazhC5PlNKI3XMJ6AfkLiG6P5qiaV+8+DYsWtoHlXdUdAo\nD86COkFxQ2pC//KZE9e3toC0vRQoyxofUCHj7WILa5QFg6JVWmzSXEhgzDS0\njKwH\r\n=iGp5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"b31a9579875424faa2a99768303666e2bd986aa8","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.1_1568109865330_0.9926643261868804","host":"s3://npm-registry-packages"}},"3.2.3":{"name":"storage-mixin","version":"3.2.3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.3","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"9f674f78ae9743ba1893603e7e59a300eb511463","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.3.tgz","fileCount":28,"integrity":"sha512-CwlDy+9JTS/FlUnKwWoyQFKYL18MyGHZYDfUoQ7ATFVl/hn9a/BoQn3bu1cqNNEv8Je/1xmt0/Vh4AUd5HzSRA==","signatures":[{"sig":"MEQCIGG1IqkAsJdM0R27svSjRAWBxjQOq8DOnzMoObD5/T4xAiA/V7O9xpgf9SneVX0IobPwugru1qLtM2NjSu/IXbeTCg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95285,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdd3zuCRA9TVsSAnZWagAAid8P+gLNrxpp6RXeDPlSXh2X\nSxPABowZIdBsF88CaH+64QgfIWZ3y5KPfl+EimrMDe86NrGKYyB1kWS35fvk\nkLpvW1D5un15X28d9zwxfElq2wzhStlAsyCEyONxhRbfBlqp9bHroN4sUcbz\n/IAYKoop10BDlPfHzB7ogXjzq87NPWV4auI/OXNWz6phBzGM1zKcd3Hw7sOr\ntYeAb5DAhENi0xmviCyFSFbOyHGxyah4M+7euEqxvYaG/ahciT34dBCcCEXp\nSOMfF5Y71uozs52iZkmThWZI1TBabpD4Ijv2O9OZC7yb9WAJQC1+X1OsEgF4\nYVTb+vnQ+HFg911XObWab5O9KimMi4IzfXjrbpDYTzuDc14xViR0tS6B7aQJ\nJUOiHf2Y6mt7wJKiZ81dwgQRYqnm+FqqsEublDCJrWgrbtdmQB0clwPk4z0C\nFxXdQsAWMb1ZiczkenXXkKxTDNpcTNwH/Q5T2s4+Mh+cZiKivl8BfpN4ccOR\nw/80mPJL2I0rkLCKX91k/BTR0HvBVWDyXIWO32u3Dsdx5LIoE2Ns99defW/p\nX4YTV/H/ItpJe7m624vtC8YNss1lvmnszx82FsIi27ZywxY+ppUZG6D/00Mc\nzyPZJbd7I234mQoCL5kyJWWSv03t3KlGqdAdnnih2XFow/wAodGbjbdyVgLY\nV3VQ\r\n=2rA1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"461587c3f1a2807ee8d8441dba5afa99718dfcef","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.3_1568111853414_0.741156897852161","host":"s3://npm-registry-packages"}},"3.2.4":{"name":"storage-mixin","version":"3.2.4","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.4","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"61fcd44bc738c18586c12cf65ff4f045157b806d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.4.tgz","fileCount":28,"integrity":"sha512-n/6GdpSdeQ/hW210KvDiYCfNb6n2iV+WJjJOeQm2QCxO0uqvcClyCIx2vZvknkRG+KomX54YNoBV+yo58sJ07g==","signatures":[{"sig":"MEYCIQCsEoX45fpWD4yzFs5FeS0zV0tXGYJsfVYRI7zGMFzOigIhAKbvqABYQbTQSXQbmd3xhSYgWBRMMsBXW5g77jwTu7tx","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95269,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdehLcCRA9TVsSAnZWagAAeSUP/2ivvio8e6MT4QyO68KJ\nnVHVGXM/noifxEt8A1EX22f7aKpzAPE/z61yarVxiNBwtpbj9Vqw3rDdhMTA\nZYQkbsy7IHNJQdviJMAVzt0HoiWBypXHTh0AbmnglqiAK5IiAqhWD1wB0X20\nK2AISCQowK77rEoN+aBMXCmdlDepo2sPUMYEtINtHDCV1VGkCUv7B/kd/T94\nW79IyDKTchsl85wxZX7zwAeBRa25JUqG33vRjY2wbFAclqYjr5PkDeVyjFuN\nLj/TA2bM8ks99nMgBrELrAsXOFV7KrRI7PzXf7kS6uV6nuGaTKroTTDKEtwg\nOhTdKKZ8QgSG2LzuMzojyhORxILX8sRCmk26GQITxoLCembIRPJyJgLaQX6j\necV7fOvo2pO9rG3WQ7kLYigtzwt0WQDDFff+RB/D3V164NiUAvQhcMImUUgB\nAM8rusIHw3UKrPhbcvavOli9R4kSz13JowSNE1OU4nUxU7glYQ9GKj9JotPE\nFVSizz0J+eyB3ZKFWoONttK5c8p9V4sTz5DcrxJ1st98+fvHU0WZT0Lvu48t\nrzmxd/bJFIYbZWzCYcxbQeM18HEVbGlY7axhxSVEFInfQAdEdrYk4o3hSp/V\nfMYCb5wWPimqyA46vbMh/iet9FB+HS2gOVMo9tMxae2U/F++dhs8iYj7iNyd\nDlDT\r\n=YCqK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"fa3e2592e5ffd2a2cadfba57113ac0928a79c808","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.4_1568281307549_0.5403372124484871","host":"s3://npm-registry-packages"}},"3.2.5":{"name":"storage-mixin","version":"3.2.5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.5","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"6165a6ab5f72b843f6af56daab8f9c1e3816608a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.5.tgz","fileCount":28,"integrity":"sha512-udchtAwyHdFt/CoxJ5PwgtwMcFG7TnSAslg+NZ30bP4aT9sVE30D+8mF//oz+4bey6NnoW3oyikOfjCWYtBC+Q==","signatures":[{"sig":"MEUCIEzSca7p9fBCTZEpl/VBr+jpKZ+brCmcpdZ7jxAmDuqfAiEAltAvLl0hIQp80nvj0PNK+U0sQjClDMGj8u3dYOzT3hY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95367,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdgi23CRA9TVsSAnZWagAAYk4P/R8DfADRgd5ZeDdn2Noe\nS4ROPoy2l8WUf+6AADC3XbHIiUqbmtj49xWdeMci4rpQukUJiy4Mkuf4Qyet\nChoac9xilMnd8AhjV+M/TOyxEi9/B9JLuyCLcVkH7klzDil3y4fjjiCCx8wD\nynexG2u2C2ZTaqYW0NOAV5Z9LR++b0pkxPYNNNx/gtdiRkisaYqWcasrVGYy\nBfZEM6AS5nDdughT7N1EGsecV8ZNz7+OlrR7zsDqhBkFHSAF8S8vd49Noe7T\nNhuqwR7/arLl/T4KcajTzTdQvxSl08s4rZk17sUQxBRXlh03RFdJK3nF+MRJ\n1WQkyXIIvEiuY6/zhLNgpMEJOaqv/iMzarf3teT45bemWbc7li9kZW7lyJzd\nmZADttStC4ytt8xsH0WgloF/ez1yWwYn9YqQvBs5iWhaaatRG/horx+x6eED\ngS/muCxuKjFgqJIQvN4GQ/BJR2+2//VRzbGWV6BA789o0cQ5+WUj9El6/XSQ\nwGQHEpSSiUXRe9QyBJJUslh6ODT8Enz2MtuKnFgwc0IGgRE2DhFyIO+ddnqn\n2k/duXFrjq+zaiDvAsLByKOKJ1t9k0hbAfomOCxhnWJ3JqP270rIer8uVQxV\nvMQxmxQMhWn8jMsx0svgvPoNtvORyDZy0uLUoxzb2fLYSGkV9P0MtBFI/YQr\nJe1F\r\n=Bve7\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"a6d104cd08fcdf1a6e6f709a4ae2537489e3060f","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.5_1568812471242_0.20775188912139186","host":"s3://npm-registry-packages"}},"3.2.6":{"name":"storage-mixin","version":"3.2.6","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.6","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"dcoupal","email":"daniel.coupal@mongodb.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"c1c713955cc6f52f649f88b75cd0419a24be1c24","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.6.tgz","fileCount":30,"integrity":"sha512-HuFdIyxtMPd+Hy2HMD5JUNbOLbD7l6+SOgAYAOSAnmFya87pvvjcOBvFGqXhZar3f4JZR3mbHZtLCR3BegmOxQ==","signatures":[{"sig":"MEQCID9VElEZWDjVZ+U2NtFc0HDERH4IXFQy4ULrMQ1h/TNuAiBvpy36mF9fofGR5OtSSYV6JfMQqKvVU7ZeihUuRGLVpA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97195,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdilmtCRA9TVsSAnZWagAASRMP/3RE/+jeYLmZHRo9gG03\nY6bCCpPt5aeVEjeVXsYBr1GUIccF9Kh2lkVomM77kF4s9krMmFeMWQ37hSfv\nhzgpIc8krxnFCfQ68S3EWcGlXm+1MDcfWO0LE/tucj0pH684VWxSDSIpt9Uh\n2g1ocI5hTHproMewDBU0yTI7D2VHMI8yPptd61GJBrQX9dgyrQr1Hj9LNWU/\nmzHwCh84XRQUAEmHxm7+9l9ZuE0fA7zFGD7AkmtiaUi1+GLBpncwmPKbYkl1\nKkSGsKh2naRfEdnztWYb9KkLtKt+LbGE8ATvGRnGyzBM2orWOFN5y+FVA79+\n+Gs+Snrnk1C/ny8yvgD4nVb+oq+f5MCKMnt5VSleQ4W3l84m77xG2Y5tvphm\nJw4lN0BsdcJa2rZU87Zffz5h2SCsyrZfMSO6Sdct1oCpze/YoyOFkRLAs9Yu\nfUclNNXYPW/gmy1ubAbwUvDvT570mR3tO28zCz9f/LV5951vW9WJXCYJxAxT\n+hvqUeVU+LIcUijpCQwk3EZ5hd+67kbpemshHkbovRswaqmdUQgEDWbUuX9/\npgbEbM/GMDUQdKevioBFKpyOtHlEHlvMfx+PG2Lqnfo4UhikHEAbr789Dk4N\nAyT3aQIMLrKHBW92d3Jh1Vle4TCPVMfyn1IVhbT3K9Ufun2gg8xhJd5LrXcm\nMFXx\r\n=bvUi\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"e3b50a0e544fac354c4ec988b4d202a495f678bf","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.4.1","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.6_1569348012417_0.8057912617393788","host":"s3://npm-registry-packages"}},"3.2.7":{"name":"storage-mixin","version":"3.2.7","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.2.7","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"daprahamian","email":"dan.aprahamian@gmail.com"},{"name":"dcoupal","email":"daniel.coupal@mongodb.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"srv-charts-read-only","email":"team-charts@10gen.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"fb6c7eec57339be987a51161464a49002eae47e7","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.2.7.tgz","fileCount":30,"integrity":"sha512-LA+S3UgpvjK6AiVsdvtknW1/doH5/xjah1KBUD5EiPwJ9Sadl2Y2HakE78Dj11+fp4j1zSP/kEkv0fyK8yBOlQ==","signatures":[{"sig":"MEQCIDyiEF5VJ5dqjF1YCJzXuTOeA6vr62eoTFJ2wKzNPrOHAiAgCYkGOaFTJjqz9l6NA/Fb/+0mb21rdXibL9+6nLCsYg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97250,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdtvNSCRA9TVsSAnZWagAAFCAP/j2J+Nbq9rPjqXEyjC1e\n5bLtoQpQUoJ751kkKp0sRZ6JARFZ2uvZV58hLX2j/cIePh48m2caMNgVdeh+\nN/jV8ZZxWeDLpThNVmdtB2avSLtdWs9r9KFB/KfdvGt9YSvElfRd3ykG/Wbw\ny+iEQhYVkGQEhevk6tFeAabUciqEdOMTxVwd8XkAsnNv3OSF8t1vm5IpgyWk\ne7XuJWm1UQMXBE0+OlMbFB7LfZLmxya4NkoAe3bNiUEuiObai2d1RXKiQcGr\n3xuJ93BbvuTAK2cIewwwV490hykwFNBQCVpEF5OrHFwkYRRTVxoIwZ9J/qe4\noCtwPgo6fO42/rutXfj5UtiuVu7GhUpex7vad/edjrTSRgUyiRZAOc0QE+ro\nTCger56u8oIvmVZSCYtzuiVK+YvZ7x4pWWffdKnSUeWt6l/TVcRpjOUlL2ML\nhmyjMarpMfyaYc0y6DaOLsotgkmm0b3Y9s8KPMlvpsdUhgq3hG3g5kRBflD2\nQCrNTxG0O9xu3JoO2N8WAL/OMVrKgcR2kxbmXsgZWgOUeH8Fl6Y2azGVj4Dq\nPFmq/vkpByiYyTR3Jpb52iF3e9JdjdI5yKT/nc157QO5gdlCLsmwrPSFFw+p\ntITEjGw3KR/ifPNf6YiqrUUuD2vPS4wB3+2AeyWIzkGFNkEQ4FyDfaddmfSd\nJjpA\r\n=kPny\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"d140d5462308360336094e087c8a7234c71d12dd","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/ --verbose","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.7.0","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"10.2.1","dependencies":{"uuid":"^3.3.3","async":"^1.5.0","debug":"^4.1.0","keytar":"^4.4.1","lodash":"^4.13.1","rimraf":"^2.4.4","hadron-ipc":"^1.1.0","localforage":"^1.3.0","ampersand-sync":"^4.0.3","ampersand-model":"^6.0.2","write-file-atomic":"^1.1.4","ampersand-rest-collection":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^5.2.0","electron":"^4.0.0","electron-mocha":"^6.0.4","electron-rebuild":"^1.8.2","eslint-config-mongodb-js":"^3.0.1"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.2.7_1572270930440_0.25029107005070705","host":"s3://npm-registry-packages"}},"3.3.0":{"name":"storage-mixin","version":"3.3.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.3.0","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"dcoupal","email":"daniel.coupal@mongodb.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"vrachev","email":"vlad.rachev@mongodb.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"b622ad438aacbd218e1970012b147e0d6aca4611","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.3.0.tgz","fileCount":30,"integrity":"sha512-cNBDyAgt7XMcy7COFKMWM7rTDNeU4fvHd/bjIUo/9yT+VvwRwmAaAOJ1XP8UhYYl23Nns4x+LtsWInmS6tO4lw==","signatures":[{"sig":"MEYCIQDQljpt84FWOHipvwZUAOEZLS3JqnngR//xqgrZV2JyqgIhAOplP1pSOqRhWQCaw+zY26mM3UobbEh1W+KCL781aGmY","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":96366,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHSalCRA9TVsSAnZWagAAdzEP/jPXgvOkgPEA8k2wXi0s\nUlVdK8HRxQ2989oWbAkYFKck2t/H5372b1uqTT1GIEqm2V4d0Le2k1X7nC9k\nKJ2VbxRsWQG8ZNZcXLGehgGBSnXZVtBC2ynhmHLQGpqQxQcj2KtqcFSnAkhu\nfWUFfBKs8auXx+qhT6lWlSFPoEYGh0Uc4r238Wn8NqEwg/W7Fkzr7QdJTF1B\ntzZOHFaTdfMy1/WlAATSfZy7TRjPelt9ZsahhCjiGZPDfbT9GsrebL7sZeJe\nmSHoNGd+b60g1uxXUGVXwDfUuoWm2A9c8885UWLN4He4W1h5X2mDCPkjS1Gg\nUyhIswndobm8tjhAonQhPBpbvB6zGUIchlG859AsoylzDVjyUrXPGCSeS24R\nPc8ABgCD8N8FNvqW+bwdbiVggPUzBVcOXIOThHXRWibW/m35YqMMepoFDgub\nVbaj+NMpFqqUn1Cx2VLs0EhpRGLR6ej70XyhGSmm5yTpxBCBRObh6DjXl+1g\nmUCCoFQi5JwDRJW0fgzg1ItrxnVNXnJD6coOgC5hBsmQ+VZfw3OlhYeayfxs\netMFwqbS2vcoO06eEr9zeJSw6DBxH8z5fKMIcDqifM8mgniOiYbwRIo7RetE\nfOFeVU6p3aeaSrcgnWPahiLxZx4DdzIJ0mTrZy6o+nS05DFtCJOPDSCqfMqg\nlv8H\r\n=aAy2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"e89d6667491a221dd7e67cf142800015457c08f8","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.13.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.4.0","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","electron":"^6.0.0","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","mongodb-js-precommit":"^2.0.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.3.0_1578968741118_0.664207251540653","host":"s3://npm-registry-packages"}},"3.3.1":{"name":"storage-mixin","version":"3.3.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.3.1","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"dcoupal","email":"daniel.coupal@mongodb.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"vrachev","email":"vlad.rachev@mongodb.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"776cae78023734b7f032b30ec63643024b65f97c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.3.1.tgz","fileCount":20,"integrity":"sha512-nEUwmU5YJG7bYH32dxalLks5m4CMXxM2ZNKuJN3cGFk8+KABj3LaUBbWxPNuGdjLP7xsvTfGZDOPu9gGh22HQA==","signatures":[{"sig":"MEUCIQCF9LdMUIKzbSwBu6Y7dOsxHF/JIKsNz4uPnmncj5pm5QIgHcChNQYolda4F/fn7tGfDdFc0dRTq0qHxiPSY6YuM5U=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":61668,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHSb/CRA9TVsSAnZWagAAZu0P/3NhjmR/0czO0zbclIo6\ntYCiNxgm/FzlWNpmDJqomuv9IETANdqbOUVXpA3srZmV1lWeat4RTlZbgUNo\nxcGoE0Aho2tS2vmqUXDKbYNC61sdJifb6j6nJae8vRYVn8qru+X6AkzygBE2\nNn/ALaN21ylgq0jJXGyNWLDYpRiJbxcfsXc/ow1L/EWrtdWYQScPeegVTwFy\naGoZPsz+kqk4O48zW3higIPnqhhwZGjwcqdAKpT7tfxw7u3hwhd8kEToWg5m\nKB8F8BJNtzUPQrANeT9LW2sX9fsLH1y28MV42a6z2nT0ziqqW9O5LBzA38jX\nk0b7e89SuBW4BqEuuqOKOZdsPLZre85kLWJIFudb1OsrvXFTKmVcMWaTihdm\n2dcUcI2glIgunEnaov96MecRs/cR6BiSXE13EfNR1FEov9d8eeshudemheyN\nH/4gaezMQbuvIcuyV3fj9i7rPW+L7kEtKIOhk8avNiDQqOMtsChDCyyFa+5h\nxKYaGWZ293J6AbeIrBZSmGQON5ycw8YKiVUx60M0BxIks1vd7wDs7hB1sv7w\nqVliKZK6IcRcMGZtpk9yS7gSLWIvNUDmOChaCF1L605bNr0hXjUBwu5IStDy\nz7o/pFSdfUaPhEH39cLXiHFxNUyFQICBT/9DG9KRiec5kdirSDLO/Wpfz1UG\nsWOu\r\n=PTog\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"486a637656d3e275dc71c43462c87987341b8a5a","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.13.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.4.0","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","electron":"^6.0.0","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","mongodb-js-precommit":"^2.0.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.3.1_1578968830512_0.17225314448952966","host":"s3://npm-registry-packages"}},"3.3.2":{"name":"storage-mixin","version":"3.3.2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.3.2","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"cilix","email":"matthewlevenstein@gmail.com"},{"name":"dcoupal","email":"daniel.coupal@mongodb.com"},{"name":"deafgoat","email":"deafgoat@gmail.com"},{"name":"deepshah","email":"deepcshah@gmail.com"},{"name":"dpercy","email":"davetp425@gmail.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"glowe","email":"graham.lowe@gmail.com"},{"name":"gregg.b","email":"gregg.brewster@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jimol","email":"jim.oleary@gmail.com"},{"name":"jon.franco","email":"jon.franco@mongodb.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"micheal.parks","email":"michealparks1989@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"mpobrien","email":"mpobrien005@gmail.com"},{"name":"redondos","email":"aolivera@gmail.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"ryantimmons","email":"ryan@rytim.com"},{"name":"sampoonachot","email":"joy.sampoonachot@10gen.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"schwartzrw","email":"schwartzrw@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"terakilobyte","email":"terakilobyte@gmail.com"},{"name":"thomaslangston-mongodb","email":"thomas.langston@mongodb.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"vrachev","email":"vlad.rachev@mongodb.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"719168a85da220eb523180db0908880afcfff99b","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.3.2.tgz","fileCount":19,"integrity":"sha512-bEvIYi0mevFhsyRQ2XAscOv8HDndiSkkJTnvVOm2TEUo7JZqtJejSikGuB9bVE6Px7f47zNP0jgp0LnTa/iKhA==","signatures":[{"sig":"MEUCIFSefYA/F43nNlTP6AQbmM9PeNort9ClxMwXsRKOvCA+AiEAsqSlWw9rVHVLy8awlAJwy7Mk6UzdAV/7X3/89gGWtmc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":61580,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHSc6CRA9TVsSAnZWagAA0EMQAJj4Ei53ylNZoRk9yURQ\nb52Vvco3zLdfek8jdXltFY9wnH2+cWzTIpQXOyyhIXLhNuK6VGad71v0jqvP\nnL3wP1opX6GeKxt7+n6IYBEW7tID5v/caDzNmF9vx3UcYxcCiCLyiHcuavl1\nMonDkWsi0jzVx9IEJuZVM/QihAJNOPhJLf7eeGfuOpdeg1ik1Zw83gZempft\nVpw1zZ+kB1qLqLs9qJOO1DCso0HTXk9bxBXA/6MrJsSSFspLzqwou2LT33p3\nExtichX9/g75wNlu5oGtN/Ec4CD3ujHzD7fju61f6PPIbYihKT6d6Vwr0svS\n41p63ece08jYSc+omz3+plz5M7NCW1QVfwWwqrkIwZRjHvslGK/U9JfKipcl\ntQJ4UIK22U6nzvsUQ8ieV5WTT3WkAO161EHvVODp8kVe+k2RMkdmF4kwwRtg\nnb8UnUQBIjbm7ZSMiFLO/i5f7QaDFUgx71n2F5xyGRy1EGOrGI5cSax6Ki35\n7KcT7jC42S+NNlMdyBmF/cpWnlK48ZkiLor+GcXqxcE84z4/xqJx7TbThPi8\nYIhooj3B//4ZSlIcX/T++iQlZrMqxvRVoh9UrsVribPnNG6ryQ9Am1vmJl6p\nh8oOREZiM7OJPvoM0hYLgymry8AnXUr4moLnFh1QZeiOCx69uGhofnwaBHiw\nhCqo\r\n=jlaZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"4281185a5b1ffafb7f3511d5c175147b3f25a300","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.13.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.4.0","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","electron":"^6.0.0","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","mongodb-js-precommit":"^2.0.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.3.2_1578968890168_0.5514807154435757","host":"s3://npm-registry-packages"}},"3.3.3":{"name":"storage-mixin","version":"3.3.3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.3.3","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"aa90a49f1d7d9dab12174ef27da85506267faa41","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.3.3.tgz","fileCount":20,"integrity":"sha512-IVVYYadD3PqR7sPL/hvrhK9nrPH2Av8Fnp6jfpXm1yNwA6zdzQJ+0TEU8yNGI6iT8pOn8WckB6zHmeiJ/ew4ZA==","signatures":[{"sig":"MEYCIQCr3qXXZ1+KTl3MYmLmHHF94Yd82JRZ7L3e6vg2aqS2wAIhANtSlOUBSuYWzhRZzfY91WN5zQB+b0gGdgO1HrWLAa71","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":61670,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemaziCRA9TVsSAnZWagAAWwMP/Ah4tyf9fXoGmiaQLn+1\nT7M4s9KYc/hAdeo7uOn/2z0Nm3koK2H5CdTDvmsOKUjiarqaQJb2P5xjav4O\n43cRppOQzXJJ0PU7ZDjz5snlHtPy9/PvwU79TeD2WGjezDek4ciKVlqCTUEz\n1TM5B1Ey0gDN2B0nxv0qp4nTO+/iCRLZ1lb4D/kDHJ7emtEanFR35MjBc6YD\nbFAMP73FGxq6K/0zv4nNRST0+GxlvEXxLp6/QsXNkNI+AbmT0s/yCMoFKQEU\nhckOMeilbFwaMXvQwyDTkJe5lVhHfYYCaNYLH4Vp7NGfr8PCCHO5WRBUWM35\nN2BjVh9PsF/lufs6B5Zo7SHb2HAYDiCVd5QboI6of2sola7nCwEjPTSX22k+\nPfiu7jY+to658uT+GoHeLOaw/TVTJaZI/s1M2hGyP/tP6JHbNgWq+IY1YaGa\n0veWBHfyYIoPxXdiiYR0orfH2Uk/9wJFeORUqwxZ/tjXG57DdQFehPyQF8cl\nR980g9gyah5jyg4fPaZEjAEioJb1fn2e1sk7khz/8H4jGxlP6H4zuwnEK7SA\nB2dVViOf+Khm4RCMjlf1ORCk8OlWGk8z4GJcf+PUWwh6KRlFMnOBH07YoeVy\nX32anqNCHAD+mKuE5QcyLaBFi1BH7MvnHebQuDcsYLpFL0yjRg5GIpvBSnqD\nAhsJ\r\n=+mEl\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"763acd302016dbf001a133df4b198fc183523732","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"durran","email":"durran@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.14.2","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.4.0","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","electron":"^7.1.11","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","mongodb-js-precommit":"^2.0.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.3.3_1587129570038_0.6884239275777078","host":"s3://npm-registry-packages"}},"3.3.4":{"name":"storage-mixin","version":"3.3.4","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.3.4","maintainers":[{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"kay-kim","email":"kay@mongodb.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"scottsidwell","email":"developer@scottsidwell.id.au"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"tomhollander","email":"tomhollander@hotmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"6a5593a2470281f41c62b30f17aecaf3c6212a91","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.3.4.tgz","fileCount":20,"integrity":"sha512-NUD/loAAp2Enxqn28N4n5koJQFTIcN96AaAo8YFEut0tznR377oWrvd5ezOZTesRYbXKB5gKjMdK1e+IMpiE9Q==","signatures":[{"sig":"MEYCIQDPdy+qwTOsnBCwE3u7od8rOzowNs300TnM30B023rj1QIhAM6Xy35fDQ4CFcQQ00wpwJuSHXKxacn2DbJaFGwdeO1a","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62556,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfM8e9CRA9TVsSAnZWagAAH/oP/jmRgo0A7eVMb7YqfdWp\nmp2eIKo7OJMgStZi+7rWEijXjOZ/4N/94R1iExtx2h3731jMNaTZPKKCFx7X\ncYig1v4jhlFxhxq9mX+03puNR42CowB47/MucT1LAnwN4sxHxQBH3QR4Z91F\nSnt0AXmjJGkY2O7srS4x2qWk1VRHmWTcpBy+fw3yDW62o9queELq0w/fAXcO\n63A+F5zAWia/icZJnpBOabLQR288n6jXxBvDcq/w7WYAW6I3n6Lnyg9GSL1E\noSjpeVsKpnphGd1KD/mnU2Ah1eFDysWlSuIA1U6pwdDA3jegVNC9HHUnNpOq\nq49p/A3nVhHpZ60j4QM98Tu5zdehKS7+XWEKvVSaBhw6S6PuVqaKNXZxIaT0\nmiFyc3piKM+at0+Z9UX2caM7SVvfUyfw/Qf4CKnaLPhHNezoA7cpyB7UJNou\nWhK9mQTLKRNzc2d8Vp34QLsA6E4aYoX9ZkJy4+46guLraSLwoF4o+uMtiBxN\n/NrnJe/0AVN7KH6UwofG9iWPN9Xc9NLsVFXTlPYm55JskjTCIseNrxMBofEu\ntYbFvkMsTa69F/zZHa8jURq8g/FRV9yCe3TV5lMBoj3212ZdxIdxYrhsHv3c\nYOxzrNQ9L9DkhnLr34gVF1VF1sTgijF3B59fuszzWtH//aGvmhZh6MDlt38M\nzdND\r\n=Ipiu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"10e9200b337d482a69e492f31c1ad96511a6fdc4","scripts":{"test":"npm run test:node && npm run test:electron","check":"mongodb-js-precommit","test:node":"mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"electron-mocha --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.13.4","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.14.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","electron":"^7.1.11","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","mongodb-js-precommit":"^2.0.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.3.4_1597228986589_0.3019610939852335","host":"s3://npm-registry-packages"}},"3.4.0":{"name":"storage-mixin","version":"3.4.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.4.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"893be1eb7df3d24edeef315ed608fa1ee9196807","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.4.0.tgz","fileCount":20,"integrity":"sha512-Jw2SbQ1soEUW0zhO30ya6UIR+iRoyTT0UPSac5UeduAGLF1gNYhAHqvj4rdO3op47YIMgV+i2L3uo66xv7RYjA==","signatures":[{"sig":"MEYCIQDfUhRh6kGbce/dZekQPA9rtBiAICnYx5c5ScEyGcZJqwIhAOy1FWe9DWtSBcXPSm7qYufuJkkDaWqMWtskQIoruS5z","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62992,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgrpByCRA9TVsSAnZWagAALkAP/RX+XPj3fdlhb7L1HofG\nn4V4g0Z3kECbyjWeDhxHE0Cqi8CPrpdIUmYneUk6Q/i6DZsK34RIsdez0s5X\n1rbl+SD5z1dbKiwQbkU3wg5u/pBdxoqnSXPqNgg1TX0sM9KkDyUPn+So4sIY\nZSB8IiXx74e3CulUoLAuu+aC6CJaOoch8z8Ak1Lh+YKunO0O4A17mvNHl9XP\nf8fL8UoPloBQmbCfsNQJQzVM9bopk4vQgTq1aA6pJL08qVjdp5iMn9VFdXEg\nRE81l8LzkrZNNkGAydeGmOQXUEaOaaO20K2MGdoWEWegB2+e+Ry1bQpUOJQo\nIHWFefxfDQpAFA6C55EVPv+Jrc/dQJvB89Q5PA5MIpYff8robA1pxjgnkr3Y\n0PgKQJGkcWg+liAgvnW88nW1f4Ys08sMJOzciiGVEN/NQAf9lbqqhU2Ru5lo\nYIEBBQdM8Tmu3+sQS0EkZN6R+WcQ7BqVUQHT4I/aCQ5JlEgTIF975wV3IaWu\nxQiIDPgxqntz00Qm2ZZYr+B+d9EIHpAtMs14jp+6a8phOCV1CmKtN+xZeIIR\nd8VGF/GoIDGAT3a/oRnO4+CA6srOjoD/cH34aUXOG44bvk2vqUUmzugeg+Bw\nN1fn13ZqE/RNLqO56WjGEEnVSIcTe1Npd6W1dirncDJtlgljJPg4MM8j2ubA\nv7Sm\r\n=7jYI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"170c704d3e22d335d5bf380dafe2b87569d7c4be","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck || echo \"!!! Dependency check failed, but the failure is ignored by now. This should be addressed in COMPASS-4772 !!!\"","test:node":"xvfb-maybe mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.18.4+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.18.4","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.2.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^7.1.11","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.4.0_1622052978087_0.677481729252448","host":"s3://npm-registry-packages"}},"3.4.1":{"name":"storage-mixin","version":"3.4.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"Apache-2.0","_id":"storage-mixin@3.4.1","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"d5ce3c14e58aebcb09cfd7407d66a639c4e2e76a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-3.4.1.tgz","fileCount":20,"integrity":"sha512-jbGZ/zfqydyweqg0khBLre5lMeUlDWVoD1zCRuFpjlsp5beITNfAbNP1Q5JJEcGleoTxUKh4WHEyr7tyAaquDA==","signatures":[{"sig":"MEQCIG/ZWpf0H8iQLnIoGn/kVFcJpAB7an86b8HzFQza9SCAAiBk4aRC/fTBRx7ELVBBiDWYPmwgIrHrmOkRX1SrkOJmqA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62935,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgr8OQCRA9TVsSAnZWagAAj18P/Amlg4MecTl/uwFcg0rN\nHjokvbjqOq2yTFsaX4CDOk/EkC0QuF+3vM84qwOnH/evNVHqJWrD88qBH9+y\no/BG8JgjDsGDk5o0WShy6NF+VXEl939qc7ZYdIiX/joHQNEiTggGBqLrZZCU\nQCRszUjafQdoRUcNFSs00tMmuZw9f3w9NIMosA8gIidW8iLg+puJU6smaTGA\n2J0ZalZOXk+bhSaICOLSpGTR/WCrxqABLedP0FroL2/8zle7zNF5wvIzpwDD\nfIdw3k9MA16Ju+jy9kO8jOYGJvU2l6oXhHNDxo/4ZkwDt2wP+BoPRaqdLZZa\neEb+k22AfQ82F+xi8gMF2q11SC3qVNvx61LUXMV9mb9xf04So1/xV+5RfNT3\nohSiM3FqIvNkL8XutPbjjTTSJNv7hnFl/gd6/jy3lkPUGhwLwe92XG32f+JU\n5TBwKrfHa1rs1WH5zMzafzhfjaWlRN+J8Ft8mD9plDs2HnwgKiPWnCtsy8cA\n5wMA6M8GAo46zdrT9APbu+Wm5wtNXVcAAupTIXBpQ3aJs4aTHhI6Ytr56Alg\nacS5ojOG8pcwQn0u8zd/dGMQ95UwSSVazDvdFz+c6DLqdPDXQbnOaaWsFakt\nm1qoKXCuce9MKPdo7hJ1rSVLreLfoQIkkwOUFjQnh3Z9oAZRnnWFD+wYKBQS\nc3KL\r\n=YiRm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck || echo \"!!! Dependency check failed, but the failure is ignored by now. This should be addressed in COMPASS-4772 !!!\"","test:node":"xvfb-maybe mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.14.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.18.4","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^1.2.1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^7.1.11","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_3.4.1_1622131599627_0.4451263194269237","host":"s3://npm-registry-packages"}},"4.0.0":{"name":"storage-mixin","version":"4.0.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.0.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"5147d64d0128774f0809f3e8c3974d94b38286ed","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.0.0.tgz","fileCount":19,"integrity":"sha512-m5BpHRTAuxhKCQmknTErEtQ/cl7b07kxr1eAQcMM89I2gCXmIu5/OVHtKhR6yOHNG68uRxRLNmX0mO6KupjCrg==","signatures":[{"sig":"MEQCIFDfsPoeeZaeafXrANwBPi7uX21ZibsW3qjPh31HpTaPAiAlh0BTNq8MiZQnMkPXFmr10CY6wVBMAQHnBiz5LdBlng==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":52674,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJguSktCRA9TVsSAnZWagAAgUMP/jTL2hVgWacdpTST/+zF\nPM/Cl3TLspbYTGmAKVZLYP93k0DLuWFI6n5gyTgXYThNKphoupVJpyaj4u/b\n+uMM0Bl2zyupXHjsSy+tY77CHYluuowOHwvHVrMLWcXLv6xcJovuRt0MKuaF\nsuUo05UQzh0F3bjVwbRpSAVocWOaK6kH/QshlBZG91RIHHDRufvtxYnliDFI\nftqGMHjzoZKeNOyr/CstERkd9GhBIk+UzPyIjlUtQryqTs7CUobYSX6ICXWk\niNr3zomvI6+svCRpmD8Awval7AxToptkVXOSXu5I/HsOv8kKcNwYz0PafOO1\nIj9E3CXrGYIxxtqrqUq+TAFhCKtX40upMOHcF8Tk4mNIdX9pgOenuE0npkP+\nssQAO4APOvqQ4joG6EFUnFN1qrzmmGzkZJfUq0SM0b9qecHhUHesTBDJtf5T\nJ0ZM4MKYVrOPIpteSczZqvf+ngigwehQK1IouhToRz30CppzJ60DFiMEGjJO\neR4cgZF3SWtFKl8Ui1ncYlzkqJcuNTXfp+5YBFbTHKL3eBT9biYjOcPdp16X\nsQFDFN8C9oVmEvF+3847Eua0wUNr1gxYVLaK7EYJjBpu7lazcIkf7d/IaccH\npqInqjtHlonoRVdB8eCAuFJ55zls6X3CrD+l57uulSg3/IKq76JICmdWgME3\nPkip\r\n=HUc6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck || echo \"!!! Dependency check failed, but the failure is ignored by now. This should be addressed in COMPASS-4772 !!!\"","test:node":"xvfb-maybe mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.14.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.18.4","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.0.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^7.1.11","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.0.0_1622747437676_0.5068838344217492","host":"s3://npm-registry-packages"}},"4.1.0":{"name":"storage-mixin","version":"4.1.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.1.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"aherlihy","email":"anna@mongodb.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"lrlna","email":"shestak.irina@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"7a540159856833fec53ab6638bd41be745b36651","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.1.0.tgz","fileCount":19,"integrity":"sha512-93d/tzzT/hRRywhaxPe9Zv+hnmYk/Thsg4pZWf5cd0Gd/hO/AQ8ZEEUkS7Sfp+K+SQDANW1OzFKgzZcnz3msTw==","signatures":[{"sig":"MEQCIAZGIMGa1PVb6eXQ37xMLNABYmZBsF76BMBK6vEI338sAiAKaT28XmHKxr0LdBmPxeDugYsnON1xqtgB8BiKcHB+9A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":52674,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgwMjiCRA9TVsSAnZWagAAdQMP/iE+C8ZA/cEDM1o/9LT4\n0i5XUlke/RYv4pvo+SFnHS/mTf6/DxJAhw0bDvQl90UIzFPMjcEOqPCv7d3f\nzSKDhpIjkinLsd5n7cQVCsP3RaXY7/LyvJppOeNc8rlci9hd2RBURCkqOXIh\n/cKJJS2mY05xH3kchx5y+gaOAURYbPz5NrDkFUME5v8f6FkPIQc0rmYbXlXK\nEvOHgfVGkqlg3GutXOCZ7t+dJlABPuPYYPijHk3gDvEuqMiHN0Vu30D1OoyE\nHOw0dWyMUXVu2MhF8655Q3JJbo29qCe27p4vmbtBpl4em1Nqi6gg9fhSuM2z\npxZa/82eUscoIvv0qDPw7AdbR8VO+CTJwivF7yWqpuhiJoXP3hQDRlxEH7sF\nDA/UR3aXN+e9xg5sA9GkEsMSqF4LlqWYnUyaK4eK613WbMlf7gPJD3SYf2kS\nBHaUSKnQR5g9OwqqgWdEq610uupp12tPiC7h/qzXj7ocEnOuz/HqlPXQDExr\neIIjTvsokkIPIcIsU5Lnie+X91vwILJeRWKjA37o1DZtdFKwnMW1Dmqs8etM\nNRA/+DjkM+QFdrpNrQx3hCg6Oq97MRhZU7XdaPIcUa+VDh1F6jt0a9QBM0ih\nun5ojyvzBwFdQiXLjynlhF/n3StHxzaUmV969BC+xJ5HTt76XyQLRcmHOA7j\nKrm8\r\n=j5Ux\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck || echo \"!!! Dependency check failed, but the failure is ignored by now. This should be addressed in COMPASS-4772 !!!\"","test:node":"xvfb-maybe mocha","pretest:node":"node-gyp rebuild --directory node_modules/keytar/","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"6.14.6","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.18.4","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.1.0_1623247074060_0.6983539485072441","host":"s3://npm-registry-packages"}},"4.2.0":{"name":"storage-mixin","version":"4.2.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.2.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"7ea8ee7020099df4d950bb139684ead68613a940","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.2.0.tgz","fileCount":20,"integrity":"sha512-czCkoH/FRGM9rIUPAeHMiNCce2NGLgHkJ//Phd5Zw8fiFqskVlufJNYxhIS2W2ayaGQkRAA6cNigRCwRRHyCxQ==","signatures":[{"sig":"MEYCIQDzz3D0/f3rXWKYXknMe6A3SzZeNKKKDwuvBKh5oTQAvAIhANiVa6hE5W+rgCZA+e/QDvzaHrN9LKzW+lU+yrUpOfdN","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":83184,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgyjb2CRA9TVsSAnZWagAAiNgP/15B98ncaChD/AURbgJX\ngEvhjmwWxgqVrjB9YCLBMAEgE4UZdJ6UDo/o9LSmf1iXXn2r0Qi/4JilOi/D\nQ7Hi92zRVaKZpkYesz/GGgOdJ8s7WB1fsmM0lx7WSrE9S3H8l18cnMQG0+we\n/1WPSZzSFQfSFsjaZtOt2q67c10hkaQKU1ucwrImMDv/vr/5KsO65/bGbADe\nF14oQGm1LXx/Rt/v8qly46Bu1gBvRy1Bmcc/i1V33vlDdjVLcFlz247Yn8g/\n7uqDBXrXdMPVsTQfG7lPGB48OXmJE26nokjomO/2knrKpiXc1rcZlfXw5A1a\n04GIe0BOOaCnJI7ioPhZ+wNDtXOd2RnCVBjYDqHl/36RYIrq+BBiHPm6d9YD\n4H/0DZyrBNWQRt4BKtorN/dPBeYfHq/TdBemntK88zA/1gnNsB+bc5gqw1JN\nWYit3e9CieTHN2eoI/bXigAxoP5GELaFhHh23Om6FKuwtPc2yY9r18jN1RdX\ncWHFxZarDQJrecGlBz6I3cIhkALN6nxEIx9zkBknOiwgWF43+itc1OJ1NyMp\nd7vj03KOjIi+QF+56QufQ4lU6tO2Y8v8rmHonk2G+ycdNe2REk7cSAfqSO+P\nw0/aCT5WdNRiRdgyKUZg/LIFm2sJq+T49S/e3wmvuTp/JYyW2nGXHqFgLGE5\n/4gV\r\n=LiKS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"cd0a29248dc71d8ab4e3428dcc04f534fcc48e3e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck || echo \"!!! Dependency check failed, but the failure is ignored by now. This should be addressed in COMPASS-4772 !!!\"","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.2.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.2.0_1623865078447_0.4259672214437944","host":"s3://npm-registry-packages"}},"4.2.1":{"name":"storage-mixin","version":"4.2.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.2.1","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"e349873b1cdf96a7ae56af553e5701a6baae16ff","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.2.1.tgz","fileCount":21,"integrity":"sha512-iGnyfFrpXcWSDKjd3s66ZTVO1EUzIZG8rR+OWB/F31jXy9uGeb0wHLF/J7VGRVDIpJE0mhBc7JSOD0ESc7k9uQ==","signatures":[{"sig":"MEQCIFx1npGk2Fsj0hHIajWTQAsVhYabkc5p1wVMvI/EcXDOAiBOX/oC4h9UR8zi0eFw6O9kC/2jjRaM5QH8hDsuKHVefw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82864,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgzLq8CRA9TVsSAnZWagAAodAP/Am9fSSiM3u9tH8XxQHX\nj01FYyB3s5Qq3Z1mMcTU2o3fkJ1qOFWF6kRFHpoZzqqH2gwEUlCQFTAFtpBF\n4uhALr8OAO2/kd3UABEAFFZsHBLV95kVhGwosWR/9n79RfjIgz2OF90Y1M7W\nApAVYXanGX2ucXtLZjALPFbGW0CGX8LcARZ/qk+VCtZPdJHDDcOqi73jyt0d\n4L1WA4UqjewuxwDou9zYKwFXiyDjTrL1ckoxgcvLIB+V8w1BxU1TMJgQ/XbB\n0HGkMTb/4EWn4OWUQeF4v6Fj8kmqTrrbVI74TCw7oeZFzF3cc0xPbPy68R5K\nwwNqcapVkkpS6T2rbbCMd2hBeopWp1fabj0YodryhZiVFKgI+4FKSF/wOft0\nRx+EVhPhmekol1VEnoCBzNOtZeTv13LYyeO9D0TSDyz6Siqx0hpdouzdrldv\ngAX7+bIF6WpqYwwVWqF1yzwthfiErOU+NwifysjlsggV6GwdtQOjKsK1RWko\nM7cWkTl/KckpuvN7j1EMxBAft3gm41np8IHm2dqgZvyg65NGCzdUjohuJvUJ\n2ExBjkUXQurJMH7N5oSzOew2OYgnimOUfnxPFZ2fd958B7eMuVWPpfd/58BW\nZKjK65ZQMXGKAiWNOo+1sdfaA+O+Aw9OzHhAW2ib/XE4b5W462YoQiCH4Kzq\nt5GF\r\n=AuIF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"cac56f0836005f093bdc5967102e957a270d806c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer"},"_npmUser":{"name":"addaleax","email":"anna@addaleax.net"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.2.1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.2.1_1624029884323_0.48293428260799365","host":"s3://npm-registry-packages"}},"4.3.0":{"name":"storage-mixin","version":"4.3.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.3.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"231d0f8ec8fafdbe1bf918015ee49fd90b6b6ef5","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.3.0.tgz","fileCount":21,"integrity":"sha512-QXiVW6bV2U82O5AWqg5brIMROmUhis3HBeFzfEvrYejSqu2Vn+IgkjWpeODUuEceDKPr5y/ESBlfKul+bnA7CQ==","signatures":[{"sig":"MEUCIQC9lrDbQINPi08UWdKKZFkO5VBpliu+eqkyvcqE2EOQpQIgLA9T4f2mg8/+/t2IcrHYZHehWgc3YEbhsQbHJksptGk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":83089,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0FsDCRA9TVsSAnZWagAAqrIP/0mVsBFiw52Vl6fZoYC/\n4KwgLpvHNEOF2io32P9yMORWApJ22bALKVtj5huhDN/f2DNptb9Jtc0oTN54\nd07ibaRme7DenUIfwfFKzSt9zyfsUsMVRXAiek8/vZ/6j4y0yqy3lflQSmmZ\nC/vlCYC0j62UBzI8Zs8lR/pL9xpmX1ulLNsf5N3WYcWSnQeNBplJbwHW9KVY\naz5FosvaFU683k0gf6Hrl8nFT16sGBB4jorwBuOo3bsMyfj0XYFd6+cQsC3F\nu0s7674mkrp8SqrLJe0WTjNZEWBcTz5c2xusWbZ5LxNXdStf5BEiugnaf5G/\nQe+ZTz0UjiGzBppnD8isk0Ka4juJLAcyPWnTYOPW8sBL3hgZ29ukQ6V6rmE6\nxj6t73lRsE1a2Yl84Q7ezz436kVszlrVhpRXxKory1gHTzp4WZPZ8zksmLOn\naCVMLKw+9VvGMxFPGLjyXpQW7vEh7Pq1Dn8tN5LzaDCkZiIwz7gTjQi3erqw\nsSjpRkZSOJbtM0wfo3IjMS531bKW/MGowHiuIdvebjrDbCp0+q+KdljddDAm\nB5ZsarLNAuBP7nJpCXr7I6hen5LqCcYpW1Dnb4oIMpceB8udVlqsjqZig8Mi\nfcG5elDm+wctJ2HpD2YcqQg+7Xqlbb+qwmMAEaM90VYza4FJRryv9ogdgmtt\nIdBN\r\n=J8od\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"558b869fdc5c6c9cd59229974f214e1a40158413","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.3.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^1.8.8","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.3.0_1624267522847_0.2969842415800772","host":"s3://npm-registry-packages"}},"4.4.0":{"name":"storage-mixin","version":"4.4.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.4.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"eea53098c7b11754a250233896c049b622732fd1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.4.0.tgz","fileCount":21,"integrity":"sha512-x0jJN6Ybhmz5CkQuIIjWhuCxEi49uwdHCggF2x9wM22pT2R8lwqfznodd+5wLzeTyXCLAebiqsMz0lrNzw0YTA==","signatures":[{"sig":"MEQCIHr2SIoUZPXrDX8qFIxUx7TTvkONhU5mZ6zItUPREIXdAiAy75l9WZTprLdZksw/U4p9AKTB+0L8b1ZAijLqu5UhPQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":83089,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0ZHyCRA9TVsSAnZWagAA++wP+QGnZurRTV67HsrTxAPh\nzUkQgtb9eR2rPPgUMjqAvRA3PIoPGWzd3FXLLE7qZl2KKJrAu1wmpbYsPvgz\nIALYwMwWsZ4CBuJhzgfF/R6EJi2/gmGuCaFx+2M/nqKmuxP9VABsx1v3qmpb\nfAMvGUqUiOst+aG8btmNMTwSUR7Kt9D4X0kZD/4qmbVYaJGUbPAs2FRQEyDZ\nl0CAxWXMyQjIVR59RQwsNOU8L3DWt/4NHK4szBkRifWNjLLC5XUc0Vacn1jk\n81sSeAmTShPtkK+sHi5Getylj4n54132S/ySvtpoX/vF0+CyYJqs0GItXWiH\nbSrwC9KmPHTcStcrVuUc0gImQSvC/WW8q7PI8IxRiYaHmBIXTtJzvp+dDRfF\n5TNdqYhz+QD5zxAbJb1CximGz3hZu+2QV+foDFvxGG06lPr6zB9Yurv5FYYM\ndo7zs/yRcf7aBsJ6AL/vmVL+OHrud217GrlcKNXvMXZISZQdc2uHMr0PiHCb\nKfkrMzSw+MMekhsPpySM+6401I4LeYheAy+K8uzbzhoRrdtk+03gMQvLSu/A\ntvOReIlJfowPgIVyiGz5setZQdT+ePh+ZTutmXzUS3whGp/uUyqirPBI2kID\ndwQzS1WviY0DmM4AZhi0xctUwIYuSrqEMICkgcYONMjra4X5iVMH97ZxIrol\nDHc/\r\n=XmQt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"34f63c07f35cc146ec42b0c7011b4a91ddbaffc0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.3.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^2.3.5","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.4.0_1624347121496_0.9369292547566144","host":"s3://npm-registry-packages"}},"4.5.0":{"name":"storage-mixin","version":"4.5.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.5.0","maintainers":[{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/storage-mixin","bugs":{"url":"https://github.com/mongodb-js/storage-mixin/issues"},"dist":{"shasum":"f93c974a7abcb5a68acbfc1c19f98e6a641f2152","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.5.0.tgz","fileCount":21,"integrity":"sha512-KisJTw89kWSNmbTD0PTIldSuyHajJkel78qUmz8b1lCpH7F/b9IZm8cx8C4syGFe8GdIHAkgAMde1r1nu08Sdg==","signatures":[{"sig":"MEUCIBBJkWRAcsU1/L+d1fw10TCAOJbCaUz9oEzBw6weaQ+zAiEAxJcm4LfSSbWYb0IHuMFbnQ9LkNsXAtn6Hh1LRXCYMJ4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg2Y0PCRA9TVsSAnZWagAAPGMP/1fGLn03diJit2bl8tqb\nXfWG+WC/h/8DdxbPaQhYuVlbQ32PKralTlUlbhA5CRINnJMtV2iPDdT5R3Cq\nOye1bgqEdLHP7akupcpYTzrlvxQSlpffF81F6xtIUbb792ZXR8+F51rLsxKs\njoeD7i5qtcJcjEbCp65Iyg8XNKCfRaXlTFwcAC1nStcBAkKmBP+YP26O6+y2\nmDmtxOik8eC7FlceTsRNWvtIBINQUW9ogMNfdV1puwAJyU3POrmd6Fj/1CKb\nr7dQ0zAuZGuf2mQ+l6wRaVz65FIZNaO84eq5HdIaHdRGC7Ttda+0iaV9fINK\n/keSteibHJizOp/Bh1PENPZDPI5f5aefzZJkPfnYKP1se2w9r/vlNOduTVbs\nZUIFqlOmuDITnTEfMjSYaF6ybtJv24HhLoFTSwoH0bnc2pVjhiihwL0hti5B\nPiFitLjnM9dLLn9ZaIWPgPkNu42fX/DYErndPqB43YL4cT2//z96+imrnQSl\nh+phoC40sZsaU7UhvaHSOjANUY8GrmBzx3TqQx4A7TvLBgbKMjrkstHPlR9E\nwIdBx1ObZmYYy2FGR4fgILLO6kUCHOIoLEQhjyvW5HvDaPb8uAS/GI3AVDLS\nPgxoDYyQAL0/i3yq0F7OoIA4nfvOTJ+FhFtWGzALYoM4HXzikzLmUasuWIQk\n1DWD\r\n=JeFm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"0819b7be289d05d770a45071692cb772806e61f0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/storage-mixin.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.3.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^2.3.5","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.5.0_1624870159414_0.17356007987766664","host":"s3://npm-registry-packages"}},"4.5.1":{"name":"storage-mixin","version":"4.5.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.5.1","maintainers":[{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"0f83de123e13e52cec9c96c3d63984bde25a219c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.5.1.tgz","fileCount":21,"integrity":"sha512-7Muq1+on0jNad2QPRo18+UNARtS1P6WGpKp8r+9rfLon6wLFBcFW9FFwlh9xcNV4+B33I7XhEP08K+FRfYNFnA==","signatures":[{"sig":"MEUCIQCCoeXcGCud24CbHWNvb+Vp2sIJeXG3lVSjGd+j1kS27gIgF87DQOpabtqsKwJ/O/lH4bvHE9Xyy9KESK4ZeNwwEbg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82937,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhC9JfCRA9TVsSAnZWagAA5v0P/0AktoYxDlmf0SbOg44i\nPs17AYaOUhao1cMjx9+i4p1bTL51O1oPUbdOa34NwHEyWYmeA2yaQJcz1FSb\niXnxb7jOkRve2+c569RWAqJQ4xv7eJ7Oein7o5jnp+h3CJI7dL/6gIHL/nrL\nV7704XANGqerJSECHKWmKYSIdZEbzaOL3Nsoozz9wRPwZ+eltn2RQw1tDgM7\nJvVx++w4AVd5WKcQbWrtCYX6kzh/ni8NFtck2JIlcyo7EkhRoj6Pb4dFAJNn\nrxwMEd/WHbYwAnN5cqSt9CcTjonxo+y/l5ZCA9p3COYDmOgl1Y61IPJIRZlB\n8jIMtllza/m5rDYfvexoMwKsOG7rp+RsLvTITh9Pk/m6nWVYYXCfOl+9FM2H\nVKkfnsMZtSVHUlwZ7dlX4DZFkZlpu2d4JuaIRBMfvLffQi4xj0cNZp5YCmKV\nQ0EGhHSGE4DkhTEUWG1o4uNSOHNYItM4ZaO/7c/rNtEpXgcVDJDkuUOC7GQt\nZIzWV5jZ6kIkLE0FRNU39JgKESFq30goWBjyRY+N4Yc+c5Z9viwvWoIHbjiC\n4II8uGAmWJd029nfJ1aKHZ6BxioeFHQorYKVuvc9ewDtWU7tRdj+XdNUJrie\nG6UFaoy2dBCd1YIJbsyAnB0zoPDZMJJ9IB8nxb7AL7ygcP78QFjXwXKgKQrL\naFzr\r\n=mrHg\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"8ec19acfe461d3f9c3e6eddc550669aefc029180","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"addaleax","email":"anna@addaleax.net"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.0.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.3.1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.0","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^2.3.5","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.5.1_1628164702824_0.4788592818528672","host":"s3://npm-registry-packages"}},"4.6.0":{"name":"storage-mixin","version":"4.6.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.6.0","maintainers":[{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e67d5578230d184224d4e8ec0e89715325eb258f","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.6.0.tgz","fileCount":21,"integrity":"sha512-4ekvDj5utcyXOheKP4ve7QY5/Zr/XtxfDDdlLAw40sakPrQ4ejmX66fWLcQWSlFeovS/LWC/zVkTsu43EulghQ==","signatures":[{"sig":"MEUCIDbSK4g6CT/9QFHPGHEo1742wQjICpe0XlAZgQzcogNPAiEAvvFjJZlFsm7UdCm71p6VScp3JmZW3beSFa6tA7HmcNk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82937,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhE7aECRA9TVsSAnZWagAAGeoP/0RdsuxUTOFK0m/NBsef\nsTkx6C2d6d6eTIIO6J2Z23QXN1i7jlFErGzvOKWXYqS9vO5v6JNJNFt+vesq\n/X51ft1dYs7v3jnd4QWHtn/rUgpdK6SgWInmFF7WAR7cJQKMws4LTQZadRbn\neaJWTzaR7RlSxisqhkwIlL6FZR0KosTJBD4MBswOiBkmRbl353RV+lEVFjCM\n66/oPDgWx5VhTsNA3emyRIV+DHdO/rxCh2Av8Lynr4w8nkjf7JMqtE+wDnO8\n1v8YfF4olBYTFB20/8Qkf6LFBIReE+BWqZ3qa8YLwF+Fgv7c1skdHactHgdP\nsiQ/pEYZwP8T6E3fM36VRKgAyCNUxEQbZOIdp+Gg1cg2yJ6DdxZjD6pP+F1D\nMXLMYCkc5TGX70NDwS5jQ+h5No1Q4Ws6rYYqGlV7G9dBaobpNTcExvqblXCq\n4evLB0/q/pUvGOwLCUpa4aiX3PPbO8RzMT/cf0XB8PWthinwkPFXwf7HU3gD\nK02QjDqVIVuCpOu+Fh69C4d9s+S/lCkJNH0N7aZaqYEsXYI1fNJuve7AjbkD\nzyLlxj1EB5Yilro9Jdt+4XrAdp710CFVnbXQHzskOzzLn4/nUpM71EBtgvX/\nLO9LCfpQiXPd8XGq2JVjys08oeqk855EbNX+WZKtaHCyIBdaLE1d6NhjJwId\nk+fi\r\n=XFME\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"e00da432655fbd1b723fd693527bf481f4c1e645","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.1.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.4.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^2.3.5","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.6.0_1628681860817_0.8045842660479645","host":"s3://npm-registry-packages"}},"4.7.0":{"name":"storage-mixin","version":"4.7.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.7.0","maintainers":[{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"754fccd1d9ae3fb0512d027b67a61fbf142573e1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.7.0.tgz","fileCount":22,"integrity":"sha512-P/R5B4neqBUxOZfFJgGCXsTPrsyYF6q7UZ8JYEfAzVF6xIeilMlFZzNsvkqwkFBLNm6FIEqpbhCEAcXpcrCcuw==","signatures":[{"sig":"MEQCIHRprdMDcF7noDyEhbg4th+z0YC1AIQR7wJ3KJReZj6OAiBJMkV4G5AbIz0TAtxHCO7Weu4pN8MNMyMyGyxa5c+VjA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84035,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhQc/+CRA9TVsSAnZWagAAX7AP/R/rCLe6wZzTlnWsQKvh\n0UAxb4rxZwqry9FXpLLK6JGCFKpxbzjf6t4nbB2nCxpXouw9hKOpuJAMfhTU\neHOdZqrVCva4j1Bd5Akr+evNdWSqWaXxLKPMyWXOfPo1bFLVOo2x9vDPNVrb\nMo9lmj3uUFZZHCNYh81eRdytL3ZS/I8e2Jl7jhwQncqfKODlIaOY1oTzXUat\n9c2K1U3eoyjCFoaIc9MyqzWRUyEZpFU6ZOwD9LPLvpr66O+5szWzTV+2CGHc\nizHMEAzu0DzzVsg9zRK0SAyT6423/5wRzqce/OdO9vMhe5BJMfZVp+gTCJ5Q\nO1eSJOaNPaCBZzvTCM3GTJAZeLVzloah8zCPU1oIbZ1iceYHYxXZ4bDS+FiF\nJpE6BGp4qp3Hg9jeoahG4qt84XJJZffSzQHYri3wPQEisYoKdT2PPS6xgA/7\nRZrQ84DwB4/gQRMpgdpbmpJ9MMcI117LrijxP8n04l4SvmJtimLkR0Ocf4B/\nAxQSnzPu1OCSXh0tD/QZefW2G5qMCHDi9kR4XT7hJd0/d93M/K8Iiv9Uf9QF\n6qXBWSLI36Vp6aJPcnDuJ1WyF0BR8iDMEtTUGPbWbNoiI7Sl0Gh1vRIaZApc\nmKRfOUxr7pN2+qj9BtFTB75cdiJYb7oA2NP8VCMVE7V8WzUOxP8UIRkXz00a\n9cCA\r\n=E8Wd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"455c6523f99a08c6796480d59727b53bdfa441f0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox --renderer","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v12.22.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"12.22.1","dependencies":{"uuid":"^3.3.3","async":"^3.1.0","debug":"^4.1.1","keytar":"^5.1.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.5.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^6.1.12","xvfb-maybe":"^0.2.1","electron-mocha":"^8.1.2","electron-rebuild":"^2.3.5","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.7.0_1631703037898_0.540692619915252","host":"s3://npm-registry-packages"}},"4.8.0":{"name":"storage-mixin","version":"4.8.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.8.0","maintainers":[{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"c04e036cc415cdc5abcb1674d93695f36fa6fe4c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.8.0.tgz","fileCount":23,"integrity":"sha512-qwpGc069ORwNJHMnvxM+xP7qLlXfhCvxkxb4vqVFNeM2UR1IyuRCW51bAahVmrrDGOAWShg7CY7Z7E7NK6bCGA==","signatures":[{"sig":"MEUCIQC/VuxRhymq3PsbFRFfp8p07AvgHKfHTY+fopNgEOqUFQIgFeY9L+KdsNkRpn5G4cr0uvRU6o3KB2/W12thZYsupe8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84660,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhl4XPCRA9TVsSAnZWagAA1OMP/0T3ZOLAhXpc4UBie9Xy\np/FLW5lQYSUDi99kyU2zdIcZexn7r8IMS3jbSvfCA7h7sPuCRAY0uSF6qPfu\n338eJguJLAxjZMLJ+x3KaGVbfY05Kt1US7EZdwcOJX/Ve9PbokJCCp77CDqu\nowIWuuO974d0s4DHVYoNC6Y4/1U4IzBm/VkXAOtV2WmFJLIk4a3jMlCWQdLh\nFkaNxUs4GDlZZFLbfzep6wLkkDlj1gSzooojAkFC57YevGIwn7U7opIgcaZq\naOSrSpk7Ux8nqEDRdLm+xz5Hg/qgJGcaQt8QxF6zksvd4CgpYUTxR6HEEtWH\n9B4Hx/j1Inve4sshs/GPDJXDZlbQ/1RQhSzW6T2dOZL4zXnMbS+lIobuxQTK\nCddNT6q2iSC9JLWiD/9pml32oTQ3MzJV4FvNYTfslKEPexfJ+Mztk2QVQwKs\nJ9jLW50EDEmJ5QQtfJSIC6sOo5A9LdhxSaSfzGC2AqtqjQwyNEpymxzmqODQ\nE+NYRHkbub45nmPe9KKFWiXi1wGxDc08+0MAx+0vvIQ+qVICTSlM393Wghmt\nyLrcj06hfM2ITQOFRAq6iN8nZqu8PCUNcVwdgF8IFXCxbNBtm4JHjLCd8KDE\nfYVqmQhahddSsmkTAx02UkcIUOGlkc4W2yb87IImiSkkcB+vskKI42sm3foJ\nr7fx\r\n=UTmj\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","exports":{"require":"./index.js","webpack":"./index.js"},"gitHead":"8ef2cccaaab6d84a5fcd633ea8dfc4c7a4db551f","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.17.6+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.17.6","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.6.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.8.0_1637320143561_0.13258329991046325","host":"s3://npm-registry-packages"}},"4.9.0":{"name":"storage-mixin","version":"4.9.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.9.0","maintainers":[{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"brookescarlett","email":"brooke.yalof@mongodb.com"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"cd6c17ebacb292dad00c8acfc87306ff36f67047","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.9.0.tgz","fileCount":23,"integrity":"sha512-F046hz8MehWM5+iKONQIUZccGNvGYpgJ9r7oL9/afdTvkZFW0OwW85pLVdNHMxW1U/goYCZtsJ+lLW0zbmL4pQ==","signatures":[{"sig":"MEYCIQC4OvHjiIYtcQzJmLUkf9jzo9det1RSPTpzbdA2JfSKQQIhAOVfy81S1ACZ/+iX9onxWJIYB6kYnspKzoZ+Jdd5nnAb","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84660,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhweFbCRA9TVsSAnZWagAAId8P/1SbWugzrZ23QGndbvdI\n0Lt+d4mH9gpWSA5ifoNF6e2mjuCh4QiJdblwj1qY3+cBBaMI+9Tn6wE/OJkC\nCcVyo0gOEQ6ebNp4kVwkpWGArPD9UietWFSOGyL9ksECHEe5Nr9mJu+dybH6\ngxnC0u+YroAGfikcSUUpvmQZGLqfO34zg6ZgL4j+lxOWJaYEO0gG6z5txNE4\nvtlLKBi8tFGa/ECysgYWZlE00uHK6l6bgqiKeqjLHU+HKg5JvMmAMkiYkyqa\nIWlrmVoIzzIdpE3cekaVxNPm+12rirBQbrLWXCAIKOROTdf7bsGf1aj4NKY8\n4h8scJDVmGCoD3gxD00oPuvVFmERTv0VXHnzZC0BqCDp3WPj5gCYPAlZvP3X\n0mhsxXnRVX/P5JhfyE3yS2h7xM/YQVQ1QE3wMLsuUkDb3aNrNj69lpSsBKDa\naS2Jw9n0ZU/fjADMfqAyXSB67mE1mh0yP3X2jLHMH1V+dFwMU8o3YwaOb3gO\n/uJMdYaPX5Od6r6qd6RD/J5VkodBxLvpmT2OuLIApxLY1xw/CgnW3iJhLbrb\nN+lb3cqmNstX2nfbLXgBmwkcB6r0PWsunjccUgHj4CXDGfmJ8tec6ZS2lwYv\nPcpgZsu5d5EaYyP/amKy3EQBq+AJYZJQ3Uow8v8VyPAmDMr8foI5lqkDam9o\nCTvd\r\n=CgzO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","exports":{"require":"./index.js","webpack":"./index.js"},"gitHead":"77166e3754e36e95c7ff7efb5a0ce5e0990b0ff7","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"alena.khineika","email":"alena.khineika@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.17.5+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.17.5","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.7.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.9.0_1640096091185_0.348673345222146","host":"s3://npm-registry-packages"}},"4.10.0":{"name":"storage-mixin","version":"4.10.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.10.0","maintainers":[{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"rosem","email":"michael_rose@gmx.de"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"a5de1a284909d46c9b03af409ebf6d41a81a0f05","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.10.0.tgz","fileCount":23,"integrity":"sha512-OakS6GT1wtHqY1/a2PSHLm2E6C17taFLcWpbtwQmgT4yrjtOxkJD7fothx/GdnCz4Gnn42GRRok9VrdRvNzKOQ==","signatures":[{"sig":"MEUCIQDfk2lA2m4kkvv918q/+H2A27isfkGq+1cJAmZgC2cZVwIgVVI6idSCuugl3okRNVZRPucBXh8iQNg8/gKzz6DciZA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84790,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+9nQCRA9TVsSAnZWagAA72oP/2fNpUjQY8AVwKFMmy7Z\n0MCHACYuvPy7TaM29ZJb46JbpXg2V5/XqVwqm3BOlFxL0uNWrv7tyKipiQVI\nVtAyMVAtt6a6z62/c2nPjnYhiMHswqWnJWLRAhSvGy6P0uRXTFTyLCI3o/Tt\nOe5HP8UiRPLJcw/ETvgaL11ynhP6nYh77VEEbXqpNnTK3vyEH7DYyD8IdR1V\niDSZUM85WqskRAvmSJTh5CcrmCLUsgXpyi257hlKhthMmxLdfH11bgWX/XfF\nMDTmjw4FD6djAoWGT/hmZh7eU9Pq/Cj03BY9QzJR7qIr7cNeIrTPUtqmZKIX\nkMQx7p4I0+eWylOUBtoWU71izgQjaa/k6+v2VrTpwU2WlJDKurvmeuVIvGVV\n9AqCex+r6FazX3BLnOl83dQxoImaMxoc+9Sy1r+nntrliE4RMCYHguFhDaUV\nOfMqAR6P5hP5AHpWVr2JyeTHlKFhC2bNJTsjQVQT/TvZM4Wps7PuzbRty2BR\nxMh/3fnxSbuWAKw9KoVxynGZzJHUtI7Mt9afNlmlVPJZjdCEn9sajjON4MEV\nGhB3TGqDdAY6uCtnb1mj82gEGXUsC4yfilEzhMHv2PhpBGM4z+RlIae3XhMf\nWqQtb9wazDeztup0dYQto3HXG5Yl3vhRqebfzCrkcm5mX/0vmreZJOdd4ukm\nDV0b\r\n=so2/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","exports":{"require":"./index.js","webpack":"./index.js"},"gitHead":"6563679c816fa44691a53b7e27fa0cb5539e0854","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"alena.khineika","email":"alena.khineika@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.17.5+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.17.5","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.7.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.10.0_1643895248212_0.7442981359003047","host":"s3://npm-registry-packages"}},"4.11.0":{"name":"storage-mixin","version":"4.11.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.11.0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7ec585c45581247894e454a4ae55dd91b949aa7a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.11.0.tgz","fileCount":23,"integrity":"sha512-Hq823wQXbBZgTraF7LW/113GcYagyob6qrBFmEdeBJ8iVKGsM2nZnV/ctRc1fFq97DkrrEiV49NXdFbZkFw6fw==","signatures":[{"sig":"MEUCIQCsap7P80KYRh8hcNOGmDZL49fmdtO3+Km/iaxDj2sxEQIgMVLQVb6kIUW2pS/CQURWz34OT56XvEQ9e3cSRCASlnU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84790,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiGOMgACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqvQBAAiCBkVhDEUU6Tk4t3NV057zikLtAvKzU6J1p2VTbFgdMHO7hh\r\nQthidEF9a2nhYhRlgB2TALuz/Eb1mq0v9XfXDaIA2RftJ17fH5aG5YnL02DR\r\nN+h68jlIgxvz5RhMHrMkS3mBVvOrYKArg1bWxRGwDVRefsRt1j8JfoOGpKXM\r\nPqbZqGVzD8ATItvoCHd4M/BksfoUMRg0lzIvFsJ650X84CBYdIroWi3F5p7l\r\nfl8PeFFkLsIlDsUDF0t8wLAfUBmjhDrk3Gkou7hv2jG6uKt0CN+nW1ahkGEe\r\n7ybYMoGFR4DOntN/d3Mnvz+8/LUp8WioVj70t1Dz1o7qZRCaYXJJCLz6sWYI\r\nYadbbs34y0+pJUm9hPglKs/36gD56mHiWzcdgHN3l0kwkIZWyCYI8kWgu7Et\r\nuoo/82MsjBJQ9o2phmAmcaD2xJcViCgKAwmhBr8ZQjWLkjVKMOBm1p03vMgF\r\n7X5jfCpn8tchu+C/t1+ootsUbglX+K+RFst8GHuognu/fw+uHrWvXN7z0jfS\r\n7k2FUPkvkkCiYZR0trTg/DwTufKsGAfQudP+jdww63qn/jyOPGcSl4lGKQ4Y\r\n2IoebxU27CGWmW3EJpdWmTkBdvqjNmLFluOMQqt50fPXCQ6cOwTqo1nvpJ+3\r\nMmZz8+yFI/qI96gLx19OID1JkWhCIrw2jdA=\r\n=A7io\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","exports":{"require":"./index.js","webpack":"./index.js"},"gitHead":"2bb63cdb1d4e825f280c0d2af14b7298c5769490","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"npm run test:node && npm run test:electron","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test:node":"xvfb-maybe mocha","pretest:node":"node ../../scripts/rebuild.js keytar","test:electron":"xvfb-maybe electron-mocha --no-sandbox","pretest:electron":"electron-rebuild --force --only keytar","posttest:electron":"node ../../scripts/rebuild.js keytar"},"_npmUser":{"name":"mabaasit","email":"baasit121@yahoo.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.18.0+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.18.0","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.8.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.11.0_1645798176463_0.33334269659572446","host":"s3://npm-registry-packages"}},"4.12.0":{"name":"storage-mixin","version":"4.12.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.12.0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"49a63efeec37d02a6341b0440786ce41099bdec1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.12.0.tgz","fileCount":23,"integrity":"sha512-OZRjMcACyxdAQRiKAYAvcKu39ozSMW3XhKI9a4YEcacZb+DT8BoynGpBcADieXu50lK0PlCKN7HsD+SV6y5cJQ==","signatures":[{"sig":"MEYCIQD+BxI4QUC5vBZej6U9/K047DPZyTcGX2NM8ychU0fxFgIhAJdQ6mGi73TyLVaPkxIfXQ/CfOOu7ptq5V83lexYH631","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84574,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiINKAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmohsA/7BagFs4KC4Bz4LLHynZsrzZnE4uI3PHkLKYkBAzxg5eZFJK3K\r\nMydpE1GpkVORpM/yu2AUon11sEPkqv5IisXmshtg7uU+TMuAHJ8BWGqENbW8\r\nwbchKcs6kXBd1hLTdJnYHRfr7gzLgnx0KVQ+c+QiPvPfwqmkLpk+yABCoFPA\r\n2pxv8D/oK1LPPa9qOZulstyMAGXwsR0cQrZ+PI03prRrpb35LXOT0Li+4RVZ\r\n+e8E7ZVUFCiqlYmJe+sa0NBvULP34afpL5Hsj1myjI4lsfQXwlb/wpqlDREA\r\nS74s2NTIJwNkyS2kL29a8ljUHX6FHricA+TuYn50maORVv041jweiutfUOIg\r\n+jFuvIo0q9R/u2vOTBmuNCi2HW/NkHmNS9LO92nZphCxrEGCUqy8oWwK66XH\r\nV1e3ENtjL497d6t0g0+7Eg1/TJK/X4vZyoRGPHCZXqjRRTEhrA09f5CUi2tH\r\nIxVFAuMLou1o7juTvK1/dvuEMTq5CPaNDhr/jQ92hPbs6JPs4ITdQ7yvWYs4\r\nlOpqH24oKFvfPofG5RftekeRKHajr1BP99l5/V5kwqv/g4Ne7+6CBjMM3Er1\r\nqnyRmRgPDUdKlQk5121yn/JYUgTo0wgDFyWzzusRSXItpJg1AsxB3peZzZGB\r\nNc7MbV7ezJi1gOtyOukaQFq1IB8FOwfQCiw=\r\n=V80t\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","exports":{"require":"./index.js","webpack":"./index.js"},"gitHead":"c125a379bd769b3305e494b68a4fc9bdfdc7d1bb","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"lerouxb","email":"lerouxb@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.18.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.18.1","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.9.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.12.0_1646318208004_0.9422403963016548","host":"s3://npm-registry-packages"}},"4.13.0":{"name":"storage-mixin","version":"4.13.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.13.0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"17a2c643c66dbb124a3446b8e82e14d21d550ca3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.13.0.tgz","fileCount":23,"integrity":"sha512-ovsXmHp1Y+WPpha993AaJSEgrjKsWVACRMhBS7758iMvI2Uz587EVk9nI2ELP46zXDRNMsbLbQ8LSE+b0QRPyQ==","signatures":[{"sig":"MEUCIQCrG9gHwDhwccxx1PId88aPfKqWdgZWPlodOzaNtTrgFwIgc4KQAQT7pjsIlwbIHctYYDwF0RFby+20dUhaT1DAwfg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85126,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRI/dACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp2rw/8D044OPdLNRK8l/sc2qAXYiRJwnhAmZ+QeuudsAb2mAKiLnjk\r\nmdYeBmVu2rYXYzw+9nbe1fMn/FHWvn0vJsT2uJOSMuhXgJhb4D7QXKQNNU2f\r\ndO1Rmr0TuKg/vnbnKfUv1eHMTbhp27B1MJc3yrU2ueUqGpFhVJPFsFwNZOlr\r\nqgBw/4vhb2/vRsAZF3JGQ+0zTZEBCovWHyulYeM2nF6Hf15NQBhMGW+vVEwg\r\nT4rL/ShGaPtVwY6Vs0nF/Saeg2Y/u8tUS5lIwuogYl+azwon628CY6EKv2Wt\r\nqgzWrU1x7Uc2WidQh25JrjcW8pdLTIfhVilc2hoMZ3bynR9MPEFm1tNIUjCP\r\nk69IpAHUcqd0ZDtma5PPP4/69dVUDK6urjE15Ge+KB41VREqKjK2eGX1ZYjj\r\nBnO6ZZtXPF3vBKkg6Aw4JJmnhOyxWrlrIw0AvsVgN4zWnB/zvxa53zTI5IXk\r\nM84KmPYiHFERBCQiBNsHJz/36G/AFaVeUO0WuW/kHdLXpy6HvfFZCmvmKgJ+\r\n4DIDjnVf/XJJvGSOXiLNHsMXLx4rN+6x2PLXXCznFBvpIKU+bGRNjTvM6BgH\r\nnzLxy+kmLC4BZfTYrXlf79XezVFj2e8wIatJHCAKoceU6qVRcC3jrTJ60YNR\r\n7/Mwk5A/aEY++SOaS3CCxTDnIMa2F/rhbl8=\r\n=OY0t\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","exports":{"require":"./index.js","webpack":"./index.js"},"gitHead":"a1283df32eb52881cc00eb73f8d435f772cdbfde","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"rhysm","email":"rhys.howell@10gen.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.19.0+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.19.0","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.9.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.13.0_1648660444774_0.30093691666712385","host":"s3://npm-registry-packages"}},"4.14.0":{"name":"storage-mixin","version":"4.14.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@4.14.0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"team-compass@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7535a0c706a8de7f9c5f48f70bb4d208ccc5d983","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-4.14.0.tgz","fileCount":23,"integrity":"sha512-pvEhJ8BXSiihahQasTeGshTDK6oLfCnPqttCV3JB9ZhAkWhoEY+Nil5Ok+Qm3Sde7b86ASV6kQN6uN9KlCQoeA==","signatures":[{"sig":"MEUCIQCM7MumYQZ0jtOFAzzxpgNmlN2qsKrbPD5evH+++6J6UQIgKF+uwttzTp39aKpsP9rOAnqZ6Nai3eNo5KC5Z4BQmvs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85080,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiaW+yACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqONQ//VydgGc54w20Sir8ncBKA/G+jf2TLffAzPSwxRNJXC+1wh/tv\r\nPPzOxDWSakeUrA0gRXvAkj7i6ADOwW2A3avl1YeOC+GLOmYDx+WCk2H1QbeI\r\na/BsE1NL8RIi5dvJjXB4mpAyhjWBxs9OKRLr62vaNwKdLtXN/fs8kmd28syV\r\nLXNw7surFIjX4rOTTbBcitY1NbrOdw/AYCzAyEzYu8QlRM/w32qAg6ypz2oB\r\nqxQXbNN8o8vv/aPe8sZM0ffDZ+kh/sDvdLSmBYT3ksR10sawBVsVNdZ7AHgH\r\nzKqWHflySqbhZGgsJgrObGVgWgof7Jq372IQkchSCTjC1EGkviZmm1zbL8GW\r\nfVS99dnXGcUDAx2RPDTEyJvFa1oXQZ/xGKVGR3y7+2VdelteqTWi0p4MCrMD\r\njPa8uv64rSwcBNZMtWMc7FtM+LRqwovOzOukMtnBwWXHS1lccRz5QeOBF5YE\r\nHnHe9OyqpG+bYHL10td4RqCHZth8TPZg6J4f7EQSzrTg6pchTDVHatpH+qRi\r\n8Sl8JXNsc0O/+Lqh+u5F8Q5ynkHKTq8KAtA4k48Opb5VsL6vHKwS7vqeyrjm\r\nmEtk/0wkdnV6KvOMLAUe6OEwhhIjWOXKeHJ44zslnplh1v9k/SxUpIrutNdl\r\nQBVhHjehO/0l89B55zgRMBiaX+4tJlAO4y0=\r\n=Vy8v\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"2c4149184e87b8340851590663287b914d7ee63e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v14.18.3+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"14.18.3","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"4.3.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^2.10.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^13.5.1","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_4.14.0_1651077042713_0.5944863495465429","host":"s3://npm-registry-packages"}},"5.0.0":{"name":"storage-mixin","version":"5.0.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.0.0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5c0d951cf3893afeb6bfea5c02805131dc5822e9","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.0.0.tgz","fileCount":23,"integrity":"sha512-f9r/7VSeY8nUBTJ7z2FZrt9kZvidJego52ZVz8cVegN32oLhjUIlicEVPt8WWpQL6KlK4M3A1iljnKHqSg9q+Q==","signatures":[{"sig":"MEYCIQDxIcP6qsWij+WlBp7wPNbu6LGGBUyh63qyl+ENQ9a33QIhANXnrhgtymjiOoICRRsbVR2QnToQhWvVLoLEl6NBOL+Z","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84708,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi8mBMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq2aw//Xa7dTK/sLicP6qCojhVeHzSrr/NB7UPwgXzXXOmMvUNPJzc4\r\nNRG+YoIXzKqYNnjS4g7af/Jr03LXcpPfbOBBF7Kh8K5RwzwzVHyiuMDbUWl+\r\nWkP2s+QSC547jXyya9/FSI7RMALd2kGqSBr7gvX+LXb43dkdMcynRie3bvcD\r\nJZPcMsTfq7Wu8PpanDqiAuo+K8FT7lK50kgma/RHCJOJs5JJdP+oSU+dmNMq\r\nPjH12G9NKL9FQCfz+vt3ZChq8OaXlbPGqGgEkaHwcqYpmjh6wO6RizuQfEdi\r\nEEFybaWGiRl5xvvAdxsKjBLsXFIq+NPekyJ3webMWVXCiYlGyTNusGzAlByj\r\nH0PGYohYc9MTbIECkmmS+4p3DBn1qGVCqcBygrA7zTazwYuZQAjCdaARamPX\r\nZ1vvyGOgmo3N27p0GdZXsUvg33CjguBkOXzFH1wM7EDQn1tyyKcoQ4o54vKs\r\nW6d3YF2PvvAPteOyaE/x/2WWi0EOo59ZCTaaQP+ovhjjB2T61QBih2x+34U+\r\nJmzQeWCI60Q8tvib78bk1qkZrqCa+CxVY+fgANPOpfyfJZWdFyZF2YWN1nQK\r\nwBmeLL57VXiWOJxFGBOMBkMU2VQkol6FZ1UGjkd+crD1p4dkEtHJf9b361CB\r\n4+HDXXXnLGAc4QSiilLds4PZVwXW0G01Ia4=\r\n=v3ty\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"a30734888ab496a07d58e26870e5e33b374e98f7","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.15.1+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.15.1","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^3.0.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.0.0_1660051532610_0.01779162849669369","host":"s3://npm-registry-packages"}},"5.1.0":{"name":"storage-mixin","version":"5.1.0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.1.0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"fd54eb9d0e1f0aa10c1ad19e1e167819b3ebb057","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.1.0.tgz","fileCount":23,"integrity":"sha512-FcHSdOMt2Wj9RzqoTlDSoigQBZoEQ8sPetHz5LT+fzS9bbtPGXevGGskEY6P+bzWu0BbAeL7VxtL4jPCTIH52w==","signatures":[{"sig":"MEUCIAbyOpsvXzqxjVH27Zaut6tld3wR0VI9VTg2AtQYILwDAiEAncw7pC5hk1+SszxQzADdQEEW4birho3IKl4SEkPZ01A=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84745,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjLHu/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpRFRAAjaOkpmKHBbPu15lopPW5WYUhTQQrZuuvdf6FhMqU0DX/kyUe\r\nx3vLx753dDi0cNiSgRI2M0iPms9eIiQ4HMbfCCVrk420S41hcc87ys7TRgex\r\nAehFy+Ms6ST7L8H10RcZqMcRnOKmoXTzE3ArSpGPm/Je9ptRRSCeYvuLVQ0u\r\nAXUJ+E7SwKEZBD0Lz56njARFCW7BkuXKdIUObj5yIu+cjZNYpvZtZzKeK26d\r\nGe65ZdkoRjunFTfRPoy2Oh2Vvbz74074eFhHK0ik9bTOK9AJo1u4u51Sz22g\r\ng3w9v1n88gChfDI4Q89uizr4f62zyNbnJqUzRLu9NDPAxdraKU9dlHDHy2i/\r\nZAgx0lUauoJgkuYqszy4gE1eAYscceWGttc2RFMjOMP3C9TBjzflRkfGPxuy\r\nqxoi9uCbXba253fgcnWzfOhxYdk/LGaCse4WQtBCupR9gUrTU8h3Yb0ZeqqB\r\nvlVyB4Vy85PClVrUTSNsIxnEtvrtLvt2Fx7CBwU1PQivRwVuyc7lZC66Us2k\r\nR1q1t6NigPkoASiE1J+nMFbzE87TsrpwwOvFK5WagfHvROt2e2bWf8oIVrPx\r\nftzA3j78ra6YtG70usCAiTlakNEdR1bXtDRIfRJ/l2294OrK/JcRcTU7oWBt\r\nGAwwWIcf2mOUyFpACNh6ydbH8y2CV7BV7qs=\r\n=JH3T\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"51f04a0ac45c3b51a3ffb98af390c811d1404380","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"alena.khineika","email":"alena.khineika@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.16.0+arm64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.16.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^3.1.0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.1.0_1663859646697_0.45951058700276826","host":"s3://npm-registry-packages"}},"0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18":{"name":"storage-mixin","version":"0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ebcce9b4c02d7edbba936ff76468e5a4b493b0f1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18.tgz","fileCount":23,"integrity":"sha512-hBTccNt/AbPulLteIEU3uv2DZuNXqzUSWpImI+kdWd+YmGm+HbXrrbO+KeCCIJdApUfnspCt2iMgH8QQsOqRSA==","signatures":[{"sig":"MEQCIFqNVoZO0wzp30VUBKzrLfYQiL2p0gaAj4pAYUOdCtHsAiBZDsmgjIJFxdU09mETfM7N8rpcSeMnGHlHtNKUx4gq2w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMaZOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr8wA/9G5daGhHFHsJckImFT6/UGvoynknUaIzOSIv3pzBpajXikIoh\r\nh9JwsNlQHx2HQbMcA0e/d1zhNkIaoOuwOWTjxXfpHozxq3c3FNdNBRwbxHYy\r\nzRjqhWsc6bZGgtAeiPSCuUTzQHkOXrwTKP9ifDWspMHk/KRdqWiK6s1udQV3\r\nFTwznC328SAuu+pNkgHsErikLIrCCTSgWvzCgXXhujVrR9MufR1OZEdIGFXF\r\nhMq6qnopZGC5oWC30GoD0dPmGsJ2lZ7iAigMXwOI/gLygdmVQo7WmKoG0XKy\r\nHLVEKnwOiT7a4n58ylH90z/KRmQKdApmXizcwlAeWH62WbLbUXRG0PQb8aaR\r\nzzDS/sTv8JVjHLcefnRXZ6As4L43vS7Fp7xCaIcpzq/0/uJ18pMaZXrIU7/1\r\ndgzKLNbY++88FAwnqWM8XUaGiYGD4ucp+q6ZOBRk7p9C2GTUdcmgFj3fGdk/\r\nlVcfPfGO4dqBfOSfhfncapawMcZx8H1tfy+nlKRcXE0CTf7/ChXhjwI2keWi\r\nmmkXTYumveOO0BzXOvZYbGlRHvJ+GBrbvJ8HdIbuoYS+/eCAc3sBSyalfF8Q\r\nGFlbfm2OmI0swFIOsto3Sc7al8cdxdujjE+r8J7FaQu5PFulGWq5qEs4Md1k\r\nonbe8jx5OblFxRg9cPEr9fSgTs6l7FUiG2E=\r\n=7dq+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"85bec9e9b95acd9ace066254edfc492578f4f8b2","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18_1664198222449_0.8047021214958383","host":"s3://npm-registry-packages"}},"0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8":{"name":"storage-mixin","version":"0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7ac8cafd936968368e84799ffe0167e139c51b17","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8.tgz","fileCount":23,"integrity":"sha512-NX7YE8w3Qn23bwezCbBfPTvaPDIfvpwj1l7uIcYD5dDfFmNHKWSNtfWlzLtL25BvmTDMqdlCKAheE4EIavR09Q==","signatures":[{"sig":"MEUCIQDq6Vr+CqDMCwFle/2nzizwO42RaofjWa0eFDBzX3TwvAIgJQtW8pyHdBlQl0Jsx+sf+MeJuN/6YE2fNVDqIie0GEc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjMbIcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqBcQ/8DyicNCHtPuEEtwwlzT6KW1R+gL8Ifc24xkMD86Rmp6lLHW4V\r\nofcJWZ3+JmdFjll7nbK5kFOVYLEIsKn3Eiq7tFQrl+g8pxBjDlpDVYtdby2k\r\nEF3qKZhjBMC6g8WZmYiXwawtjO34cJbTG7Jjr5f0v9cRqIOdeQRQ+/Gf2ypi\r\nPya3QnnDbKR9EwOLTESu89Onr7RytkwWdckoSnIrdfLxEQsFCZj5zmwTRIwU\r\nQP6auWe0k1VuU5GncloGvbpSGr4WSokUcDyY8DqNeOCV1uVPQ2oL+UMB8ORX\r\n2BezLgLpUYaIpyybOU7VZnfdGUZE0Egvx2pvdC5W2QAurzWZZK3vYlduw9K2\r\nKKVvaZ06Lor6JNTa2nMS9vBncm2UZ0gRj9fWBHamL6Z8Eb+aeD1Vlnwxyhi8\r\n36znmzNYVjKNB9Mlxuf35MknuidEOUFFdJ/lWDxly38p+S1K7bi8j7gs9ndp\r\nyH451OG4PXeBfxEb4aGR7fa549GxHs4LBy9PtG3SM578Yiscb1ZawqpOWTQw\r\nYQVHzZ4E+u0zhHSml9q6ayxd7k0XwuPxi4FMFPUtQFoMbYoREvsPq029rLZC\r\nPYZ9rzEGh/Y5FViX/K7WjS6H4uM8oa2N8frKR6dHnPO8DDpjcSiuhl+6f4hp\r\nSNm8vbcyQecodGMGhsHX8FfT8qjqq8SYP/E=\r\n=xbYv\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (darwin)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8_1664201244589_0.18810705845681897","host":"s3://npm-registry-packages"}},"0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5":{"name":"storage-mixin","version":"0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4c584ec7eed18248be2936962b24d9f85b858a34","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5.tgz","fileCount":23,"integrity":"sha512-5vZAU9NfqaiU/Vcbrh9HSIqgxW3XnvU58gtkxtt9c3Z4+QzIgC391kY8mLHHk627AlsLJK6nJuQ7rQxuvB1dtg==","signatures":[{"sig":"MEQCIEnZ2eEtGoc6XlZO+Py9ImQfsOanjnthR3qO1SUPooQbAiADDFKYIjuNZ6vjxl0WmMqbQdXMMt4bdu0axWrri6fU2g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjNHwkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpqIQ//Y7D+zR7vek1bm55AOnhKyOgayVNtnDrG8dQv99S0NWDU5qwH\r\nWs13vGr4iUkomR7dDIBZK5hEwZlgznoYK7gaCJ3MdD71Y5VrCUVfRVl5yL53\r\n0NzTba9ho/l/3wIqLCg8umEtM5I7HAVjTOOH8maDOuiHeEYY1uc1NdsRCRoQ\r\nH9wzXzQh+KhKu6HlnjfYZdnDlvwPHtUaq6jTTx1nLYpBX3SQNCar97ogI8MO\r\nNcwOR4V53rOW84HDCLRbXUhmjrvj2cFqJTIDhJQ6SFw3T+U+COX7e79hdGxb\r\npRhvLWPAKk0kRSOCSHNdzO40GuDMrup9MoTtei4ntYM3oB5RsjJdNIeLGYWX\r\nAbcsshH8HMqpqHGWEdHVHZVYCarBW6pOPEYKqzJx8ZC5h1GN9/viaTihUE4B\r\ngl/nZkzZdJf/mAsTU1I32uvJHW02vbsiWsJpjRHi5KzdNxFpKmuzU9ixoFap\r\n5bUsP8lQPRDlnjYFvtU8L4iRS8VrEf+RJc+FxcP/TbkaxmVut50y9Cpb7GMq\r\ne/RqfGy1gCtR7pS1XMTLkRPKBaz4jqqHHSAzRKOui6kHTqtYLyjK9VBevkMW\r\n19z2EwyReksqrbDhtIP4ljmVSn9mps+7klz8/jtjZ3nkd8NKhWg/ZFz/Se/9\r\nOr6iN2rxS3wv8AarpE/H1lGNr+BHhOKSXOs=\r\n=0nVu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"25b11de63d51aa4ca7fda0f3eae67999e3418ca5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5_1664384035826_0.677013909680982","host":"s3://npm-registry-packages"}},"0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940":{"name":"storage-mixin","version":"0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"d235fb2a9007da5b23392aafc9078838372d0eb5","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940.tgz","fileCount":23,"integrity":"sha512-0hCdXOO1MNDKvWGarjryIOHcjUUl/ySP4edxxqvH2W3iZE9NzrgJIfmu6VOerMc8rG5zuY5IgLZqPtxDGxO4RA==","signatures":[{"sig":"MEYCIQDkZQiNaqxINalXRnJbPzl71Yg7TjFc+XvVSj1PME5n+QIhAKsg4C8MmKDROCo5jnVQrrS+kkcgRiLXsHsjsjcU3YZf","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjNMUjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpeig/7BWLh0IvQuw+TPh6s8aLe5b9WeV4dQqyeYP/HJYNgAcSuztlR\r\ncGlE4176oAQnMFL+ltq5xlUQmDcXm/amR39s/I+xmBa63TSOyHw04Ci50kB0\r\ntrNTBNzhXwvOJ6SwsihA8891dg/4CyXQ68TBtPajcydP5MTUcU+NrpPrbn9j\r\nPaywX2hZhl8+Iy3h4Urkj9TdjFJNSfuoneWrpXbTZRj1rVbEnfc0lrMpMw5q\r\nFJ0kzp3LmZoVdEIrGSLrxe7NRX1QomNk60VnyM5rrgryBSx5njID3i5W847p\r\nbm36Tr/pTJ54rkR1Oxiix3nsjW9Nrpkhij/ZftJhDPzJ/v0X7yJ0eb6Qdg0e\r\nCfv/FoHk6Wh36cNXS49tRyr7Kg21EBgtwwY+BMhX4eLwBZmHijpzT4jN7+ch\r\npHE9LPzgiu+dxvprHLxuwyDxHI4HYLgJcl9+HCiV27Fx6sB4mxFHyYpFU/42\r\n9sGVqZFZfhKwf3bs60ZQ7yPiWg9ncsv8hdu69X9gzL1SNMZvsKrcnEhOSlwA\r\nIUmLlC1sVrmIVA8P4YiHMFuJ2h62o56usC+YgyLqXnRzBlNUpyLVuzsBj47O\r\nwEDXdBTGbWJmdY65k7yAbskH/nSdGeGSc5sgatzvDxug3PwWoBe86mqtJKaN\r\nJSPcC2a9lZ5G1hURWh59QtCtd4wZaP6UHHU=\r\n=PtqH\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"dfa464112f63969f158bde32322e393fa2b77940","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940_1664402723482_0.029206678579980938","host":"s3://npm-registry-packages"}},"0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e":{"name":"storage-mixin","version":"0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"1f8429ecefaa2009946274a3d5103aaa8d51ffc1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e.tgz","fileCount":23,"integrity":"sha512-mGBeRVN9NtVVpfPMcyQLwd4QZQQ0zT4BowZ1lvU4CFuVz+NdDJDJVB/dLzBiOpdbWdpMOh1C5wugIBRb+2zBLA==","signatures":[{"sig":"MEQCIAlrGOgbpvjxWqhMdWpaVvVNjZEdvFfwzTUUSQtojKCpAiBmQMPIsVg8V8c8aUVx8IAiaIiO1ktK40KPCOdfjAavNg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjNcLDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpXPA/9G7XmC6uGLrKL0qDwWk4n6Rw8REDqJuVr2o88lYGCyp0k3N+l\r\nk7abJGCFxEnmoAjWXaCvdcsCpRzan21wb9DGBFTcwPiP88CbLxkxlQQzPpub\r\nvSzer/fzwUB8x7x6+6c3zlotxBS4quGveM0mO/pbR9b4/erAfSWFJ+fzdhkg\r\ngIsoLtfUwAc6M1acyz1OkbkkWF8GCVzLOOFhxdHSo8BonzXP7QNR5uW11igt\r\nlvk4FEnIhWMHnv8oK01ICO3e3qZk+pP3zA+Id0+28wVbVkAeHDCHoTU3teLr\r\n2t/IAtEOYV30m4SBppX2SaKtejBfO+pvRyHr3P2fXMSmI70r7xEUcF92sI2O\r\n8CclWdWEaKhVJhAUCxYbMQ5F3CFqvkqUH3fj0xFvybQWS2JjgDXd9X3ngymU\r\nvyFocQIuaTLhdaX0RkayoBSk44GAzfbA4dmMNPSyBOUe8sTo9fFNrP4D7dLh\r\ngbvzr+xe2d+1IAFkzdBAN2j/0nY3BGOCr64watbacY8rlKJsX6S+A00NoNrL\r\na7Pkh7Yf8eswR92ZH+1RUlAXQXLLkSK8Q0is6CYdQZdQ97L3PNfIQoRCX2wa\r\n+D0yrlUaorhTni7I7YT58Rz9VcDtsaulhKIgHjeDO4/JB15rkAV6GRCBpmHZ\r\nmn1QKOi0o4/JmCy5/PRchBDoHkvZPZw5zxI=\r\n=s3Sb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e_1664467651182_0.07200224336781136","host":"s3://npm-registry-packages"}},"0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1":{"name":"storage-mixin","version":"0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"85a9e6e273eb1bd7e99c1a997cb901c499eef966","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1.tgz","fileCount":23,"integrity":"sha512-lsuBUitX8dN+Kldo9QheZhQXGDQfVcQAiZAVyNpHAwLgOGjFyllSoo0rw53x+TOvaV/aid6TDFB33+G3Qt6G/w==","signatures":[{"sig":"MEUCIQCP5VJDDrMWXP/B0l9x1+pZ6YLXR02YxXvjhmA3kZ+TjQIgUzBgIycgK5+qwxfuZDapvhl39AtmnTaHMpGczhWQlF0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPWY3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr5mBAAkXw0qwYMaB3LjmWofTJKBCve5pbWFeqRAfrn/oKmtx1uCqJR\r\n10qxAI43Ce5kN7FwHILglIeHAqO4VXMuJyS7v9+CRSEzi3gUaHIE54bx9G/W\r\nwzbtsJtVqfHkaEJ7EK1fbVyItHtEw/YpLN5esCkNx4zqS3BCGu8JBKrXQnZe\r\n5avRt9nuBNfBn3T8mJwfiSlF7OPtZbFRIEJLGizwxRfHhkyDVB1dA97Y1uMi\r\n8uqmJkZADK2LrqgZVVtMWeBA5JY2Fx3xQDaXPaQ90IO5co9EALftW2Q8CCZG\r\nR8HhGGGiHS3q/R5yc+Zhy1l5M84SPnHMNgVGD1iI69R3Sa8OD/IlJh9s+TTy\r\n3VTcfc54gDIK+x3vfCCKz83qEG1wt5QZHahjdIe6uJcW5x4Bn2sxUWymQeiY\r\nJTPTuemgkt6rfTLVJjaIgdKhyYwfN1PgUuDNe5rWtdyqxTINOzzt1v8cisL3\r\nMRK4cf/r8l9wmUNvmoPzLmhBM3z3qV7PNgz4GbIHjeoGyCMtwvXJ6LtKgq4S\r\niHcT2hIO99FE2dfvjh1OWvTIEoNzsCfP5FgQyBa/IC61AIpAnJL9UZjkczLI\r\n8v9bx2iU76HDm62LXzmiobElMqiOs0NYfFK7Njew14cIMKiEjOrYfZOcEKD9\r\nSCGbx9aKmSBdp6EPl3+xBxrGKLitYl7AIVU=\r\n=kE5F\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5f69e8129e0242b4e507fee055188a8a83e1f1c1","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1_1664968247771_0.8189522384436143","host":"s3://npm-registry-packages"}},"0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f":{"name":"storage-mixin","version":"0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"f2449da002cbb4cc5531610842af669f243aa622","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f.tgz","fileCount":23,"integrity":"sha512-jVQm5rPkli+ecGemONGjM6YssQpGpyS4kdjrbrEzKnfmZkZgYBNe/rMYY22h+OzMNp+3nTSVv1XFfXMajQUJvg==","signatures":[{"sig":"MEUCIQDIIz0Q9gl04OOUMqyqE+D3PAlsSmmMRbGOfr9qAlf03AIgKaFSSbknoMvAfUAoLbDUtspBNGkuU4FUp4K9geE/wj8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPa1/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqjcA/+My3xD75EHhMmwIIJb9yXybfFWkWTrgfV74Vk3Kvh8wtpQ3hl\r\n8BkMyZNrxWRYLLoAPGo8TYVXASTPQ/J2VUDIK7tCDEIQfGQAGo1AnO0XhoYY\r\n0NWcbLn+oJdhhvgKccuBZ28LRqQXWg+PDSvg3Uzg1WNBETMzoNoW3cbadi9J\r\nZ2o3kC7VLLcFlLuZ+rxf6jPUL+ZwwsvymRIYULNHTcDnG93HFrUz90gay9yk\r\nbPkP6srmI/dfEfOaU4BCHOKhGRi1ksCutTsY47xjDz148nieyt2Fwh9mFLZL\r\nu1HEFNs+5ssFalJtyI/mQRC7WUH/dTZQDb+F/9smQ1L6SJvRjWWJDbzH2R/X\r\nOZsHjEdq9/TnKuFzgDfq2u0AYQvozlpJRVqwJ3/YfyJ54PEtUtm4NpZWZ+wC\r\n84D/1GfINaaYJj1C3+Ed0276EBPfHlT2ZhbbL/dUX3OsPvjyaxonV8+aUhSZ\r\nW0g7WddsY0mMPxZgx7Su2fOvQGWTcm9JYNIm9oWB7kdD2Yk9Br6l7eOQOC6+\r\njFdcdxPGMDVubSBaVWPttsq3I0BR+IqMWS4gTdG+RJMRH8r5q/6cEBQe84t+\r\n++hvXFw1V4paSqsAyKMZbNqumbpWdcHk3Yeml0JulPepAHTfz/sLQjwVX0p4\r\nZDN97horXg5kRIaMpo2n7nWL+Krcq5KtZAE=\r\n=Guyv\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"823f55a862f13d28437b87fb594450b2208c0d4f","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f_1664986495348_0.6511982973163861","host":"s3://npm-registry-packages"}},"0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47":{"name":"storage-mixin","version":"0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"28c0d7456a9fd000c889ae26349ff75fcf4834bf","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47.tgz","fileCount":23,"integrity":"sha512-U6JrzQKmg3AxqOlDe4oxUb8QcOKqdEwBWQ62e0/3n2VMsAv5kHneKGn6WokY5DuPpl9mqUoBN3dKD/nwTyKKSw==","signatures":[{"sig":"MEQCIGG9i51/niPkHck6UZJSmYynXcWPuLC01HaCIHqX7JB8AiB7txv6T5t5KIV0l8m+3NyDKurzGoR/Cdgykx/8o2g5OA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPqQHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpoag/9GP47ZkG9AU+MAfkyMIf1XZmu9ouVIsme6NfU7k+C/vzW0vel\r\nKWSFfJrpy8oAQtjeffyFvjleK0p5SdyRRF+B15YhJH8pnBKxcgU0v2aG3X37\r\nsogv4e6dC/lKZZZpTeTVPglYvDDgPbI5Q3wUIegFKy3ORx4zteTvanl3YfOb\r\n8oyz673cO/tvTPR3SKJZsuAwOm92srsf5cMK+Vm/qpokQYv5ZZx4+BfogNuP\r\ndkNQdIxffE1S+rffeqK4beTtReu5NNsNXuimLhWLQ/rC03vGH6CD8HSefYUs\r\ngKVftEYlr9/tTaEzs3UKMbg8UQuWnTqdXnozlBHiIbRnSeCZ1fg7qfopOJvM\r\n4R63PIWrJfLdo2alCwdR9yyhToIfrELXoRyCc5ombUkTn5efrTw+YtXFeihs\r\nI2VTbFkO0YU0j5nYPu3BVa5kfp/+8BSz1mB5e3LhMVvKCKM2EF0Zi0xLw+88\r\nF/tNCiz4faFD86AfTGWusnt/O1adBKvHt2JNRFMfdCbNuDsMC+D7Z7Uhlds6\r\nEcmhIsUBG6vRFJmHEz0hnTTxyNFg+FyE2fGxunJnbYa1sXjku6TGSY+5vLJR\r\nZ8FoLa8HppL8IG8qeeSMwDMP6IAgHtfS50V6iviqb4CCoFnwvYKYHhEipkRL\r\nbTVuKzqvRSJlyCYYPLx3yIRHPRjN5LiAN6w=\r\n=R8qt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"01a3ac56d52443bc859ccdcf7ed301ffbdea7a47","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47_1665049606968_0.46463407239197596","host":"s3://npm-registry-packages"}},"0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9":{"name":"storage-mixin","version":"0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"a43210d1c974487f511e750168aaf0b752f79e0b","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9.tgz","fileCount":23,"integrity":"sha512-F6rNl7djMj/m9vhq3b65Ru+tTha7eVUTvXn7cjLoVrlPMB0EM9ezDg3hE3JZQiQD/9KBYy6nsnf6ykqFEw8Rkw==","signatures":[{"sig":"MEUCIQCc3LB6O5He0YK0vulH1saC2MLsDLwAzqxiQ+YdEzzg9wIge2qtMgM6D2uXaZLS0FcKlyTj/DxS/wIzV/x3K4GfTzk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPumyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpj1A//cqk8/kQXLLi5ajwhGGi/kYtCg/v8CISdeA8gNq55Knc4PbDy\r\nYHUlC655PVc9wHgp1jOOnhmelj8kSQYNTEucetc6EDZa3edYw7kzgZA60YCE\r\nvohzVGzQCO5BXL++ZE0c05Rmy1lAHtnPx3iZ9tFTruRYURAvnrVHpCbVRBKi\r\nvPDX8FxPUthdn01r/2Y1UBoL6sAM79RmdYDCqW9rFYqaWooXLoyUTB3WbNBz\r\nlPEqIL+ouhv0PbT96jvL1Gt/mWMB1g7dOzX6pGM19rLz5s3qemWB/5JpjLYM\r\noqIpgguO/CxaSBYPXCS0CwgExJpOKOtEZvXMUfVOQSncl1f6R5g6P35vJ65K\r\nJs2c74UZ9uV/hQcTeL9ebDL+oLyMFn5AosxNgABWr7kwYfow0AT5vYRn/Ie7\r\ne3kRBmtKpb/DCsx5l1r19l4VOQI6wVQA3fpGr4DVzxEvZXkDxSSbe1c1s+m7\r\no39LsEVCXA3WQI8ZuWGMT+b8tAtuZEzjc7QPJL2hRMNqQ5nQ07vT0KhG8WEK\r\nB1vpE+u5zotnL+i1da9jPkix6ju4ZtPyG1z6sDuzdA8i4+gRtyPJaltIjOIU\r\nYecEMnD6RPjId0QSqJAr64duc6BjgfKmNef4IBl+mokgjZMNlOqKUbh4DqJ5\r\nKLfVYLt+xZ9Puu2Tb+RF5Iy89+M5eX0lwiQ=\r\n=2JKN\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"cd3c5c1303c464ef7900dc08adb8154d15c7f3a9","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9_1665067441841_0.7950105199033617","host":"s3://npm-registry-packages"}},"0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c":{"name":"storage-mixin","version":"0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"0a1f3a645f2cd12352f57bd5237d6aac9c58f27d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c.tgz","fileCount":23,"integrity":"sha512-I7ri38LE9Tvdr9wnSmDAQOsZpVTZROMiymUoFy+zLJVlBV/gtMSbaeapwzJqaISoGFsfBj9P2A/MCNLFp99UNA==","signatures":[{"sig":"MEUCIC1Ejx/im5I/wg5BA9yNFvwgf8rApSpAGEEJqEIET3XHAiEAy/BUJIGsRBOu5GlptgDoUxxsJHaifgRxxGH4H153Ims=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjQIGkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqN8w/9GFcr4ayOylLN9FAgUTRs7rHLCiZYm2HhPrD5ac6zGcclh8qx\r\n5ZoWuq1GzlXRgfnbu6YtKbFyYmizqgkKNQWpoe5MUIjceiiDenwxt7CZ5p5g\r\ni+9I+hHb20mCPf7UD06CLc2hIRzus1BM9As9OOYIrf+lujVdLlNyiWdVQvhG\r\nK73jxi4JOqOQUXaA/ZU4Iz8TplWALQocx+5kkJT/w+2tOftCIyG7dKVQcxyi\r\nircOBWkjdUHDEvfFS3mT2cSzO/nhzbBjYm6EYCg5LQARtQP1O6oDYNi8sBpn\r\nZ4AiE2BcuW1rdpZvY9pVUBvu1KrnTIvw5nFyT3yq5q969ZTkyPASuafDVOuv\r\nvLtIqsd0Si8j17Qj9NXyKB6Tzo2C++wBsFLGrKlTJkrwVtAwuVttW7/bW+JG\r\now8I5WQUlV0G5H6WfaqR8kUJc14q8hWuQ9un5sFopxyD4NnS1e4tm5hNs7nY\r\nR1sVgtGFrfz4XyV/5zjID2wy4xIndtokiayt5E4B+OOXoKv2Pyu7c1CWGj5O\r\n39MnY/JWQ+MZZ6MaPOgIlSMoD89Epg6E35lfTbfjxPax4OPmI44jEh5MfmnR\r\n5xnciGQmBpPbc60e5PWkdT2BzX3s98kuhC6XR9bQR6LbvNdzNlXI+WDmqh8t\r\nwfhyP7Ap63YkhVyKDajtu4Y7ICTXI0lQI3g=\r\n=bJma\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"d9691f3c8230e21aeb2817ac2c984aba0d79f09c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c_1665171875602_0.7862007710971786","host":"s3://npm-registry-packages"}},"0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10":{"name":"storage-mixin","version":"0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"0900eb1776bf284e62073a57be533ca8d63e1dca","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10.tgz","fileCount":23,"integrity":"sha512-oOcI64HdxtAHIK29woiudosSM72wmK/kuHIPqJ6+NJ93JHLvsDsomN3gPQZqLxYOdriOesy7SgItbNHb+arnEg==","signatures":[{"sig":"MEYCIQDrpnDs2wvMZZk5bXPVlz7116iZzx0QtW1Afpf4FBWHNQIhAIkap+sKkKDJL1wX1Xfo8Q++FvrFQ9ltSRhEIBzVr99z","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjQILGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoXhw/9F0Mtdta0RG0fnQMaZf4x0KxPHXRRrCaEurDDpd3cNDGEL+v/\r\nYqG7vGTR0qhZgcKORIoygR2oAamLC8DpsKHrEAWDTtvdomCPGBa9rxiW1g17\r\nn5U+SyGn/ag26iV90eFsDFhdbW2yoX0LCEg6cJs16hwyDCjprU8YNg2nftTU\r\nYX5MoupvKgKfF9NVn0ZteEWZOb5BAmkkbJY8XenJ2t/xfJex6hIK5fjmQlfA\r\n9CCJuh3BplHDFNok3YAmfkzP9hBZZE9Sl43LJ6yKagcPeudgb2oorypqeQkd\r\niK4kXH+EwLR089a2ZeDbWtp8pwYH3qW14FegvS3HtzQilS2ObfjTK52dGiBO\r\n3afxBMTeqD4ZAejUToW1II86BS+AgZBhfw2yKVDmptt/2yrxwbcO23FPHgvw\r\nrWtkpoh2fCwL5cFY8iReza8yUOaf6Rbtg9JlNJMqwbCFnTFVy/irnbrW8r2d\r\n/2CJCGWzET1Gv7EV4w4jytaBRU2ZtsDewQ2zbFiac4smLNL79FcLEYKKrEq4\r\nJMTMp8l4AyrdzLqOYQrCfZurHxN5Qd8zccaMHukv+NzVnOzOCdGnwnqt8jKj\r\ntWSGUPT/GLqlNjwMqx52cIva5PxAtfwp5z/Q4+cYxJSW1znRu6nEXtsUmBge\r\ngOe/zfZkpB6CFuGhWww5V/cshJXvkNqA5nU=\r\n=e94E\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1cb9ea1724d90e58422b33fe089df5b774e0be10","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10_1665172166184_0.8622974521408384","host":"s3://npm-registry-packages"}},"0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246":{"name":"storage-mixin","version":"0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"bf67e012802231bf7a1b793ac3504509d5cc7850","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246.tgz","fileCount":23,"integrity":"sha512-nsbEXgkOC2D6OZZ4mlyGJ+1KcB2DWW1Meg0t086zx3PxlfifpRm1+uggNc5S7VYqBeTHKPVx8ZL2vSuTIXNumQ==","signatures":[{"sig":"MEUCIQDIvPoAFOb1ZOQVtrfftSJ3dTNU9OVsBDcyRN7OG/qSegIgU2yACYAqgx77IHdTvWFGIv4GG1ttKl6jNrPUOzHJiQM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjQIVNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqw4A//VhDzWBK+JkBqd8GbY1KQg05pYZZGNceg3zbmVLgkZoBcJo+M\r\n3O0xb6Oh7mBQRfqLFnL6MCHc1+R6XTudbDYeJo/r3rKdx5+0SoCh9i7mniW/\r\ncalvS7ilgxrXuMgOMy9BimraFmEd5Z6v6Px2cnVezAUg99xFl9Rd7kVx4C5V\r\npaYhbxVxQPhYSidhR/6bJcXhcEstYuTAsC+8vAVverh/qm0hFnt59Vil2B1E\r\nA8fVin63p+ubufJrn+HlUH7S+qUvzil82kAdgTbQMmVg9Oz1rIrkFYhKGhtg\r\nZgaixvUA3DbXQc883p4gJrZFQciyqUgf93Q5XHBo+mh4JHy0Hgfjw6/z5uZu\r\nw2c8Ud7p0FE6YuuSztVbkboiyQu/xQtUp7ExmI+4QBZsD3IxH44PD5D8ZR7Y\r\ne78lAL1PHf2ZUZSY6fnFUPCqgbUQsrgAzxJiDXTHrWs1GjydYYpYVISTZ4Ws\r\nwcEVKgs2Abi3Vxku+R511Dak5J9WQD9TLgYCrOQvr9N65cSQn4Ft14N2X/qQ\r\nsE0/PeKN/pIEw0FmXNjKGnniHe0l5rYpS4bqayVnuvD/20yduo3mkcrChglQ\r\nMySJgO8g9Ra8Sod+5pplFRhXPeiNPVSx5qfCv4zd6fcKoEiiVUm41g9Re+6X\r\nsnmkOs3LrD4yzVPhQSD1S7mmZtQDJuY9M6A=\r\n=N87E\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"4216a27cdf41425fff35938bb42040bb93c2d246","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246_1665172812768_0.285581863323356","host":"s3://npm-registry-packages"}},"0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55":{"name":"storage-mixin","version":"0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"b0f07a22d48abfc41208296d0f561266fb783f22","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55.tgz","fileCount":23,"integrity":"sha512-vimSKArTa4T9gWZAgoDVO0XBQn9tysnDZfwYRD9OFNPWbfdm2lexSUGTtTcFXHJFZG4jiXEm+vllHVRAhkvUqw==","signatures":[{"sig":"MEUCIQC0TR0SdDKhfkvhjOvyL2I2MkiUbc/gcCwrRanFqd8JoQIgCBUfHTs2H6Dmb8Cd32wystTuQqzfisGdEhOkRL/znY0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjYVkUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrvhRAAl/ey2atbA2hVUjcW5rHXJHNOje4X0fYWt+ZCiy4y5o5s2rvY\r\nKiheFDa2glQrbsl5Hu4lsnRWQnr8T7W113loEdYDSr3bTG6K06un9UXRMgNW\r\nZt2jvpqgpLTN3+xdhxg5iYca0ZCdNkwP+s7DNhZiY4jexDF/Z7OSIGlQXPDG\r\nUL85EZbaGHYOkQHXBVTL9RaqbEXPhp9jn5GKNfTuaEH1Cjd7qW4sioTUsik6\r\nhpViOwj44q7QdGJMFObqVH5yVKrZ8+NPJPK43Qqga/UFMNcIYd1bI6iZXWWr\r\nZ0T5ieYiyNOcrksAl8thmaNrPoGfmSjgIgwjfIjefesTmJ9Cechd5tr2YG2W\r\nVIlHsbKR8VATsfYpJd+AJ8t3z7OYZXkvY+2fyFqLJUaMP/hLQ/wssJn+wZ0M\r\nvboSqnkYRM242ZPGPQSBTNathvV9RoS2g+65wxNSI4rqqzqG3y1QIrRpp9Mx\r\niWagbS/KRu6SbnUSEtfhDXZwfdeiVIwPLWI5jIU5ZyekW1sunjFrASxEknwL\r\nKg6JsN9GZ7ZbIDN4aS+ZjunYfw/fyPxWAbuzdOcb4gN4ET+4gWyRTSgFfwVy\r\nbQVF9M2Po5E/z+uts6l364XKDr9CfChBpZXMKA+9OtUv1hwX341y+ar9GrXo\r\nebqyfBfK5thcQ5EzF+j12Ku1NxnmOASRMHQ=\r\n=ELeq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e3d7e58db726184c34e0d2d9f3342595a865eb55","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55_1667324180112_0.1620263023923436","host":"s3://npm-registry-packages"}},"0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3":{"name":"storage-mixin","version":"0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"a23737861b880466e738d4bc2b727cb62d807b08","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3.tgz","fileCount":23,"integrity":"sha512-juKEAdUemOi57/tpvWaLHLPl7u3ImCXc8tZQ19rnd43HVej01KZ962FOv5AoLdOUwY3o87zCZykosSER1Wem0w==","signatures":[{"sig":"MEUCIGGgwhHAeTs6BJuOA58bvz3fmIR9YTeI/a+eco0QudImAiEAkHVtJlT12EjyuB7qVC++YsKZnykgI+X1jqBC82xkV7E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjYjQqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr7/w//b3UN0DBVdSsara9O4Lzw0DDjyLoA57fFPLnfTUWmDxAn8v42\r\nFfjgjSL/1Z6VsZuNcSqrbgQiD8IvJkThqocsiIcIo8jhyuYHJQcplIh6vcIW\r\n/PkCJrfgJ1Pf5ZG7u6tGBlW4NMSAwht4lQV2CoLSCQ8VNIvqNBwDlw5//ODj\r\nSZc/1HM6kC1vtVybv9cdij+EkXVPGZZzPnPYOZDDO4jDo5KeFCf5inDaxTW8\r\nlhSBYXE9JFWbqId+Y014NnJMUvDAxwMtRqtZg+qyPZ19Q8Aim4q1nkkpdF5w\r\nRq2wkA3fFgKUQNr+rgmMHDREqX9VkcISaGJGJ2KXVGUGfA4yus5bAQRNnacp\r\nkDIY3ZqqiesRW6S9Ed7dwAaXIogyuxdEtkXDvLIijDIFT9L78fbtwGDXO5GY\r\nPto3RXbkm47o4ThvQsf2UADSWAxFkGMOvCS2UKUNxuaKprwYM3XHQ5zgh9lF\r\n/ufaWjlZRmsH7WeqiftmJlf8r5U4e+lwcjsitMQflX3ixMdL+giFF0u/xu2t\r\naK9aboC/cUm3WuKX6ays0UfGQQLbOttuWnFqKFSI3CxtqEB4blsMuX9/OFBA\r\ny6tU91pVGGLbfB7CJpr2spqlxT+iTtujxlEb/oL9aiPv5u1tJ9X7hUs4sCzz\r\nTgYyHwMyb2LWMdb+qJ465v94gioEyUjNvYY=\r\n=EaSU\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"dd9be0f790095ebc62a3de5b5f33543ff3c55cf3","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3_1667380266313_0.3384348917250737","host":"s3://npm-registry-packages"}},"0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb":{"name":"storage-mixin","version":"0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"46e415b590defd9606196973cee3f663a7597a30","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb.tgz","fileCount":23,"integrity":"sha512-GdzAB79wRBUfi1YoqAYnLxQqnw1XGzbAOGVEGr4l7g0wUQOnpwmN+gLpPLukBhRoDMb0ArjHlrNJYuQVm+bahg==","signatures":[{"sig":"MEUCIC2pz23bJTBj+BG+HQYuuZUheauCQrpFOVGkE+ySGtkZAiEA5hgIn91m3MX9uM8A/dAOXR9SVsWIceFz1wE/fFCIqbI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjYlTmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp2Ew/+INiPx8qwYLkbJCbyk4eivhhW/FNKrKWG2emDfXPOqVSa0y9w\r\nu//H2AEtu7I6LS1vvHNKDgF5Ekr9dbU8tR3uvbTIS67NFVqTqhDhH3RsLvOg\r\nmJ2MzRrr4AY3bpDoikfiKrmGrZNGeunSs4Gm1t6ZGS3HnXi2//lYffi/4HTL\r\n2PQ1E3iETGFT1mEldnyzNP0H5knlwlntFfy19PfCkCbc7OtgWDFzaSxz14aS\r\n9UFjjUpQD+9R9NuWmQDtW/y3b72wQ5iOdwQrSLlPNsFuonlGfuSeR+L864km\r\nWxV+27tvd+JpZWmNjTb9FLaAKWYdpVB4Md4N2jyAogpZ7N61MA8AReeB9aUj\r\nBeFPo7GMHOBFr4OB9FN9PWY/P8iZDBgfsqMtgeDtym/6d4EW5ZTY/Yz/Wlni\r\nxybA47KzVSujyqyp6iUp+FT/K03PqGJTzYSw3sgPkDR5O2gIeJzXuoulXakC\r\ndBi/0tciXcROfMG6ynUfasjA/khbiRMIM+ULIGjnc1PlqPLe8tl3MM5B14TF\r\nsJpy9QAjligLiSo91OEdBVTyvbVwbBRemA6NQSpW/utOo2uaI01gDe79qq5k\r\nqkccmSTAPzx7RRaQW41LieFbg17P6fEEqH0Gl7gJZP045RgK8Delh8MZ8r6Z\r\n9OqpbOKulpAh6oTmd4a9UACYqJmrfcE8if4=\r\n=2OL1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"10815be8fd57f3bfd89d061e1592eb7136d4a0fb","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb_1667388646033_0.6827802509892069","host":"s3://npm-registry-packages"}},"0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d":{"name":"storage-mixin","version":"0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7b031626ef6ab4f8668f80f262289f296d805c53","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d.tgz","fileCount":23,"integrity":"sha512-IIMl55ZaA4WE/LJ9HPzVT6K7642aJNWAE9Dr9nUSLdA4joMzZ5pCJZbgTcYhiwsLpcTi2hMHiE1PY8ucbaltrQ==","signatures":[{"sig":"MEUCIAYBLF+C+1YxJJgjdNg5VehvOOaqxt16gd85FiHKsu1oAiEAh3o+RHGcFm6qv++O633/IIAkW74DFRYXDvuykAwQ0wM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjZIKNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmouCxAAkzx7W+mc8weKglSedq4RBSx4Ka97ItAoV6ukvOIoOUwWk3LI\r\nmUpLVWHiNRIDlocVPz5LyghkSa9OVXFCuQStBcocOAp1gFAPaoPn76x0uRNP\r\nUz1GJEsvK2CEPS6v8qJX5+jR5IWqZre72AQQN+/05f3r6/kpwH4VEagu2cvU\r\n8LpcliQOmAPSBBMLPrMLHCgSOcg7Q8+k95QHrSUc271L/KdQN1r5s4ciHrjM\r\nC73kYKAEIcvwxPuJHNEP7FgSFziWZny5zXhW/bu0AKhSAjLwEhMDEaJEt7k2\r\nFgEZxn1wElylB39wxsf2hqOZ+e/LessbC5ACtNovsDSBXlwjgQtF3zGcccD6\r\nNZjb/5L7tinCrCykS9j3RVjnGdmVzVuIJcRl6oLruiHRS+vBbL7GPUhYkTZf\r\nez6zQ1cjXm5pL8FJjTa5VDcedA6VGXNucsH1UNixOWpzk24bzk8TnXmRKCs/\r\naSfn+Svrucu4OFMEV55xrzrcc/qs0NnF9gprNRvYaXfYHD+WbpxAFxlPYeAc\r\nN9x5GAMktJfQt5UuFHmA0P2eAz8zqjBPUiun7OPSlCJpyZNugTFOubhwTwiF\r\nuBKaev9v77iU88GtPEbXm2CQa3zQPMRPfMis091BI0gn2RowNUvnJQ32fkBx\r\nh7ZsyVRgS65nEC0kXQEotbr6b/gsZFfFGZU=\r\n=lGec\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"59e1f6f134da2a3417bd69a71c7788320608ee5d","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d_1667531405131_0.8776840129216377","host":"s3://npm-registry-packages"}},"0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba":{"name":"storage-mixin","version":"0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"259671223250bcbf84b19d3321dc3c90fa3e34c0","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba.tgz","fileCount":23,"integrity":"sha512-H2GkoCDU+buU6/+WHFXMGK5bbHdcPPyVOx60X4VSO6m19Xb7gUeygcYIr6tkSBqOmmNMm6N9ant9OXLh5+Ctfg==","signatures":[{"sig":"MEUCIGqwu/sgjF6i3asvcwCGMlL0TM/e0NK2zWFpHWrWLikBAiEAhglSo9jPMyl07b67+Iq0GW8hQk4OtjSAjkk/SLiL/K4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjZIR0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr5dQ/+JGkFRjn2T6wVI2M3BVvj4ghQU4EXgXwfJSdOGdN3iWNxitF2\r\n21nCCScicD8bhvMN32ET+C1C4WBTMuKRjF2YIokiwj/lo3/+LXGhVvsKTlF5\r\n2f4wsOOhkc2Ue5shTiDdm7vYFT9YAvLgYz4emNSaWVGk29ATN73AlKK/ZW7e\r\nCcRJVE3cack/nT/MJQc9tVcAtfAJ2nnCZEnsCLp2RCr1nXyw+Zlrmgv3Dj/Y\r\nAmnzKgSw+YB6cWCY3+gd7w2rOnpI8tDODdDFG+orcbtPiGEeeIVXp9KKa56p\r\nfp/cvti0bs51JDWnYpeE34JvZpJmkqAH69IaeO/v+3+TibEQ0O0ngDzUCTBi\r\nY0Ab80D5YQUmW0JKIyDDQipPwl40nzOAiD1aBsWoYjvN6z2nbZsUlVxql8FF\r\nzhvGMLYQ3nepZCb6mQaSVI+N3LwDbJ6MULIKFaM0pUHb5+oyW/dt2fTsSBcO\r\ne7faKPMENwf+VTNqEYurtguWFuyeSdt0eRmhP7Gcwl2TLnB4ReiDUsIJwYP4\r\n2qxKg2c/2PiKP4yppGqRMQa1i6Hw8V9/DIWI1+Z8TA0WniidSnY5IlYOmzOZ\r\nCzhymMUmYg4aF6UPrWyDpdiJNS6ewpQRRfM+DZ9qGwnywjDe21HvZJvBPR7o\r\ne1/myxQpjpQ8lIgRfbj5l17K88c5g/AzCiI=\r\n=I7pM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"ea4f317e964c0504e54c01d83c385280a9135bba","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba_1667531892304_0.11813357618459142","host":"s3://npm-registry-packages"}},"0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04":{"name":"storage-mixin","version":"0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"470889b92a766075f8bb63b7bcc166a9c456fbdb","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04.tgz","fileCount":23,"integrity":"sha512-VRnhiMYMSpgP3t3JId6AhEaOk+dhwlJaUMVQVRjy3rlvQwWuvxdaaJ6+hJzdqeRWq46OaBx42jVDC0kexySxoA==","signatures":[{"sig":"MEQCIHMz7l7gn6qCDc6uK5h2+VBZzTIwJqZMd1weySFzQii+AiA9HfvRzCmMQNWqZ5SXPIUjUj7R5AdRuRCXI2qO5dgLQw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjasm1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo0LA/9Ei3GVnoWVOQHiAvGZV1B6MwiAn5nkYeikFiN+9h8NLMWaIlv\r\nCenQc5bWJOwvPZbaenKY2yRA8s3fx2bfDnRqoDMYmLVEoxc7p+KzVyVGix2I\r\nVLYRgKfdxtwsBrVH7xcI6paNOdcqyCQDAL2r+Ma5KVh0gYCG5o/piFXyeXEa\r\nV7Mlg2y8iWMJKqOlOBY/8CtXoQxNPLaGee9Fe2URZ5z0rgRz0POsGZD08dKB\r\n/wUv7MQskE9iYWSN1roIV+IcaAk58SdicOROERn77vapNTDwYq9vXEjHUDI0\r\nGxFT2ui76t/g06mu/VLsvxiW/g2EpOXsqC/fs8WlK0Gc+4zMGkXKTYTSQ0EV\r\nqPUXfLe8OE0t4A4HdxKz1HCl+wsVNa0OGLOk/xqmAs2jISs6KSf2QbyM0+UO\r\nNscHit3xf0CAxikDCUwvaS0pxMBftL2Wfd/KbmSMArSpkIHRGHwg8nQWjcvZ\r\noVEW4bC3SbVgIH23NTUnuBD4ajTFYCl4ZwJ8htqtXAM2faKTWXwKCabrw+5V\r\nP0UEy4wjo0EZfVpTzI8DLj7xJBTI/5fARk45SKNRRCuqo5j3Fzw9e/ZBZqPe\r\nsDuPxPbCbJ1qmsQT0ZcAplAeFlWNgeEDTXycFSe3ygJQSeDDPvcKaSQMhzoT\r\ntkP7W8w6LgRfPqokKTnIBjtftNW2kwfDPV4=\r\n=T0bp\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"bfa0f33f79b0349abe5ad03576e17682f507fe04","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04_1667942837399_0.9553197779616904","host":"s3://npm-registry-packages"}},"0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21":{"name":"storage-mixin","version":"0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7214af30f0d906ce88def987b1d72e648188f70b","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21.tgz","fileCount":23,"integrity":"sha512-1Qi9vLmISkKfp2aYAZwXmS7PQxatTJgpErBvM+MaLJNOULK5TXc/qLmziuhvL7Cs6rQKqT23J0wGA6L2UwpXuQ==","signatures":[{"sig":"MEYCIQCGxJ0FXK0evzy1oyGUe723xLswPikeKoDOrnKxIHE3+gIhAO5u18QlCFW51JUTmixlcQt7JvfdngdV1t7nQHnJ3tG7","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbDtaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoYKw/9GPUee9TUVGO5/72YsYQfAyA2pY1f9Tb/YqsGcajTyCMO1OKB\r\njzDBS3S15TFolT0kRr/OWeRfMxsG5NIzxNiYbDkLqRuvDnVmQEg1RPGXJcrZ\r\n/hztUpqLLsY0yplD1lI+91L7PDM+HZcBNmhkIrZfsEII5eIuYgD+vXPy/gv+\r\nIlozcliy1hJ3LGyvANGdDUSkgx19KW6NGu/Zcl33veNt64pF0Am/mxbFcX3j\r\nHK1iiiMzQ8ngbbShGJyWBRZIDHL135Kv5upK2SB8lRRltwpKDdRvx0BsK+5u\r\nooLG2hJhpU79csiKvR9KDQEvyGQik2mhiWHilB9FwZZ44d/9ZtSwIzUJhwvw\r\n7tdjaJuCoaUlyyZhL9qDm0Q2qO9v6ew79eFeF89qGRG4k6RZzeIobah8rrvF\r\nZw18ayrlDLUTRKZxBSbjx613BAubd4q8+DU/56T9NZNJ3OCp2E0v/O8sNSvv\r\nJy2Whi4rN2QgAI3wcvVFSZquwjvyn6q6bbETIZIPKqV5TcQOguYBtrdpoJcI\r\nKHVd9KMgMCZcbr69W5Lqk01k+3kuk3oOcIXNbNk3SRHDYDasAk/N9UYDM5GV\r\nfgqKevrhA541dkXzRpebnIaEbzKAGs1nVgdcJHXcHLA5PvF7x27+Nl/GKzJG\r\nG72MToXWIpr+OygDj5vfUB/zN1DfGQe0ES0=\r\n=gTdC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5f5cecf01c890c348e17907482b03cea2f8c5f21","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21_1668037465805_0.8313294449497797","host":"s3://npm-registry-packages"}},"0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e":{"name":"storage-mixin","version":"0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5c959ca3123ef11d1006eaa7bfb1c5308e3c965f","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e.tgz","fileCount":23,"integrity":"sha512-tilxlloTJhRjwete2EltgntbU/LAzx13I6JvAhWtyVQetZXzO/DX69qsJSNmz+BMmgA5SdmPrxkIGk5hz+en9w==","signatures":[{"sig":"MEUCIQDPq4bHJ6r6Y7unUFKs7zBRD04mFDtSxhiNTdw+cMZNOQIgcGCbTbwwnCusAW68ldZWw6QGd5Pru2yZ9dMlXhyMvBQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbDyzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrHnA/8C6v+wiRuDZN2mjRbrrto6CicCXg3BBQkn/PjHi59KuRCBAz0\r\nkIsyyqYrGSbH7tredmVFljt+1AH8IpglsIVfUwYv8CRsF96Une5rqFRE+G3D\r\nn7r6NBnEuIh66M+8rhpgPgWclkw6cZYu3d5lwxswmSmJ9p9WOpoAxnpxUES7\r\nm0tpNIKwIUwoGWWMtW8rzNzi7oFC5UfoNflRdJplE/LF8V2AJTayZKD5XLde\r\n0DGrLKsnQhELHI8x9OcpJagCb051YAJ7HtzpCTwOup/hYT5CTpfx2Jv/IKpv\r\n0zrUQpBZMHG1q00KEzpOUmO14T2UXNxe2K9vhcsYTMwAETTUGMhKoE6Mgl+d\r\n2ocs4M/ZF4M9ERZCDrfSKlPUdER4xuSpLhNUOxfWeLZcKMKCg321RqPA7oOv\r\ngPGniMgG1lDGGz/LrhdIbfRLnE2AKWMz/ixvLREW9TlheLQUEjrDZLpw7H1s\r\n7/alrNZxX6cgZMz58Uj66DB/1NxPRJ7ivpXFk3ofU5n8OjH9et5DF4sxxEeb\r\n06JbaFjXOkrRTivwWwtMwUvO2agzOt/xaHCVfo+I++jv3bRi+9tIcWbilMxI\r\nsCvdpqfWpq19120XI78xDh88mKcOWPpt/jhX/eIO1iHi35JVxwopbwY4Qvak\r\nKyZhUAvWycr4d9gcBPwkbsJSh42oyGyInUY=\r\n=eKEA\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"51a8e00f16dc1652cb0f0674c540570614a8895e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e_1668037811145_0.6279343324395295","host":"s3://npm-registry-packages"}},"0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a":{"name":"storage-mixin","version":"0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"1ea851a8c65275d3fa38cc960c9f2217a6cef466","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a.tgz","fileCount":23,"integrity":"sha512-YfIFD4n3X6Lp9FopeFS8Re44V8VSjXQWLoReL9YEBJeIAzNidXQPxJi88sVQZYkVKOIDofoHpLuIApkemdd0FA==","signatures":[{"sig":"MEUCIQCZFF1QrDpE7rCwiFilAGpujndE/+ds9N4BKhXsLv6t7gIgciCb1UTH/UHOSCiaTC7Df+5YulOv28QFUIL3NWX4le0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbD2xACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqmvw//ckpTF88K+x79bgRiDkkxPWtbivRZVOyZvXxS5IIDaN4sMt4i\r\n9aEGIONthyu6M2QJKA8fnqvwT/o4wUejbCrq/r99PSFKnGFPqMK1Sqg3gGSh\r\n9HIifIAzG4Nv5iu2ivsufI1FoWwvZAuqUuFcFnQ8tQCASEggsiIxOttF3W2R\r\ntTFUCCqDQLa9dxCez90mNFCsT45QHzEdKMCPB2XSDJpSP91CRWXm5qKYhR1e\r\n84E6GlKw/ocTUHS5mY7rYK8imlQcHtis2hi0M0LXoqh+MJFiL9kai25squ18\r\n++NMEXzEjPv/tpWxFGYf1dQvc+N9iVYjC41mNzrGTBoUbKj7KV+RQhwoLbL1\r\nQe9f/PdLEYzyNcDnz8f8FoJspFWXPKummR1rkerBmnXFlbnvp+7bBUNUYOOM\r\njz6fdvoYXaGLsZWmQJ9zC0K7GTLMaRUabvA25ljm3d0eFyeSPkOEekLMtSow\r\nPTwymFlLZESO2f3ebOQUMOhnxl7UusILhCuOxVeVv6mjoX5TEMRc8Z1jVl84\r\n362rwMB8F11SqX5AhRenTJQ0/VpSIhzho3Xa30h4XhrrcAlWtk8u8zm4awQ5\r\n/aYwuWctmiNym3HUhlYpmwag36zrPdsL42NwEUEF6uNWQbivikI0kceHJXNS\r\ne4zoRZCWsyM6m0vW8eTQKY5qDgRAONRx42w=\r\n=eKj3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6d1491390706ac21857752412a5e4d10e112a29a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a_1668038065233_0.7715035080463009","host":"s3://npm-registry-packages"}},"0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2":{"name":"storage-mixin","version":"0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"05b4ba17200c9a3540377a2b361fdb7c21f93976","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2.tgz","fileCount":23,"integrity":"sha512-hgQd6RJWo7XITA0RxFJrm42j48liDtRdboac9ouYX+egffhi7EOipy4eQgsxGJ/Ew/4TlODbQesx13lnBN75VQ==","signatures":[{"sig":"MEUCIQCRjmJtrzapmfgLPjBpeRw7R4iRXYns9y7ROHyZYATVBwIgdEf9UvXM9tKXSqfkyj4OOOFz+7IIZGZ9JZRvoANu4mY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbD4VACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoSFQ//eivuJ4Q+8gMYUmU8j8jHG7xyCQBTYV0t/FAVUqhS0BItSHdB\r\nSaJTrUuzNfQJeEKPZF0Oq0+xf+nTE7neV2DTAojOlhsRK0NXmhD3YyFSq7Lr\r\nxy29B6RC4vtAMHxF/GoFrA/A1xg1AE8NNUyShV3opLKwYNi+c2s5UAIo62Kh\r\ns2nXCEjQl9nJRIUkhhWjwhwCIHQrtlw1K+AZNv85pWAwbB5T5A9qDSU1vFUE\r\n8ZrDsB4bs8pLMxoK07scjXNAP2Q2YwTRGuR60XV+wUYC4QKqLFjn5ZTrl9Y3\r\nJ5QBafg12N0hhbwMk3IvfiBvAhCqlRpSmArDyK9rDBUMX7XfQ2qydHSbkx/Z\r\nicfaD62FBM9Ka99/ypQAXg2Ji4JiOg0ZWlww3913cDKX2T1TkWsvr1E29gSV\r\nczvTQP9YrsQldrXfthM255Qc+2t8OupN7Jur7Vjqq+kEGiWSARMwDJxejtYI\r\nGuFqXbfmeip04eLYxyLx798ohjfhqpdX9k6+vsK3Rrclm9OxU+aG/cQCzptS\r\n2lQGI1rEV/aXb4VEAlFyx0awr0iumoRT63nJzM2zqrD3ydh3LWGWEbC8LNF5\r\nIx51VN+VIABOAh6Oc7sSmKtevcWxTR8bBSNaVDOKf95JUeYF5E4XJ35tvjWJ\r\nWINQspqxsOx48Ro61Fm/dgZYcUSXmu51KoA=\r\n=aXI5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"44318443f2cd1088082181789b25fc26a7a11bb2","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2_1668038165158_0.6196374678654686","host":"s3://npm-registry-packages"}},"0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a":{"name":"storage-mixin","version":"0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"089eaac7ffe76ff98b3158eb316953a53a451b8b","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a.tgz","fileCount":23,"integrity":"sha512-KmhfJ+e8ky+CjlzoM2xwQ7vaOosZ6XXfYKYm5+1JzHIlkDtQnAV8x97ntuXuGFeJTkL7tj2Au23JqqQMzXoyPw==","signatures":[{"sig":"MEUCICzOdXCN9Oi8q1qxVzvInY6t0wnaOK0Y7w6rCM95tqzkAiEA2nqdTpbZAVSuVjaCNy/9p8KOh1bU2dzPg2glXP5+vdc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbD8bACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrrcA//cABYJVvMuZPsuIHgApbDwpZo7z7Zs/zrkzdlf/znOZ2g7EWo\r\nCKacun1YN4iU447w3R164eohPSVeW2mkAR6rfJSYMXIm/DaONImhWq1Kv3NI\r\nqE8Tn3jA8osXgzKQAf0oUcEJ6/Yz9tunen424kj1NHcgzfC1PrSEP2HzidF/\r\nhXQlrREs+BnLcOwE142GJLCxaWXtkSIuiGVJJe3f+yDtfkidXvuAvcbdNaXL\r\nfniQwYpBe6zSEL0f58g+9EAtCIC7MNLNqPF4qH7bLRD4Q6IwKur7Bs8AzaE1\r\nwBO2kySFMe3rXzkQG2yv5UOWApr0oqX57+jT43XdGhwiZR0aoJWRXcigJtpl\r\ntcSigqCzK1GnLWVCEtfuIumCdOKnNUm3cTDssmRjzTSU81br9FGmlS6g57sr\r\nYHZ1D/4+5E6qZbeI/plNYfp8iqqaPPeLF7qyMaCzne0SlTTyqE9W6zy9X3Ru\r\nf4KH36FQpvSUDG2a5UPVgSScp6Xesdg5m70RRjsQqt1GhfrdvVLkuBvxhbKU\r\nRn5G4VUHn6kH2GOTaRcy7Ra16HB+gPfWDyweBUZy7eKL62ScnBkcCMt9rozV\r\n8EfnmvXsW/cDbBjYEL4TzVxQbgu0HU0w4GdOhx4vxnuBvFF3IG6MJI8j15j+\r\nsFSIk5JY9zx+KaRQSNnkvvhosQyX0O17C2M=\r\n=VMMY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3b50f8232d3349fe79554f36417d7fbb45b6352a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a_1668038427121_0.4129246976508194","host":"s3://npm-registry-packages"}},"0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e":{"name":"storage-mixin","version":"0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"86cf9897bc28919b922f04b9ad0c79a5ed997a12","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e.tgz","fileCount":23,"integrity":"sha512-lDEByGJjCQBL9y/XAnIOX5yY58Xm5QqANBnOTT/FBaRRNb8mcN/eJJtGkzSc/Wz6IMWGDQLd2RkQLyeok2uG7g==","signatures":[{"sig":"MEQCIAWtV/XnA9OaLEw0sns+5+4qPC5VuqjNvTgHlOtARYgxAiASwa8+0k5m/h5PfvG7lzYHZIbkJqHxbosKo/fnCirl3A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbPKHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoYrw//UbAjeecB/Fj996x8QA50TenFXMNgGBNRalRRD8NjeaNvxARZ\r\nU/HNm30JLW5cj7WrFaWQC3+HRxUush7Qu1iYONBXv9ogFU3d+obxVBnOwRlJ\r\nK86/3ZDQaeOvei0G6PJIq8xhU2/54DfVDApIblTdTuZz4EutPrNn8i7B/w8k\r\nL51+BXnRUbN/pNQg3yrsoDVDVtSzHyKRTDmnNI3t4vjix7Je1Psaylk3kySP\r\nHnDK49Iu8jg0kMsHN155u4h/G2Ghsxw+95a5chWTHZG+PpS46EL2pMDziPnv\r\nKCeKx8LLR/G8iBc/4sNE/Swz8oX802a224Bz2DlWE2JWYhiTlttFERi/WPs1\r\nTSlnKA1oPnivEhLmkWBbJ+rR/7T3rmzW3nPs572xL7xM9ksDNl5eK/R9wYHn\r\nzb0Icb52ijiCSR1Fv8244/hWZG8FTQS5KvfptOAPI6Y1dcDXRyE8ocgOfqH6\r\n+Sfk36CIfERwPcTAZ5NnP0/eRdavHvgmSC4nfTpZyrSymgJH0dEt+bKiMEiE\r\nHgxfoWsdeMSgiV1xidFb/UyEuRPI3GkPwN/QSro3IBLUyzzL9M6VTKUogC/O\r\na+yJUYFPVcdoGCzCEXU8HShoKnVlxdIWNhQshwiWL4eINQnfaVBxYcwA1lZZ\r\n5NYJe80V6ia5uvvkIvsw5ITOzt8XfL1NNC8=\r\n=yxgD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"47b085701d7c0b212b54bcac46f6106d34ec429e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e_1668084359423_0.12470369163935069","host":"s3://npm-registry-packages"}},"0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888":{"name":"storage-mixin","version":"0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"f0e3503f6f91bbe9b896ee35d4a0bdfeef3965f2","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888.tgz","fileCount":23,"integrity":"sha512-MpTMwDKmgovC5NrY1Q3dJeru+Wu75IYoZahwnkcWv/5/6vnk3Bd8k5zHsLFEGNt2C8siaGnRh9vp7YlqlB8Pdg==","signatures":[{"sig":"MEUCIB0j8Ow5R72kxiexKj6H7n+lwAIogLtYy4UcLJhMG3YAAiEA62p8EcDmakE7pwJxXviEhHTfIIMVWuMuWYS5MLoJTEw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbrP4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmomug//bEesb9BJ/cTnUSa6tK/5RE7eMuQhyIXjxYPm91+Trot/FKqv\r\n2bvK9VCO+l48XscYS1zK2gvrJf00ZYw1CfspGpe60z+l8upCYVkvPuLo9DYA\r\nMrA0RWqt7qlFzgkh0O3HyaExkI3xWLx7ZFAwQ+Ji1DcFLFKUbRRh1xfjGxmv\r\n15zktmwYGNKAmAIPYF+LLY4GvhdHriDYdS3El2iyD6IKg1jRA+BxY61YL4C6\r\n1BmZg2APYq8AAZPF1vty3PCVb2HqwADaRMsSqZYTw+hSrD3E4XghcQcI4J91\r\nGJCGLv9wy+QCYDrih8D+B85bi/XxhuhSmJ6/sZNaVKbLc5PiR/1s+IIgnEG0\r\nmY9j5Xm7mwnAopnkF5nHQVRTSbBAFNJXSf7KwCsk7LGK4WgsrsFkvZtpntbu\r\ng4DKdvdpJN+GFfDMXrK/Ha80VFlz91Yv868MrplvI+Rpg8lgjdrotJLZABDg\r\n5wmtdnN7TAZYS482y7azGVnEhWc2juex27RVNhIFsA/WQiIzcw0Qgkfxv79W\r\nU7gDf3E/GphvgKltYfsH4JKJquD42xffbFk46Z2vBqIC4I4Y18ZjMHsB6Uq9\r\nGoQuSBJPHQ+tpUw+M9rPtKgtDO9zeQu7t/uY8KkRgZP8br5eZux+p62PTW0g\r\nqJ8kCITqzBOi/dG8+CDYNq3knrpy434QnMo=\r\n=4H3i\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"9e3b266e199e346a30e2c20aac373d48c2ea9888","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888_1668199416723_0.22423195360927606","host":"s3://npm-registry-packages"}},"0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0":{"name":"storage-mixin","version":"0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7d9b13a501bb3b4e02f4b248f855e915347da1bf","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0.tgz","fileCount":23,"integrity":"sha512-nNrGQ8L4sII4GihqIt40xwEKn1lQTSwg6rnOb5JDxLYPRu/Eh4hCOt6LXIpQTQwHy+GDX/nqB2aWxrddV2ZK6g==","signatures":[{"sig":"MEYCIQCZ3YQlY5ubu6lbXv5CO0dKtShf1VwHIkCtRdbRLljBUwIhALp/P+6o7PCx76cyFZV3MZhp2yQFki7rNhk4PawKT593","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdW5gACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqfDA//cr2BiBwy0QlcEZP5QKmZO8X3WWIBpvWg9Pz1GzFrSu6HH1EQ\r\nAH+cPZRSivAoWo/ww7n/vvx1KUUIZM/f4OpaSl39X+JVJgug/4PW1/bmKa0F\r\nVmEIPil4r+1FcSXATu042pLZsFzXtKjTm/bvXEvAT1S5vMhThFkowoBFkb4y\r\nRL9yvL2rva7HGJjbZOaYwjCWQzXGui9CIY+ldJb+oSEVkqYOq00eYaZIQ0uU\r\nKQ6rco5P8W7gx/WqXzPm0b+wY6NoulDkYVU4vZUjLuND3736KnlCeDw71reh\r\nv1ZXaaX085ODXMA6W/6eF6/NtdxFQuTlRIXfVnRf5EUdimsA66qV9FpHS3Wg\r\n5aXVCIE1TkWThOo7Hw3ZuO2J/fnSEnVXEWo8U/f2Et+B5gCmY2Td/gA9Bo7Z\r\nDL0B8D5bT1jGN27gevzUjc8NrTWVh+QQ7BGCE4x0Ty6zFElB7xvK0d0mmsny\r\n2rdlo7sdoCgjo1N4/ICgSqbUJXXgccnPwDcFIVCdeEzszOe8DGLciHYnJ+ho\r\nKug+9IVCVfHk7yc0pH9zdW/SXKm0VbCyQ0dFhPk5yUf4Ix420i4y5W+N2jWu\r\nANwrxXyx/uowZiDD43BmXyum4b5Ehzji/WTlb+SrFBrMS6+S4pF2nhHWQW7P\r\nVFEQWLQdguyn1qfLisyCQqb21HEmqxJUIH0=\r\n=yfTS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"91daa029e219b08cf0b775b6648d35867f2272d0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0_1668640351851_0.9950471711662978","host":"s3://npm-registry-packages"}},"0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c":{"name":"storage-mixin","version":"0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"dcab8f426716495937151d6e584a002bd717b786","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c.tgz","fileCount":23,"integrity":"sha512-zPjnSE6AP0a+EAd1wAsuCbi5WRprQNXXZJhvCQUrSVHtdD/ZQabqubmxxB4pfnK9STuq/tG/l6SYo9P0eOEQeg==","signatures":[{"sig":"MEUCIQCnQTf5cKMdkikZaSqYkcXoP62nLkpJKAA1C7Z8V7uVRgIgZ/lSgK/wbm/L7Qo3HFngtZLuyi86oEfTn0CepsoOGYo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdZ8wACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoWYQ/9Et97b2EVpEVRmW0HN8FDwa66sWNCnCHu+STPME94IHvoZISQ\r\ng6Cc7PTTASE3Yq8Avb+830kfv2oHwsxSPXa8a+nPN0WThfBkn7FMoOxVnoX+\r\nTIvTnuIvANUPOwWiFW2qgL28PZAFc8GWURwstXkB5XE6SmEmSFQn2u0Hp7lP\r\nbECuk8XWpk5kuGShh+m140+Z3qfnLeCN4jAyJowdmGnb38QinKZtOhmJ2FQy\r\nYyTMSNOLkAY9bnxatSWp50KCbH5KY7iING0SFbI/EUyfRPyaBCiMKIiSGhtc\r\ntfyAvjz9qeWfn9YWnOVxFOtZg5puxaoofgpbMy4HUuvl69Ljika1Ti13f7q/\r\niDp+/QW4T53bVITcJx8YYZhHhMjbVRyRDThGkgviSQRkgoz2wUbKp5FqZ71t\r\nIS1yOjg0NCfS9pKkQlgYfl07vp0syMjF96fI/1kKW+1XaYtO0xBEEe4mty/o\r\nf/cd+GZMaUXYBZwOiZM0m9v07H3NS9QgkTzfciPCx7Ls3adFj7N4NZ+X7+ny\r\nRp/wp9KgCBrutxvYoQlz3yLP3T3EjRhpryQOnvhrKy4A5YZ/BQsNmbyme1A+\r\n8DO51FRNrZnxMtaAma0gFIDXWz6unUcAZtodirOzqdOIVSXtvhKUZ/iFwSSN\r\nfLLzU1Q8GFzOwTeogZPQq3xtMT3UZEky5gg=\r\n=7+mZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"27bdd4c654b0108a364c4bb3541996722734028c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c_1668652847970_0.9500352169154591","host":"s3://npm-registry-packages"}},"0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb":{"name":"storage-mixin","version":"0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5a425963943db6848aacad852715fab6180db537","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb.tgz","fileCount":23,"integrity":"sha512-PU8Vu7eKMciuWSUCa9TFI23qhCjbhsHwXeyEZEuV3iEBTzXj0jE7AK3a2MZz3Cc/lb0UQUJ4ZVROlRkGZcITiw==","signatures":[{"sig":"MEQCIAI/ViECopBQVhLu7WvQGn6ttCMI4JGVPAZON5HCmxoTAiAsQOKmjWBhgTHhddFvaXXxkJlLGLzU7sVjvYie7E4+dQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdaFiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqmaw//d1olB7D0Ti2He+/turFc3FuFnZIYfZ4TtPN1OSCyjz8HXG3D\r\nBg/s1lXOnBDmSn+p5gI/wEJFdlAgY8cIlApM4eDFaYvKdWiCTPd2sn+XeVU9\r\nWDDL5szb0mQ+7CAN4FKxpFM94r169L/2vHbbE9VBPCpni96YKJ71Zey4qH3o\r\n6URh4PF1u1vZPIYLXpLHetxHEUBEFpfMJVRgmklvxk4zICVM8PMVYYn/h1pn\r\naiZM5ymFKz0lPfHNZSiEEl+kuXk0FPEhAiS8603/WCKat514Caj9YuM4N5k6\r\n5UYS72X43CzFIHzsXvzuwbD1aBUfwgiQCX1d7TtQGxdt8bmZqVir5EBzMHYS\r\njfeiReJG5A1s5TfB5/6PAWiwySCfwCPnI1RqNKHArQSgssOqYL8yCxmSzIOI\r\n+2aiXkXGStN1scAsfvFNZgp6p2yFFYGHXWXfCXjDRKuMPxRAAQu8TxHljaAp\r\nGokoFlKOlajDj9YqTiGAs/ntxry5T/3SdUhPVzuI5/AOo1ht6XAZMXzc7mTU\r\nGyJk8FzcBLmjkaPckwVFtq0pnXM7/KsU9a0Y42/+XgywyeaxarG8LZtZKKor\r\nv/jp9YUropPWUKsSGxhFiGl2W3qTJsfm1XWYPqkX9vbUJ8Jj/ICO8kD4iVgA\r\nVCqT4jRRuxyUBHVWzRoZZJ7zcB/HmhuFow4=\r\n=x9xN\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"7f1112246f97f222dc289edb7b9f0359d8f020cb","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb_1668653409918_0.2689158392642075","host":"s3://npm-registry-packages"}},"0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c":{"name":"storage-mixin","version":"0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"f2823968110f34b2f1602fccf60d54f29d8e236a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c.tgz","fileCount":23,"integrity":"sha512-+FC9gYytk0alpExARam4Hl9mFFh95J4SvHl8xfXujVPWAQ4otaB5Ngz2ysabWk93PzVJU3Q72YcpcnP1UOhQ2g==","signatures":[{"sig":"MEQCICx/FijZP+yhyQZIjX3fPsjgDhkPo8oTsSIHY8w+aUr/AiAh61j6u/owLcwSyt4Bj4jldsOOosPg5/3mkI3ykML26w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdxE9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp23w/+Lfolf9lUmh8cY4RnjNGZYAbLZ7n2YrEO6f7xIopR9YIRDKuj\r\nYjGevsyh8QalDN/XPa5+jbhlgX8RaXckeW49YrCJlrt/unwkEYZQ57bL0Qsl\r\nvIP9wA2anpzzN9NXk/Omz+18+W2XcQ2NxIvh+JAy8SHJuIdt2pVSC0rSoUTU\r\nmsinHc4ppnzsSQEEjFpQJk6hNLF18eRWRplBnXHNzYNwBwj7n2aK/RvtF82V\r\nruRreI4KEOcSKNJd3q1yUdZz7XR55pSE42rgIeEmSYInMwh77l/RPcWqX5T3\r\nDO9flYoQOzS9yMsnr3Kzx+ewlDGyV803o1N8k13oq9WPWMAZBrbrdmhyenU8\r\nooXolYFVh76jP6kCYbzn/G7sVG6QSV/lAisAM2hwl7UyBSrrrFFURRBT1A5l\r\n1sSjtaV5XEiIx5fgM7Oq0h8mkPTRm+0S9DaSL92eqhzsmCeYC2WueCGRqmPD\r\n8ykhSIwGaQmBDG3vP7BYcDz5aNAqdeRHd7+ZGWJEXsh43VKQvozy4J6vV9/5\r\nXLqCYmtYKgdxtjPGTetLiwksloCx+jtdLyyDbYzqbjvfokGSfGTnR24OYd+t\r\nkujhYfc+e6KpQRPnkUaDnAHyYBgKJWFdK1YGIrj/hRp2Y15UWV86sVVwa02r\r\n4Sfk06kTwd6ylUIxBRhRoixE0pxc0+SEN1k=\r\n=3iIO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c12720c09369b6620405de027fa85d469db43e9c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c_1668747581350_0.3760446346680202","host":"s3://npm-registry-packages"}},"0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006":{"name":"storage-mixin","version":"0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"6b77e0db51e6efad93c85b86ceaa563cb4ee06db","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006.tgz","fileCount":23,"integrity":"sha512-BQvLiuWmZ1zILgJ/+hzWLjZZ/yIZa/tez9J08SMZt/u+DaS2+BRiZ/bHTwi+9tXTe2CEX33LPvhF9jzoSSi4bA==","signatures":[{"sig":"MEUCIQChr1FCF0CwiHPbTZb1stzo9oM+GvaNoA1EjKMov/9B8AIgd3Hgr0I3HKQvp3s3A8txHC30ffZdR8hu5c6ciPO188I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdxOKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpvYg/+LNEjbgbISIfLCYLcYehYYrzT7ZubsEosEXSUyrtiwWw/u5iL\r\nZz6LKaZiziEZqTdJNkIt7cOQbgCxGpSIBgxd2UEIvb6Mf8MoEhK1goCld6Qq\r\nkDpBZ5GiJDqTCIv4do32vMpWiZJTVGmtiSzP6t8ReZQxvXUBoMk1C8rQAYfP\r\nimZqEGhKwggj0cMTxhasDoLSSMzLbbHBTirUNLhbf1gdnHpP51hebDcYiU+o\r\nb99YNByMHi21NqjBRJpUoLeWueOJNyCorDV11Ir61S5iZDuyNGm5T8rwnEs9\r\nFRrX5Ktm5BCX1jqoKFDW2Rn6NzT8NyldKyf+XUmhR0HjgkLLD8UB5yrjdJsC\r\nsqN/lEjB+vkbR90VgyFjfOEbldy7gHOBUj5iEUDq9hRgukHpjLYimqsqjoGH\r\nVah/XP/Xhh6wTN7VJj/Y2xbrcBn+MIyZIFB18jUk0TnRGBP9BGzy6uHfPIII\r\nruupQi+annaSE8OEwP7hERBzkW2ndbGMa6OK1CeLj38GQOpR2yJn3KRKVSRq\r\nleyVPfYUf2cRoWG1POSI8gnzQ6fKjj8w0kPaBx0yKt1hcwvUo0sUUdk7w8Xf\r\nVJKKbAJAaiiR5DTu/J5ihcBWxe2P890dGbjOeRyHCL7cqnDKnnpC90PDMSt3\r\nwfdiHulvTcb4cayM5Svx/srPsXIxRJF0SqY=\r\n=gOp5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"2122563cf622c0d212372dee10ec2a4a664d8006","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006_1668748170561_0.328448768027501","host":"s3://npm-registry-packages"}},"0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8":{"name":"storage-mixin","version":"0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"698ba2de6965f8acb6ff56ca41cdf794b0d62903","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8.tgz","fileCount":23,"integrity":"sha512-PNOuVUXEdU9WO3nhiWH3/WhRnhiBF+fbMHORzq7u1pRz8uC+6UhqP0kZzjvosjzFieV+bjlaPEGzmCbHJGn76g==","signatures":[{"sig":"MEYCIQD22s6PHz1cKY1BFc9kc5aKOTLus9yPF/GBiauYFW17cwIhAPX3JyNPw6UR0zgqzNWG4qcWOAuqLzXES3WxBy52qMsq","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjeHymACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrVWQ//YJLEzCUeVQPktLKSeyMGfp/LLcMKrDminUU8+dedu/op9rUJ\r\ntScOLlfG1yE5G/KAadwfDeFY8eQ/wqEwTQ7OvbphbjbFjV7HEO5kxqPql1T1\r\nzysXfZYtw09ExiFykfoMfgYKRFTMQoGpMxnjzduPSENgbh0z+mXJn1DTGvcp\r\nTphcCrKx3CnyzGdyUO/vKu9k2Eh2fWoR1y0WqkZCdJDJM6870PL9kOsjgRao\r\nuGL3RrX+IUaX0//DX2xJS2jytTGsNvzg5fRBp9DbwSk8u6DJqHAgYewqZztV\r\n/wmmycJZJMK8CcETuQC6BOeDT1xSLzpPeB11FK/+EuG07zrGV27g7Lxa8A+V\r\nlVwHNfu5DykI/fvtnk3awzqa1OG1AE0kpb4ZVNSEbOWZ/XVIbHJJrOwuOP08\r\nrapHBNbxBdoVTDxBwiEO1O3plEWXzqAgfGEmUbQy9uiGEcQJkO75gPs98krz\r\ngAirAnazT7dft4zvgwMJ1/llIgxcYZkkK8/KdQvT8uQ5HMHPHajCK4EzcFzY\r\n8yL5P4f8AybfmhMDaQZgEB/y+iqMjou1JbI5WPIA8AAGj17jUtEWwdfRWJ2O\r\nA2qkhFqHAmmO4KzixXEN7JMHvkuYKnSMrlYScKqYMzgZ2xsXpqaLgN/ZcDHF\r\nCNos+B8nCVYGy9ZPYwoI4rNE/atvPIU/zB8=\r\n=dz18\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c31c6db319e5099ee073b5782609b1dcfa2370d8","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8_1668840614463_0.6648422908750542","host":"s3://npm-registry-packages"}},"0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699":{"name":"storage-mixin","version":"0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"d7f7fd28ba9add4b9fd0d0b1d126705d410fbcda","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699.tgz","fileCount":23,"integrity":"sha512-6p45V4+jpe9GnFXkpIgHVsxbzUKEGL67u5qEZfSLJLsCUTAskFBIrkYkdNN5QmUVYT19iI0OzY+YYnv3seffMA==","signatures":[{"sig":"MEQCIG5UX3URlKsAxwTo6wDKHwvVdNfVG6SAgy3jQAPm8k9CAiBZ/5REjGP4NlOVDtEu3AnJG2ok5jyE1pUJt638HgZ4SQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjeH/bACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrjlg//ZcNxTquu/M6e7piE0itr0AO8wYp/+Q0EdwaLz10yH3b0CWjI\r\nz747nzvH5QpYSl8i1g9JfuAQjEhItyLppM/9T0jcQm9yMHDpWaKcM3zJDiNQ\r\n0++tv/S4DIIa16oVuOpKCD9vQHHOJJwHtT1eAxcIG8pbvr2AvoUBX/gkDxNm\r\nqjmv1KEFRWfBMbittEsoDGGcd6n0m1qUVF7ncv1/SApHL5oyjMA6T3DPT0nF\r\ngN3svNxFWkgAWJrhpdg+Bg1Yaj25IugugkNxE/iL9rEqgtEkKSupclz30XZb\r\nibi/jTBQQcZIKRuSXIfYiAd2XQoaTSkgd30nFXXjW9V2j/gEvZ/DOXHtoYYD\r\n8bEalkTukZEvO65A9X90dYePh1RYS/hktZwsTe++n+x065Pp+lEB0vp+SAG3\r\nf8yjcehT/oGHW0QPbdwdjSp74oFgr3pZ42tkisDUgmZUna1GI96w/NHEWLvQ\r\nAbkelpMq1Ir5kdnFH9tj/PINMLu2b0M4/H9UjNTG6iHlSyo5EmXPEUUuSYea\r\nlv7GhjMnsVP7bmxus3++ePdL5SMlz3FB+105vveswUhR2z6vSyrCt508e3Ty\r\n/QGbdIrsDwJqv4LwJHjqfW2tNDdGygqem2ciEucrUbsu1sF7IvtNAL60DLdz\r\niHpyMFO4VYSI2qi6mxV34K2JqVjCkAQdSm0=\r\n=xG8j\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"981f8ae49e299320ca0add5ae8e58c8738baa699","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699_1668841435174_0.7249917075822969","host":"s3://npm-registry-packages"}},"0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0":{"name":"storage-mixin","version":"0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"819cbb236f0ec5073d8cf4b3dd11eb106c0506ba","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0.tgz","fileCount":23,"integrity":"sha512-ztv+UkbLFbnyJ/cy5Hnri7GhSGoYiLlN9OSy+rUOcYOXI2VlmWMzSaauOjQ2AYL5dRuCI7CPCrXnFyQ9ZQuIcg==","signatures":[{"sig":"MEYCIQCArbe4C3SqlPicSR/2fLoeGxfVzOFEWG98A37MJJn3WQIhAMfgF3+GNMZEys12l9f6pgrqdb3HNI/+GlQzOmVHpMjF","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjeIB1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpNpg//ZGoJY07aCsUPuXFGtFchjq7yWTtCUjlRbGvYIsxNLghuAh6D\r\nLd313ELbHa3Y8EqSP5Gd86fvXsPMj5Jd5CfpoPRdXGVJ8oSpvhWi2Nat2eVi\r\nXl/3khFsfG0hP0gMFtYAfE1/g0070PX3ufci7pXqdmCaYBS+JU3zGNsp96i8\r\n2wRA4NdVyR9k7Peb+wl7Nl1zEFQCr0nV0YDoXg6mw03P2GEKsfiI9vMr8595\r\n1BInOacii09Y8dHjvXGTnJbrs4HfI+wi/JQy+Rk7fDx97nauhkkzq0ixwv4x\r\nq4yjq+jk0XCNgjR18u3U6D7U1pFxxApuku7IhwmhyBzjUtXaCQXmoc78kkb1\r\naJ9R8ODhMw01Z84Sz2d193MwPAcalRKtyFbk9UNZl7CoQePAbm7qUPUn/lUB\r\n4KF0AU1F1as8vX6j8PtgnPuQVlxWxQbN7/My8NBG8LiMRzeabcV83YLGDG5a\r\n/qciGqTNAyPir0LGCC80034Gm8NT7KHFtSzxPcCJAVlQqEhzzimFani9wJVg\r\nVjgm930YRrLtAJa2q6IujjYDbi/aTCTSywkhhWhaRt430ZdljkBCawaZz2bW\r\nwMvketCZ18/wm+wY3YaaK9XY7AnMAN/j/RCaO0r5Ak+Xjp8aSbXCRMiq3p14\r\nWZ00XvWSAIfod5V76BfwOEHCr19u2MHAuLo=\r\n=caOZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6a646700444fec2ae51cd86f87f6a29e58f774b0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0_1668841589128_0.8828862282943739","host":"s3://npm-registry-packages"}},"0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7":{"name":"storage-mixin","version":"0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7977ca54c703f5e81d720a62f7046261ca639195","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7.tgz","fileCount":23,"integrity":"sha512-OguIfjB/rsOeBKWi5OHXdwgCJQbIDesSgoCS7QabRlWcJsnTiNRZmooaa42ndU5L6rtJk3Urqg6ft8M1Uv5yvw==","signatures":[{"sig":"MEUCIQCMFk5vgIOJa+oJfqUBA85oALdcMYhu7aTL/HvL+31g2gIgKx0vD377BMsL5WCcTYk4O2GlAPfRp64hsKrjbnHFpfo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjeT+6ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmowlA//SJ2hb73pZKAFnB5Mn6WsdWWLUKIvvxJpmQJsJhS4RVjGCXp4\r\nUFzsoHdPbXxi2YHAxUsHt8rj6OMBg3Wp0GB6lzghzX9j+j3+xD/nLNC+doUT\r\nF9I8EjlqhpMSgcAbY7ioZlU620nU+LDqgCpZTq7M7UujCxynlwun4rZBP1T6\r\n6praQukzliwUFYSDm0eh0gd4q9OR349VkS4J1EGAP5l+1orqSQw58bPv76CR\r\nYSLwOYa7Qayn+bdgFN25ixAVg/yeIIY+TwgGwQqDnZUnbkZG/nHfAa1G2Tg1\r\neiMCEPgdhMvjXN0MQEPIU/fXqx+/YJU149cZ/+O8XKrSkHZPDPJm5aFbkv69\r\nvUUyCKhnVRj5zFEu4f0B5zbgMqmbIqQiPugRs+3viCL1IEiq73OesIM/Vs4W\r\nywx3thHeyVgiuF/S3nnEjbt38TzpyWP5n0OteydwAP22i+7767ZHl3BT/nde\r\nCNmbk9lIHwhUWDllpCuhdxB2EvOtqGZEIsDHbZmL8mFvgDEsaBdVNnxz+SX8\r\nzM4No8LumwTnTuN45OJJ82t7XDMOcVno1Jf9KxSow4a9Kh247LPuLCtDbrNH\r\ntEjgfbYYIdkL/HznPzHtRa90kxbPYtyjJVGJJBeIiQ+GyvHYo/owVDohm/6D\r\n7weAic8fapdPy9IJ6O1uPIahgg8atFp+IwE=\r\n=6i2z\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"112bf8f8b20d7181824478f76e627ee32d6e03d7","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7_1668890553973_0.9552098702237373","host":"s3://npm-registry-packages"}},"0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd":{"name":"storage-mixin","version":"0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"2dec5e6f5c233f0eaf4ba3f4df87022bd595325e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd.tgz","fileCount":23,"integrity":"sha512-GoDdsAn0gBYgQiDDjwsck+FkCT8k0cHgQLY2fkD69uJXVv81FbsiUs4gbxQAN2ACrjcJOTExeJSzqpUS05LpJA==","signatures":[{"sig":"MEYCIQCOSBqGrKMl1aQg7+n/bUKnXfb5f5XumM/Sr42rVVi9DQIhAJGLHUvnadD+Yzsw0gfaJlLGi9mhQyAqZwtKu79WVb72","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjeVXYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmou3g/+JwVwlB/LoDwk6MsQNdXC9Y4CoUXMkPB44GiksYmNxFpapeO3\r\nAlhVWHitPWFNACxOGoFWa0QYMS2UQ3S7M0zUCA+LqZ4C2qTCeuz5m8xcgAj7\r\nOYLkhResMTvrsueg3PuJlftWdzC0ExJIwTEYXHQn/BrFRq2dWwLv1WBbFJ7C\r\nhbGw2NkV94RIGkJ+rc8aSwN2lg8SbMW2XwQ3diMtr9iymHTHsItWJZGmOMnM\r\nj759+TS//upUYIS7p7qCinQaBQikf/EeJVuJKRuOAsVAiPi6UmYDWCZ81fhe\r\nc+/rP+ZtgE4XKoQjY6kICmxACIU8ErhPkxkDWlbGSjFvtri6t8UD/xfVL/Of\r\nRK5UOn1VAL60hSgvEfV6jFAyj4Bcr3TxUkQiYkj//WohceP27eJQC2zUjb21\r\nSgmNbLNvxO2ARfKYTqP8bXs/RnvvhyXOGnt6xoQdEURyvhgTC9gr97j29tiq\r\nFir1rPvkUC5s8fxj2bFXh6hFWsZn009/gl80VIXbSzrN7JmWUlD7ZnShZVfm\r\ny9UPV5N9SWv6AV1Bb6NV4mxoJ/qFKRnYkuhil/hp8nkJOAd3Vx1WZ2ILOcnN\r\nqkVzxzGkDD1tYTFE9H0l+B/PcNDgEVjSGklUpoLNMcLlHkF4O2G1ehvm9JNp\r\nnpnvS5/AuB2GwZo0ja/zzS000by4XIl7GHI=\r\n=QqbJ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"19de7da29c34177349014132e37b723c1cb16ebd","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd_1668896216146_0.17338720366249727","host":"s3://npm-registry-packages"}},"0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46":{"name":"storage-mixin","version":"0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"07aad1cfc2b458e6462f51fac8f1b5f2ef15268d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46.tgz","fileCount":23,"integrity":"sha512-E5wuQ18QAAtLNpTOa6OfSBokH2irZx0+7f2mo9To17PJAl4178BLpBN8ywEa2Nw4E4ogfZ4hQkSlR4Noj6TH1g==","signatures":[{"sig":"MEUCIH+HnYu9dHLqMQJvOsrVIj+14r2/p6MXkCUiS+C+UYcPAiEA9sdCJMggoW11HNVblCOHUod6Hqz4auInYRxS0mSAKCQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDatACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo4bw//SSY5lXaBOHi/Yqv3GAvuuHMftyZmis8eRFmXcQyN/bwmKXC3\r\naKR1U2xo1QG/9pWY3lKMZ4j3CxxOy3+rAc+fqex9aouc6+QFI4byEk9v54eA\r\n3WGlC/MeYJulpJTuatfsuBeu0143xyrb22mPVZFc4AEmHv+9ANPBKgofrjO6\r\nqlAkDBaswQwQu5dWAlRhqT4CWoOlxvSc80nMXq+6mrag+6oUjDZ/zD3g4WuY\r\nqyEHpVWAnwcv0S+1Oj66giRRFTviKROk9t0C5hIPZHt8qEGfZywjGnhGLUWu\r\nxjmm3aRjoRISlPupIzICiaV2u3gc22XR7CZ+qgMhF6rfU7GESqd9P7BbMZ8o\r\nE1LINs6fIOtYmZ26TcNgJLQcEbulkPZATBeIzbegYwgEGiXAdD6XAvDvhAX/\r\n7h/PHZlCKatJwi5sMahf46bfQ+kGrAKKajeAGN6Rj4BQeI67jUXElq/JD4z2\r\ni9pWMVRXXdDJOPAbzBOQBPKTcb5CoeNeiTuiLBrDY2HXONsn8m8nnMia1OqC\r\niZs4qThStUu+4iF1WA7dHhG6OHhYpwk9B4yTHsX4kN7QJa2VAD1jVT/+ScwU\r\nujgVzue5IR5EF0taD3LeP5NmJCgATWJIORCYK8dLM2sMq2HXjv+p/jjcrsqW\r\ntSXaTh88MTZol8UWTFEAEtNvNp6QpJJ+u9k=\r\n=AwG9\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1484036deb50fe0421bb8be4c48b2f9e56c17a46","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46_1669084845629_0.22772471143087758","host":"s3://npm-registry-packages"}},"0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a":{"name":"storage-mixin","version":"0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"056e849ddfd75af1502d056f0d57b96637388a65","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a.tgz","fileCount":23,"integrity":"sha512-XofBKbtP39/pi83/NLM9pY2YYMVhkqBjvFS1wfDqFKjkb4Yxxfcn5twjdKdw3Ovon3Crjd3jxj46xpFHUGx20Q==","signatures":[{"sig":"MEUCIQC+sSQHxebYeSC/UIcgsayqwer4PIldFgUZ9k80gQ7aSgIgfyaNY4j1Q20p+qjkwsbJZ/GBc3CRo8jA/8C4ED2S7ao=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDbfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr8URAAmRqYGb/KU9pQoRz7GRaRmDpKN2y/O8SEkv1798QNM0hr+Kb4\r\nq0w7aubRMCq0ULrk38GFmvKEQPb1nmKGpvaQbkaMzyS+En/19+lAMrD1CoXj\r\nmIEgJHwu9r5paVj+X7Rt1zTfrHEcoaFphJhKKng5VfFHiWDIv9Rk0biTS3Fm\r\nh1jAzHPex5vfDV5fZ0Nkl113fK0joec1cG7n0ZbdQiS5UscTROQ9g/f4A2uJ\r\nTDjLqXVV6qhS/R38eD5FfF6MbxHK86lPcrDP5GjF+p1IQ0s754tSuI8dm5mT\r\nvfOZEyckb01fNx6ueqF2Cb/SVaYXkpENqdFYIQ/Equ7LoqVnAfM8Wud/RJih\r\nbzU6zWg1sUcBi7yoW4qs6205PiGqZmJfsdCX+5FY9Z6WI8ZGRU4gpoSH3y8Z\r\nBIA8jC0OPqu5YjP2BfI2aLmFL4yOKxrDmpm8J4CfuxY/ITQPfLbRwNvcJXX2\r\noJ7YkX2XDVYo8H+uzbhBjEC6Us8CMgorjXqVbqGMdlqZBZMQPHP2Fyy4qP4W\r\ntnhHsdxdxEqg9CUKis2DD6JH9PJ8yML589Oajf1gL/zYNi1m/qKDCItKLnHy\r\nUJRfGl7ufdNFIz17+r9Kh/iqrDDW0Qs4JahdPo5r4brI/Tgxh6WhzjhmCtxl\r\n6OoTGhB0eR5XJwFqLkn2W28inUeMMFW8gm0=\r\n=WAJK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6e34a0d07479c665cdfa3bddb6bfd864365f6b8a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a_1669084895353_0.2046818572580842","host":"s3://npm-registry-packages"}},"0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51":{"name":"storage-mixin","version":"0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"3d876446ec0d8f890544c566199a91d22f082f0c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51.tgz","fileCount":23,"integrity":"sha512-2zLuzL363Gr3aaATfUYpqPIPta0vVnsryoEr72HdroEYp0IhQ3Hqf/IKSBu2x3aVCMiTY7nmBq3iFXlOfKQPtg==","signatures":[{"sig":"MEYCIQD/xRPwqBy0QqaKcaB9fPOMl2hH/igwI4HbEjVgny2TlQIhALiXstrFX3yDBQwUL2uzx75+lg2COGwYbgh9X5oUIcKD","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDeNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpKVA/+MAaSLI1ipDWXSKAlyflICv/CqxSsG2OsqVG0Ds8lAVn1FUSU\r\nJt1mjIl1YatWevoNhmIjEw2GfFsXrm0oHS+LEudstXb8nVVc1ifKVXsbWMxs\r\nemqXV3gARtjbK6VLDZUWOI6WVz1wLnmWZMmNhrqESHJzcqTiwogmA/iftDFG\r\nREgylDqOSCUCj/ttselV3Edqc9wfcGRGaydczxrV+fz07tnh1iRxCBMOuxpX\r\nZx7eN2zl9IqFGv4q9BveWDBy6WqO0fsNJem2S68vRS11/yvDPBTVQDttjFur\r\nmUI4mkbd4XrbDrTYdRT8geyzZkkM21VyKlq+NrYT/MzF9Xb5JaF7eyQzohJL\r\nWi04M18OaJaxR6vOYDkakXsyA8NB3oXQaAjyzZWgNnKF7Qb+a+Kz4FwAaHFd\r\n130Ev7Jt3/NfpOHwnHlY1xa2rlBEuChUZOCnhLqYI3CoKpmuBh75sxYrq7pY\r\nqXEY8EKFrUAjH+7vhTdAN0BZb31RGk3EDzBN0rdpyGNeiKlmbIj9M7AD5Xu7\r\nh++UmjeQFRK+stUX+9udXR7mm/IkoNPyS/wIIB+nyZXvuzFulfaCcCdifadU\r\nIkegPZ6dZnvcgJMTyBk9Hwk6XbQ4Eh67M11W0iGisFUWTVA4EaRmNHhr9xdR\r\nnLGp8/xp0KOtoUkK+P3s9C5U329U3ZPdmzo=\r\n=fwwn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51_1669085069108_0.25318948163832","host":"s3://npm-registry-packages"}},"0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388":{"name":"storage-mixin","version":"0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"1a2205dc88b0c545943bba897ade7f1be0d58531","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388.tgz","fileCount":23,"integrity":"sha512-RKQ3P8E8NpKeSk+DnZJ6oZnkEAkAup76+clofUubhdKcFFOkeRqly2IZiddnxX9a3IOfw+aT6UFI2NrLslIzgA==","signatures":[{"sig":"MEUCIQC6KizimPb4jjZE/WLm7Ct1MwREUQSL10Nc5XDAhE2PWAIgVuddi55oUJ2L0NLZ25phQbqA5VifWzsxLpvOCdn6KQc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDjdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrddw/+KCw8me85p53nJCDYZ12JVCOzDJqq7wVstmRds2p7Vdc8YDPQ\r\nQLXzXros7vH+bOTPoZXBNMkjLCK+CB7d3oK/zBapCewvp8EbctmB81n4/gs/\r\nTHDe3r0SDlm4Jjrxtp+UM3XlcXcf5nOV8WcM47MSSWirgavFVmftfdSUBjbV\r\nzrbval5SNCQGtBQLB7zEI1S/kCtInCzJm4axzvTdUN71qaAdRV0BDcE3CROD\r\ncKIRvDVQ3rkcwAG6aw0SX6wgnJjUkGEFuOwJZPBWVbBQulaMOQ5GXB11PdXu\r\nbZIfxV+y6rPAs8D3y+20texP0uYJzbSyUDDKbDkD36ihrRByA4fmIlYEVgjN\r\nn7uTvhM2gpc9cY6Yv1Z0lO+hI906UrCdWxcrpDZdhmoIYf8oxrSTlekHKdT/\r\nLhkEEuvLk4agL+QaHiWOO1wJrNywJXMSFZF6AjM29IYwHkrCQE5RmapW9ZLS\r\n4KhlHzh5crBoR1BTyk9Q2ficdx+dqydbOhdrM6bAOcXdzVQoQ8K+5spmCXIV\r\ni3nHBUL+yfDSfSTP2x7iwExek2w8s83dX1tWXkLXruQ9G0YrPHcecNmdud+L\r\nTg0xDoUvBRO1O35StHl0yYPqRgedOxE1EjrXHTXVcES7kwZpFwY7/lXUiZn/\r\nBtV5EivEyOHQqA7dk0YVhG1eBy1qH+eMkIo=\r\n=K2Iz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"bb1a39e78c30cda5ef910174e54d2c9708186388","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388_1669085404835_0.19159119499204635","host":"s3://npm-registry-packages"}},"0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1":{"name":"storage-mixin","version":"0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"f671b6bb6f3619dca331274dc75e17ca22f9c6fb","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1.tgz","fileCount":23,"integrity":"sha512-gXR1jwaVbaNSy+XwER7UsEPmR/09j93cH5ThrFPRrftMWMUiwdtJ0/vEHrR+5vWrzVgesEbSadQCbAMWgKXmRw==","signatures":[{"sig":"MEYCIQD79qNiacqG6tin0RUNF8rxurz/imBXewsBAp5vHEU4IQIhAKKuhum+Iv7VgBvEkflqgy2OyEFiPZkZpWA+fGDB9298","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDlbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoYvw/+OVM2EA4bHJxWrktngagjpMhyHUOVCZRDRh+UTHEdsj1X49Ly\r\niJPlSQQxWKkXGtBP77c/9uARyj/NrpUQ3Bhoh2FEiv73gCwUy51LJ8HA2Btv\r\n6IcBke4BRQheKMqgvKZErUsBlgTRB7vweX/GRVTNIoUYUEX7cBT/rY40J5Dc\r\nTrbQfOYH4B8XMcRwm3QRCab9c3M0TzoN4atNvcAaXr1e1szsht/m12l9Wf+d\r\nMxWW41BeZCTYjDf+1vhX7DLiVqCljJ9VNrvK/3npHBhceltkQjUrOx9kROzP\r\npn/iZF13RH4zaxfGWvkT9KaJPUthiuvAnlRB9W4S4QUMTa8Tgwh9AAb73q03\r\nw4dSmrO9dVJWE9ljdcwzPQaAZ1Zt0iqZTQ2OU7xkD8jET9/Lo/SNAQjTydkt\r\nOQ9KY28DhWiC4ted3bsdok3FrIVCxJEDQwU6/lGBhnkJNYM3JhHgGAwp701z\r\n+kNYN8yLT+uXYVrttG+efQMerm7nnc6fW9AUoUN2yFgxDDxiNMDb77Zquh+v\r\n6kEXJ0mgQ2uidHxcTHi+5kTwUVmuWZOmrfRePDRDPT9JoIjKdzSvnVy2C8ae\r\nfzLilxJ5F0LPkQvd1ZCpmwNEHbP0ugPohwLGyK4q3fGPgrmbzJ+PVzNw/wEM\r\ngpuQwAnEm5W+B5sbcparYhBt0BYGaVCJPE4=\r\n=uL54\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"b5a88ca5d89936f4997a6df7c6e08614f25de0a1","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1_1669085531350_0.750463146178683","host":"s3://npm-registry-packages"}},"0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08":{"name":"storage-mixin","version":"0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"2d8ee726b08d2336aee6f304c23a7a7e4f9336d7","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08.tgz","fileCount":23,"integrity":"sha512-eYNl5cFA4XwyFJ+6yGjR6JKSyyKSd5IXXHDqtpKz0wRI9TQi5pH4arn2FJf+tmh2sUQeTMl+6e8uqS6PpXdcOQ==","signatures":[{"sig":"MEQCIBDbGpX+7VD+UegNjhvlf+p92Z/Fhd0PkMKoKyL28/ZHAiAR+0g9UNo3ZG8W2xUvuaipFAqYq+dJRxjUVuiR1GqEHA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDsjACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr4ew/8DUxLl7h6Fqa+5kbk7CX1rlJzjJ+4iPOU6Uviy0CdJ2ERQQhE\r\nqLRQwAS6s1ERMit4QQgzSTEmlAVALJQad56a1iG/9uQgddWWizmXlo1H/UUb\r\nX77eg6T8pmBa9QB/co6wbsL8D8wqOmWFXzy/CkTYJCZtDzzLtF6ISyPZ+nSX\r\nCn9lLCRt1CxPVXy5hCbgKEgwh97awFKUgSn4Bii+Wu0u0mIjwTmXgBN4u9x9\r\nLGCQPUZpuuxUggWOPOcERQJb6UrFqJaqE3llvGPbXfMaXQAp4V7+G/uWz+a+\r\nJIk8iuydidMh5HltOPDxYFHcf2NJ/aVlioFZv1WRXSFhKP1wneJ8/vMJmRvk\r\nZMBZYQn7K7bT7Xk7uVlG48m3ZJyFrOoneCa4foUngPrYurm5mzSRaxnzP0Jj\r\nIki6EIPpUUlh/yJBof7ilBY9k6Cgm27o1fpmhNIRqWs3sbBc7neZ+6Ww4Gk/\r\n6aLpveTtoUXq48xds3+QpM+GqrRMXp5J2qMB1RUUp5VAjh6EEBiREH582t08\r\nmzvzUaxWzYWGL+81yPlqhfBWxC7VPFEJOW2iGVdMtwlhzdiIOWtjvsC0ajVK\r\n0p4MWVR5usSX27BMr6uzqtBC5o+2kEgJp9ZOIyW4mPghZnGVVdwQEPh5sdvC\r\nQaElVS6fZ/RXbkXR4tS94XilzktNhWiGst0=\r\n=6CBe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08_1669085987194_0.1927207333307155","host":"s3://npm-registry-packages"}},"0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6":{"name":"storage-mixin","version":"0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5da297c0b196ae382511abb98e2c531904a19bf4","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6.tgz","fileCount":23,"integrity":"sha512-/0u0kkS9g7me6yKqrZ2B6msiWMarow/lrM4J/ywjKUMqGzDKcGSwqOQKJpVCaS0WLlMbU8X1Lqaxo9/hvrDYEw==","signatures":[{"sig":"MEUCIQDPx3CCIxAm/JIFJsRYj+58Rm+RFxe4nFI4dxEYDVRE+wIgHQFOrkk/srnTIUuXY51n4U/QkVj26+3e78sZGefkqnk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfDxbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrkvw/+NV2nkAudEaXsDzsD+aJmr3MHREHa7cro+fJoJFBU1DU7X8Na\r\nYasn3V64g4jQtko9eYAjebU83bXI32xIYi+K0hgwhk36P/ODMHOkntw/CJd9\r\nVnz+YwUgbFpoge+sZrEgyg6ZLzbqQ/UuoBWE1jOzqDWrYTlOFJv1ltzNLvZ0\r\nQ12ePVbZkdcwreLnJl0L9UOR9mSL7i9S/ymjoVAIsSG1IvspZaZEmkD++dtB\r\ndjOUYQRg32YsMuJ9IeD5W0eTbHguUMTOMga6HlSEKjNH9Klid7sCPx3kAFc0\r\nHzAda/Us1MbKpTLTN2CcD8wyP8n9ubTuck68bnPSTHdKPoPjvA0jG5zRyJxg\r\nt8Azf5Vzq/F+lVNdOqHB1LXFsrYiWuybAGxBIdL3YH85xIkoU7gsidN8+JsN\r\n/jdqaIjqNPdcce8fjbnAUiJPwl21g9XgC1NU6v2jX2HMZ6GhsjMNSyS0Ym3V\r\nZHBlMnmLhOyynlviYH9pEHxRXD0Enk9SsG9pK6jyoKPFA7lzzJ7LXSf+uCXq\r\ntRf0xO7ks3fZQ05XMWlXgjo73dJPKEmBbVU+EX6uK0FxIoNuF3VXP2o8dPo5\r\nEvS1fiY1fT+j6SdHU7f8Rt5+P4KaMBNoDGMwan4Qrc6Qii4rYBh9NAkE25aw\r\n510Y6y31x6VERqBbjBvRUJy5vuXI1FnUmaw=\r\n=e0gK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"2cde0fe836b81baa0f68d274840a5f97b8dae0c6","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6_1669086299471_0.659444846878255","host":"s3://npm-registry-packages"}},"0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a":{"name":"storage-mixin","version":"0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"790f5bfdf67a9b3c937df8a3dfb82ebdcb5172ef","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a.tgz","fileCount":23,"integrity":"sha512-lrHH87iNUxmVFDcwRpr+apjIkkTqZSlsLBgZsk3idw22ke6zNuqK0qwZiyNZLEsSdUoiNV7Rb4vl/61ptre7ig==","signatures":[{"sig":"MEUCIQD+rvzRaCkskTslZd69w9ZtZpX04j8/no5a4g17M2PjwwIgIQ7uzbS3t2hVqIzaIPFnk42b3mm51gvQ1Ho9FSKP6oU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfXnAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp87g//VkUfv//WA0+Sg18gD62RWXcL7cTWNTsOQgODBq1KVzEmS5Ou\r\n0urgBUrslNv1gapCfZMt2EoHJjgEkpzA32EKpFDrwzyypS6qTVtGWtV5nE7w\r\nhPoedFR8Whq8d4ahzBu9gec3D2AGjTN5k5n9suRBX9mwigoS3oM6Siqky2Ua\r\n1KcRULDR67piQfMZnWvXeDX1roBAqH14wIEsXIa/JIDZgq9MIyb2HuFVcHHO\r\nP23OQG2Kwrsd4s89ZQYgVr4uLeK4wSTT4nEW83LAeZLIELT7nrp02Y9P6UIc\r\n1GOeNgVhTj031kamEpAEnqx7QdoTmzMfBD+suS8QQ4Yr9kxIo4V2Xsm68MZf\r\nSgkv0Qn4y/+7LASys+jcpjoDB5QrJUasBa+Ec2s487f4MGQ+nACJnmD4wII2\r\nMReIwZBDhAhgw+sx4/5h+HX7qEkmglMsQBtVgRKDtB9lFIz4qo7p2RLEDCeu\r\nNEiz82xFtPRaTUspvqY0kWEaw4LozHRUoxc1PsqrOdGUD4D9RPClm3WbQpAA\r\nc1biVANn1Cg/YKusXOfUKjljguLMU/6UGxyX5DN2/PQ6/asBf1GUTojCloMu\r\n/QI2ukdvZTS3np4tFIUTOQzFmTys+dYAVOpZWt6TIeqBeBHrVVjYQsGaw+cR\r\nOCmJFzwImmTyL9uOP/W48Z25aeoJrK2lNVg=\r\n=7b1U\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"feb0121be4234a831e6bce640173de34ce95dd7a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a_1669167551781_0.49240696911410686","host":"s3://npm-registry-packages"}},"0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e":{"name":"storage-mixin","version":"0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"3e20b359408e9c6545ce500b5944106fbde1f9e2","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e.tgz","fileCount":23,"integrity":"sha512-hS2boW2VNGcDEblX8xr7xMldlOWke+LS2gGqep54TPFsMuKktdgZmLrWkrWvmz2DT0JcMg7Mpwrziu9xYbxwHA==","signatures":[{"sig":"MEQCIAbOAyV/U7YyicHHDhXCYkfZ3Ia+0fgzynHw+GkVlNbtAiA3lvgJWYzDMyp6nxMkz4QdGTtNdAHJo9rYyJ9uaNu2Rw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfYJZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrmyw//bB2+YAIDpMrhZyQbbzsW3lHAF1BYUujzHmy488+skdWZ/I6T\r\nE7MLdGjxzL8BnWZ4mDL1SeDH3y1LhcHq+gHf5NIdReViaPO8EKHHsXtVz+jA\r\nA5gieE6XFQHqzYHILFKioDHadudsJAxidsRbGAGtN1r7pQG3kpFyzMmK14Ia\r\nW+Abpb6XpJALIu5rh7AGTMCyMdQNR2Sx+2+PcrTOB0Mplcir71B41huy9TGY\r\ntIHKyL3MzFUKr8VsDdRG1ZR8VYTGitmLuAELFtbequF6j21WbrJwfwogk8Ib\r\nQ8PBGeUO3PvkcGTd4sIhaBRqKdIHkj8kuDoB6VtGsEclEgsNpI/z/wMaQcQo\r\n1Xukw/S6034yzXQd1hrcTNg0z39KcDZg2HZvlN1WY5U86SGSOchksqsmP0di\r\nlZi3fOntgSipqE+E6X/vFY3WWfFDkeKNZEatbBvALH/ey73SiuLyOGgBxR48\r\nr5FUnjafDSoVjm+/ZHQGniVsgr2m4vW747DeBItSQGBVTFlK5SrxwJGjdqtn\r\nICT7Rjraexxr3HZL+xQaaABifOAZL5r9mUL3G3DyHV8MlKcMYk6kWKf6ZuKi\r\nXX6jP3n8h/nhQMrBMX6iDlVlV+Ne5vizSgSYh73yAgHzvWMFK5HwBF+sGzD6\r\nSdQyBEs95YEaLK6LOclb48d38c9s80aORYs=\r\n=l/eD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"64ed9e6634006598c90fc79f71c554ec401bfc8e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e_1669169753479_0.59237415784317","host":"s3://npm-registry-packages"}},"0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83":{"name":"storage-mixin","version":"0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"28abe8e367d7733613651e5344db5fa4606abfcd","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83.tgz","fileCount":23,"integrity":"sha512-3v/sXF1En6nDNRc9kxCX+64hS3X7+15nmlDF6eBos47gb2Ayx89ccMEVT/fLyKI6Q1rWbc6dsDz+k/UPr99U/A==","signatures":[{"sig":"MEUCIQCdxjVJrxNf+n44zg5zT1d5kWQdqEUdtNK2l0kuGCqcpQIgf4QVnwaVzS79atnIeySlt6JHK8cDde3+1i85upjc+G4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfuNUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqjfBAAmQTYMhL788vgYUuosiG0SrC6ZtldgZdILLd+WMN8axAIvTmq\r\naAXYU1pHFIKgF7o2L2gn2wE1s10N+dkXQ7EHWElgWd48PguBIf4sKZufwJyK\r\nB5W9gcM/yijHTEbRbOb7hsjzQDvSqyRzwNN88rRjH/7WWlZGTAr2w+aYSsc+\r\nI15E0PEc/DbFiNQcIepUk7KUxA9U4+24PO7yxyYBtP6cCnRuKaL3dqQzSnqf\r\ng3z7A0kcgwIWgFqYRK/ZB5rw4guOM9wLuPuQ95dkMM0+y6dRdPR71yMbksBt\r\naWQzyVWbR3aV+n1+FwUeVH0qe7rzjOYqj+60lMEzaZ61plGrdCpIOp2GusNf\r\nxvwIFOuJi/xHMffi04wzkzR1p1vJmUtIykEFv/YXU2wulrwZaAOyVt2Lvwlx\r\ngCHs2eEy77NHFKQW1a0rnYQqxoZSu7t1zvjbYlklgznwaJJdtuhK/IuYK6B+\r\n+GuE+c4oLEarQ3ZF+JFBTSZAVzSawZwHKyZIq2BFbjhxj0vefzqV3CJqQtL2\r\nJydpzRbfCGIIqjAS5JEjtj2pMGYRBjQVloeARwPmz7zxOd3EXNaulJk8MjZT\r\nm2tFLBSUh+2CViWv1euMdKF/55G0pGawah+48InJW7mguJo5OVpw+5Y4EbaH\r\nyjf0DoQjchBmSUjAmt8kFaaF1Fa/1gYBcY0=\r\n=ZDMO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"a005ee4428ffd61a00127102fa0c29212a52fc83","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83_1669260116264_0.3221793696984345","host":"s3://npm-registry-packages"}},"0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34":{"name":"storage-mixin","version":"0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"fcab4082bf74384210d905ed36dfe5f726406980","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34.tgz","fileCount":23,"integrity":"sha512-U9fLiWuRs2BozZQHMkscvt0fZy0lh3nx9Y1u2ltknNo/kS+fjysP3BL7DcwH3Ihb/GmAXbDUqV3v+A9n1bT+sg==","signatures":[{"sig":"MEUCIQD58ve8q69uBSXLNhj5drKBF4nQPbeAkbiEZq8a8NQtRQIgDpABDUBbaHxpvT8Q8gEFb/XkIjPxUYnsPN3vJkZdH1M=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfuaOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoftA//Q9xvQGtpRBDihNYgZXdKWvuxbE7Mcmtyu8SG5WRN6ndrjSIA\r\n8ToVD6QfkszfnjuK0XDO+74jDT/2P7KAlTsE1ZmDtGGYTbFxrYfr1vVOc0FT\r\nIWxDA29o82y9Ga2h6eVm/bAXTbE7O1IL6qawFtgbigVNXey+W0OQQM9jnE2m\r\n3iZGJdyj+ZnzYNnWTmEucwuefLRHG7plIBMo3DNBzVZSBJRqgXqWlXlqm+Gk\r\nrYK4ieoiEXVOUHbWBHk3DXxU/jRWYUcHTA8xLmCpaEj2dkE2dqt7JH8e7m0A\r\nouH4z6y6M8z6rYU4C33h5ZLKSNrTqZ7Rjq6pPXmm1GaK3tEc2cPW4lpZfsha\r\nsWUbG/897NtuSOZVlwxbqA+0XOLUEGFhq+/t4o7D9glLjPVqGiNohIsLCaiE\r\nMiw1PBi35p7fh/l1cjqTCmcl8wtLz6icZUb8OXu9V6tn1UeGD7XY8BejPn/X\r\nNQINMZzOqSCu4RlQQAdHkmUVqh7ysNh/1Iu+eTtFGlwxuwh6GDG6cNFG5uFY\r\nwvTRaFzxy9+j15fP3aux3t4lXKJYL+rk7xC8F9BRplDOV3yRu5Hh3svTeZzh\r\nLsYKbh32MhiTg7n+vJsaCo/BZvzXre2pidZxYnybTJkcGQx/kWqZjQemlFeR\r\ncQ31ld7eSXWH6wwPbzaEd1l5bri9NSqBW2Y=\r\n=zLzq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e06434c386fd387cc5650fc9c0906b46cb4d6c34","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34_1669260941892_0.08957254314130458","host":"s3://npm-registry-packages"}},"0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896":{"name":"storage-mixin","version":"0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5eb942b458de25df6b13c3d6c549baeb7d539316","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896.tgz","fileCount":23,"integrity":"sha512-OJ6nhMMDpfZGHYcMpuBXQOR6E583KVFIEWLtwvZtNai8Axl28yIivcl8zbQZx+w7neDNFuxXZyIGn0/nirr4OA==","signatures":[{"sig":"MEYCIQD+WZ/Np3kPhqxhasLNxZJT+AhNSTxSSz+ChQvdtZHohwIhAPOyw5oZ4WIiaD37k2utDgKv/mukuccZyrPKrvjokm2j","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjf9HtACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo1BQ/8CRKwE0pQKV2PlNfsDpgP0gyNTAf2yyhYpjAJR9s0qSIeXYn4\r\nOI+2u6yBuvg6do3aNqwjqKu6rOfsroFqg0aJAFgWzS0NqrmRiCb1ephLICnn\r\nhg5oCeg0CZfUJxS8NLC0KkFIf98tgQQIUqvGTFc4FAPvara5FITfeXHhdinX\r\n6utFrgpC5AFCTKlCJRVk70dQga43VoWNGpkZgOx/G1rxU5X956mBQP5TQQRo\r\nISc8d/tV5Kwh/OuzmqPRnpJMP9PXuug5H6SNIOky9wo+XYw2UUoEBvSnzssE\r\nEAU65kO3r6h+k+DG2/HJ3AHRhvuc/wy3+t8SuFD+QXPkOp3sj0eAEr1Awbl4\r\npG5yqzN+0P4r2VNRCESkF+w/C81P+feOPm3gChNbJfJnjx4kQm7sRrYlgtc0\r\npS6qBxNCh5ZH3PARV/ntdaZf0tkLj88arEUANMflWVfHxGmFCirk3kZGsHtA\r\n51J424q+7nrPuo7f//9r4Kigydi/6AiFm6aeYrd1JDowyI3pfQL1IL8EjAwr\r\nFx2unrQG3A2Nu24PgT37oVAs9X1v4X8Ls267wp9VTU9bBoMzpCdxRRAGst8j\r\n2JZbXVGOvBRPVFrXgAOMNN8eMfZpUyOfg8LPFkhmZ7ZsMRUAyaeOYUhyEhHe\r\n4UNkbY9hu4biFm4tuCaann+woUKj4Z7nGa0=\r\n=oSGB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"8d44ba9084fbf5b834ca7df8b77135d3c8fc6896","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896_1669321197338_0.040986306131220784","host":"s3://npm-registry-packages"}},"0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526":{"name":"storage-mixin","version":"0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"0c6aa927306c72f6895721e6e6f1a325acbe5d74","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526.tgz","fileCount":23,"integrity":"sha512-lsV4j3AYy76hIx9XZ3Fps/ipNKm2d1/QGPpnB2N0l0vu9oYosbU0BUrhdAImgAz+nAQSfsPSGx+Pf49o6OtG7g==","signatures":[{"sig":"MEUCIQCLPBGfxPObwDqDvWAe7xN53lELIC46NRGMiVitpv9sIwIgEYTAqbrUmbhFS739rdRR5HP22gZyvqKz4yJ3kiF7TRg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjf9NwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqiEBAAhjHW9Ep5+arNXMst1MvKEBIg3x4JD3i3cgu7OL+u+1ob01QN\r\njnRzjs7vNTw8iGU+dV0POnOlgIiSF9kzPRlYGaesa1s1gFCObVt28P57HMGZ\r\nsMhoEtOSnthNXuEFBXeY53tYwy1GqIJ/AxugskRekOMOmjMzLufwUINb7iDX\r\n1lpja9wPiZ9fccVxZQMcxcCecuaMhxF0ZoB18J5T/4bXLy3Awbs6vY4l5WH6\r\nAjEMOy7S6UPAJixAhAdagZ3HSPWKYOuFhA89dZ0EYduLKeC4CD3d636YJUi7\r\nD/8KL4fGTdbzTOrkIZIYdIeIAywYTWtIcNaZ4+jKEdjr0PwhH0QfpYmgXP0E\r\nQ2ua1pOT4+gZOx1gU9mx23Z7jCQoSPjvAYRThDrxxUuMI9Pmsca10PrugIvu\r\n6xltcosqqwMcF08zwzZgVvO3ABQ9dog4EK+frwIgQ5A5wrGndrtP9V9npVqw\r\nQDkqDY9lVdr//wh+l1HUjr9t2HYGnMbDDbET7NN5G7mg0aSmRyEVqBj+fdzs\r\nNU+hG/DXD5zr9FeHeWPy+4UnPIf9aW/vqhhuh0l4pSKfmDAD52OYUYvuTNIG\r\nST5FpVoYpL6E6lW2rS2VWdafC/qqMmQi4GVfPPS93gzrKKlP/7U/vc2xmnTU\r\nHb1dDxXFV7gXQYxdCxeTKDqWWpCKEp0a3Lw=\r\n=STXP\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"74685ebe9d7b81dd4a870c8ffd51152622741526","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526_1669321584375_0.88186232708153","host":"s3://npm-registry-packages"}},"0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278":{"name":"storage-mixin","version":"0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"af997c80b65bba8868ed5dfe949e38dad56b69e6","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278.tgz","fileCount":23,"integrity":"sha512-0CB5h9JucukNLAznUIIYaCBBj5o413wt/tgkkTwi4OXysTBkE+09yJ5zSmEgST53xJE5s8yPdP1P0pF49K9ZYA==","signatures":[{"sig":"MEQCIAQBVNPgnGD1JawG2MPx52iTh0k7f396/64WSzw5oZ1uAiB6X2VmDuJp9+GXYJhUH2U3Y1MlDelTR6vNOQzWc+dvcw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjgJJ5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqIXA/9G0cc1kZYPljl+8uVqFo2hjDxsXnyN4CFJFt9jNLHEVzvN9wa\r\nxlS3NXQMJu47oIUhJFnc/+49NQfleMRiHTj/GCQiMoxJCFyITr4IXLwN5VEO\r\neMz+uhOn7Uix2W7T2FPXutX8T8zXK5Yg3WYtr/rv3lEd/EM3jBkeXNcNuoR4\r\nWNWWqPpY3D+5cWDI5O1LeJyyQEbyZ1lLMEW5UgOVEoPdYHnOZomyctaO4XXR\r\ndLiTRFzzL2ZKnEkLcnVxdYL6dJ42dSNNgwWAazIBYdbJvViWZfAYzCgBWC6Y\r\nDOHPn9/T+o2OJ7QiEyLNBWn0v+6FtJqWSyRN2bZMbGRL3vabUgC4zplaSsCK\r\nk58FsmVNQTObZd1/ZHwG6da9VAKeqsVCpP5rhpB/M3FsDpciie6oTWMvoJrU\r\n0BXiSiYokj5VOmp24fhezckH4ZIU/WhcWdYfEmfnys696P8b0+k43EH+9nOp\r\nv/dPWvvOnrqwEfFRkM0SiLnVbRdNEq5SJK5wTGyU4bSRqMIocTPi+q8EXHoK\r\n23sMV5MuArMnf/+CzEVBXSB7yrRdfgSG9HRsaCKghCLx+LXwpHOK+PAplQPB\r\naL6WRHBaj2yKCcM4DC8pg0mdtFCk72XJEmx8ig216EiCSDFaIEha+XMmq31C\r\nZ5J59YQ7j5E1Ezb9OCPDR6Ga142/w7RjZ2w=\r\n=h51R\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"92270b35885e90f6eb7b153275848f7a2be21278","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278_1669370488771_0.4181138104458071","host":"s3://npm-registry-packages"}},"0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c":{"name":"storage-mixin","version":"0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4c95f077ebd9e5694be8fe846dca12cc74267374","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c.tgz","fileCount":23,"integrity":"sha512-jCXS/3WPYP7kOyrEPyvmMdvcKb35zIDXUfdvx2lmIR/B3Ow7u5TJc20ohWwwmeFuPnEVa+lxEXuX4JBg87J7FA==","signatures":[{"sig":"MEUCIArrm+cj2nEOHKIPe5l44Z/9xat/PgWk/NvAsXk8gNZSAiEA+G+252bqDoRbzXvazagj3YTaHcKlg9oFKZDF0hp2444=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjgUX3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmocVQ/+O1HyNg7YCwaEk9LN+OTUt3ca988J5fzq/8P964xnqplahjj4\r\n2dFGuGCw2VIC4TDiEyfEgxV7YQll904fJ5hkM4Vv0D6ayx0MYm+D/W10EwRR\r\nGtvXUBnjX2bnj+IB8JR0WAixhUdy1p7me4tplmeSmJerM0tb63W+DLGCgKPm\r\nSmbC7e7G/pnEvlQkD3rUT/TzC8PEcz2kXrIc5dJq0Cv+nHbrYGd02KWSVZBL\r\nOI2Tug0IqtfnmYzn/NcfUQ33DSBJOczAMTvpxJ6WYCmQjOl/vPjNsK0LEGwY\r\nkDhK/4GQRfk/E5wei2Fi62xvF8bucFi3s0luc5j7JYl4+AwI7t4yigt4kEnY\r\nt/79rKAiHbiNotJMjk43BQ5mOgJsS2xbYR7RM5A+ten491/wTIcZucgwp0fZ\r\n2t9d2jUn/h9h1Qz4n6dZ+AOA293KLtIKCWWjr9z1IdaaKpLi/3PG8mXeNuUv\r\nHsafFCv0gIEf8D73apo7FCHdKoKxrcIOC47W6GJbfdhEMQ0LlBRRoYFuZQxu\r\nHOvboNE4+DnuTEXJbtQlokUr4V3eEnQ8rTHZk95QWC4xfQnK99aLd1oWp4FS\r\nVeqkcKREcZ6HYfmsO+KKSchd4N8ziOAVscsUdK0QT2vEX0CyoCbD1kI4/0oe\r\n4ya3P3S7M9pcaRckCRjOz50MMZT7ZucH9tg=\r\n=98in\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"f9347a106881d77aa4b1f7f37daed25d73c5f92c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c_1669416439794_0.2731877615634435","host":"s3://npm-registry-packages"}},"0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f":{"name":"storage-mixin","version":"0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"b22375f665375cf21c6d19f32a4af8f38e66f858","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f.tgz","fileCount":23,"integrity":"sha512-B1YsAgN41FiKeM3lNVXuG5V9TSky969qfMTuOBIzgwwd4u40Fsc5gp/Uf15JI/7nykGmt7L4zXgSd/UO7F0QZA==","signatures":[{"sig":"MEUCIHXXih4dsS/4ryFqlHByoOkHUIdRdSw0Dc4tJ1/ctGjLAiEAgU05Me6BJQuZRLaddr/LrPkU2h9wy/bWZawgFPuMIcI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjgVQ+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqU0Q/+L+C0tPZRJoE0wlVveA/Ez+UlyQ4MvCuhGU5GJl9lobreGJug\r\nF8g3rnCRJKaTaIT290hYFHj5nQMSal94hwMfYXkEbz7OmHPnxkVtE9rl6OYs\r\nJLODTugIySDA6ax5l/2WWd4S0JEfkuCfH1ew8jmv4M332R2KgiDuGB9uTwqQ\r\nu4F9U8wA9I2vDLa/cCz7XzRLMpkzCpVOvq6LauHcyqAVjINST0o+k7O42IIh\r\n9e7BrW6rWlJC4lGtnKXHcSxjAzlYGAunNuzwHqKp78XwQJPdBm31iR1Bher2\r\naw6+zvEWk+XMOODHRCbGPu5Z0mrAz9mAKonzJo0xoAWe1Vup+BQzRkb8CXsp\r\n8zTmy2gpczsBF4DJ55/giGicU7fS0CPIVJei23tAXruebK5JpzeiVihTp1z7\r\nvAzBU4/y+GnfE1kBN6+HSDRD6C40VJz9ReMwt4uWD5eowqU8FBxjU8yEUTD+\r\nEI0WqMoMDp09y4CZ76v1QhDGkB9SwteeYGJNKY2lRQLhy+jHIhlZvpJeC/zK\r\nrsVjIuKQVtekkah14dF1oF4AidYQXRAxD58azUBfUHK5jpcU3aaks4qbaPkK\r\nsVPM3NM2kBosoG/s9oj/kpDJCTa2ZEnTzU+9YHBojUQN3Jtlj1nHbJhkPbCc\r\nw3X+EybdzB120fhAW1LjOrAYWbXsXV6kkQQ=\r\n=kmlO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"94f03d5249971d1eea1868df296db6e766f40f9f","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f_1669420093885_0.23750348735113525","host":"s3://npm-registry-packages"}},"0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1":{"name":"storage-mixin","version":"0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"049b003e5c91d3e10a7f206edb481b137231b542","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1.tgz","fileCount":23,"integrity":"sha512-CkG+d7ol2APu73Yt6lhpYGOnuu2p/5G+j+gyVzqf+jxsexAgvhseFMMezXechhOqrIm0TcHxWdR2zR9wPhp4rg==","signatures":[{"sig":"MEYCIQC0ldO5hpugW5Ju5J+jLEcXCCWhIIquw5IfGP311nfPSAIhAIyi2mPwGZVtcmWYhtuWoa4If1AUNU72lsVHOO3/xEPU","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84836,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhTGuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrJxxAAk4HwuhE1+b6zDGVEypQRUuIWqYOCS6ZqGD0L5ZlktrVtkYK3\r\nmnCmzn5m5xTh4e/DNBS8hDSqdyqM6EEhnVekepOGpKwRxoQma5wuuKMl76uN\r\nYf4qZJwbU0NCdJJyONpXZptAqv8mjdrFWAsTzLqG4VuDP+AAtXv1BTex8Fyp\r\nuO3UBBm8V7BZAjTmvUYsNxHbAuekpNcN9koqthmdkLR93q+E74t1Y8gIar+O\r\nPHssj6Ds9uRnDw2c+mBIEmn7rprDeWjTe8eB6FxkgsKQr5TPxSqJrP0vDt5V\r\nD+STMEQs3zOiYrAJScDm8xRBWQPApG/+I3+arMpI+aO2DECnXR2M7GtsGft0\r\nzxHTZ2RAOD/7pKEU7YKjA5BilTWR8h5PlCupWZFWul0BQJX759I9n15Y8WhN\r\nd2qUlvnNDD+ND2inOr6FNm9jZHpYNT9sQW42xOjfOLJYmaihDO9ZsyLOcSsF\r\nX/+qvze4bjOFalrOYzlOZlN4fvJeu88RJVXF0MnvhSmxOIqTxcqzCoWVebOi\r\npSb34BDOQp/MM2g/Qbg92T6WkY7I8qpIXq4r3JV1LKz4KX+lw7viHM/2xJKj\r\nYJZN1+w5zs5grmOe5GGPKbjOPdJH93Xmshh81vKU3/5uxUj9Msx+eyhILm50\r\njTm5HQmgOWhLrd9/Fy5AyRrmY+79LFlT5DQ=\r\n=l0Pb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e3ac63bd187d674b27865523c639e78bf78ac7a1","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1_1669673390301_0.5785318841607077","host":"s3://npm-registry-packages"}},"0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899":{"name":"storage-mixin","version":"0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"11042b6d49cb0f2a312a70c91979ea98c6e8565a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899.tgz","fileCount":23,"integrity":"sha512-giiU8HDRrNc8T9sY4ZmCEUvWM8EFAxoiMqGMXGZ5/Ujl/VajxOGoHdQTzS6fUtti+H+/3Ga/h0YldZ6JUP0+Tg==","signatures":[{"sig":"MEUCIQDQp6vVyAXjc/7v58vSO0uC+LM4We7i/4Vx/P+BactafQIgWUi+7jihiChKt/DI+dAXVxh94OpcakoPYSqmcP1LqmY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhpc9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpQ8Q//XRFHN0rpBF97VGhbohftdtOOFWdpYY3Rl83G62sdG2nu6FY1\r\nBY1UCQSEsdB7ilYCNxhnGEt0U8+nuend1x4SJ7ylYf6rbCwncksFykEPGlM/\r\nvPIwcuViNpZdqSsoGGFEJHxhK5enT6DJFqzcFGdVLnLVUx1hI4xXeb2UvLRy\r\nKfyLegsOV3fb4aytQ9bXP+e7YIqE1GnWHyEPTbsnrZXBrczvbFn7+Da+QDRG\r\nn5N6sbHVL77ptrwccBvdzNwtSe/46h/dLb5Txqnqq+mTCruvfBs2SNS2pb8W\r\n4wO7V8YZ6kGJ+g6fTDF/RkgRg8AaJlyTwGaCDDhs/qvKUfXx2kc8Wl+yzcAn\r\nuOGdZQ6Kn2xebUb7UYqknSdmp2086K6PM4cGFd0XkXbI5rD1A4lO0NwVRcQq\r\n16F7TgV080jS8Uw2FD8bUZKhApUGYvdvZlyza2BuKALeVN6QXX2bszkgYnVQ\r\nYrQoInqnt7cWWcaLKaj8V2Qqg35tBgkW16Szldb23lnKZ05aF2chxO/ylxBB\r\npFUjBmtPHSy2RzsbLXk5NpbJ3m00ZZnMJGYX0GS1V2N99jq1v7NTXBEly/Sx\r\ne8cVgDUV3VNzmcDWBeJa0rBv0kNeR0KWQ0EfG58UcFd16oIZabMuYkUky549\r\npe7TCO4rfepMm6PhIMelEDgO9eO/nubdDHI=\r\n=tdua\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"449f5b693a70d24bf653fcbd3719d8d88d91d899","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899_1669764925388_0.8866455621734863","host":"s3://npm-registry-packages"}},"0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a":{"name":"storage-mixin","version":"0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4de50531b66aab67fee82fb21995f953b297df1d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a.tgz","fileCount":23,"integrity":"sha512-2n1Fs2M56iXYo68J+px1tWO3cRJImyY3vdQO/hx7XlQSEL8m3w5pgXzEwK4DL2gnrMP1KZ/qdCo/OqNbN0E6+A==","signatures":[{"sig":"MEQCICzN5ciQQW35sODPbtDWWGNIEZIe15tKorjKEzDbCLXCAiBZ0ai6V5XEeE7OGuKja0afXd11S/kg+CvVM5X/QPPd6g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjhphIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpxSA//a42CqpbIeR4gPuODKRmw46rrSEchml6J2s/tXmAqrBFtGCns\r\nQNnnRzbgJmIgyXa7XsvL4OJ5ru3k0WoJ6AoICTm4v6CJhNHmdaJcH4Y5GMeD\r\n/jg0ioBlyuTcLLLTH5h8UwgG+7rLTYJpNZFmRh0ziPi91QBIDRXNPOXpA3L0\r\nfDI10jyBQzcapulC58RL8AQoabKGkNEoUEQOKLkaeRvVnm2txCKUdwp0J0qJ\r\nKI5yH+oSv9pUDK6XD0sP2VOG7AVx0+sHH97JQaj3h2KrmKvi4vrsfiefhfTr\r\n0j4lUfctkVFSrqPfuoY4xZVwp2uF2b2+ZDXtjVJMlyJALRZH5hRpV6eSLLM6\r\nYQ43EHmla47awHoSsqxx/m4VlTp4Dn2SaNeKFbjAiZVLqQ1jDOn1YPDhtFFJ\r\n3vj/8tiFoOKOJPqOE2+I//vq4QSyZfIQZLv1rh90qsfI6kXlwLIRBxw1yUKK\r\nJv6AJSkPr+tT7ASMBbt/SX3SdFffsz28Prf8LQzKuRg/xNhXewj5En9F0UGq\r\niXrLjDrXwUGlqsy4xvSHVL8GMif4TySo4FHmi17wNBDpboM9rBMADP4Cspac\r\nQ0NYd1BurT86xEM/vwZcMVXi1/HuSNaVGphi+vmqroyy4HPhQDPhajs0KnOp\r\niYWQ7q1BHtA31U6zOWGgc2Eu5vCKmTwZ7Ps=\r\n=NgYo\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"9ee9b0963df24390835a677f1a9081d9bc53ca2a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a_1669765191950_0.1920379963555392","host":"s3://npm-registry-packages"}},"0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0":{"name":"storage-mixin","version":"0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ad20b8cb924599fa6b3c294d8d5855b8dde0750d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0.tgz","fileCount":23,"integrity":"sha512-PVk8xSKd74J2ENazIAGRwUDnv2yrZcP04ClQ/J/eJReZFI67v1iHlCN2Pqql8Brg3+r3+HkbdOJv7FxnkP+hDA==","signatures":[{"sig":"MEQCICGRZlQvrjzXeUMcLg2nzphNgghTaWDluqYl7ZBH8F5tAiAdtbeG+ws1cw14Aq9xWLF9YD0bMwPaiHl5piCq39a6zw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjiHgUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoL7Q//RFK6ymgbnhFmYXfqaa9M546SCn5t9PuKj/wzSDICkZV1jZwI\r\n1hTACXvw1/87CQk1lNHPVZUhaiOY2Fg+D0pnLtH5NnpZlOqvXwxnefQWtEW3\r\nrZG2j3VLU/qdGh8gS0zuc9zCGWcU/T9OS+Jlbnno0zHNX0Ia9rnMHv1ZhWK6\r\n0YXAvI1LxF9NATxNEMwEeZ23ZJ6/LWTZjpZWaS6SJwV2LDLBxigaV45J1SiV\r\nQ7/YApUZVvRdzxG39e2sheKbOAScBHovxImbUcqiKuTCjUGkIiTUffwghKDW\r\nj4o6+ul21BYQ8BRRJxx6/jjhBHfdH7P5eEyGWrchdoEK/gYe+iVziIKheHbN\r\n+BTWy+/AzhygUHqGMCggV550bX/WXIQheHYPKNwGkjcMaJsC0FDl0BEGRZHk\r\nyD/tul2qv88sqz3j0xscu9h3BctLu6UhmDtcUHEL9Nc5EtS9YCAEB6kHKtqm\r\nbjgGdjhw/g4deV6U+f6QaFt7X3RblRRHyP1P+APNEnyoKG9ggZbAAhGZJxeD\r\nmGzse5xc1ERmuoJSj9Uh8PFgQZ90oL2a6ufbiuDHZ9uH3Rgx1pqA+gHzd6CG\r\nw5HTfmJKApDu9kdCPuaDRoGFCQk/pbQcF5YqDDym2nberbMsnmJ9ZC1mXeqk\r\n4lRMTKGb+dtM1RHrIgN4vhNsknvR8QF5Z9E=\r\n=osGb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"98550b9ab2651e46658429899a0b7353249a18c0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0_1669888020304_0.7865221986951925","host":"s3://npm-registry-packages"}},"0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d":{"name":"storage-mixin","version":"0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"30d790f3b1f8bf492d59638f86d01a61ad9a756d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d.tgz","fileCount":23,"integrity":"sha512-Fql4Oz1ZRc1fK5hzeayUJr+WoGvmWwOV04bHWE7zHZJmseldr9ILxoHjjD3F4a5A0lMDHwb0hpJqHwe21MNLyg==","signatures":[{"sig":"MEQCIF4ITu8ocy5NgK204gVQTBflOsid4iGXb+/74lS4wqxaAiBP373wnkAOMXtwkyQz0m7Nx5UT4Me+vzqn9j8lLhQYeg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjiTXkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoUcw//fKkppKuEnFKWapVQ4Prta1rUGK9ACZYXv9BZFkHc5i09fXlb\r\nHE2TOMwnmclVOYgCwCgy3PU612wAi8XBBf9jWDyuhI/xNem3Y6Cf4bz/oFlj\r\n+1xz9uAfDow3UZEmJif2jnFA/K0LFzsc26urYJ1uMcwfL/w1Qwf78FvVpZ3Z\r\nlp3fLiEq+4nRWf54OhFBLCsSj3u8taNon9KKT9u9x7Rw9mNm0mnUUobqkN8A\r\nc5Q01et8lJHItXmEiqJxDKhc4Ox2u4iXNRStXX3bz3EZvs93vj5k5wNZ0HbJ\r\nztr+cOCBiCOD+E+qn9PqK4Li3j8VuDNqDPYtBlfppTKLSSMXNUYQB/wIbNEM\r\nkDDLOtNC0L1ebDR8+Vd32/6jZHFX9qOd9YjQ8hJYw2OB00J8x1g4BgRgcPHj\r\nrmW+8doTHUUzJ+4EKyBRg9Xt2+JFk1WDj/U6bQhNy5VftHnXL+l80E+OrZI3\r\n6RDnNuw4Gx8dGSIy74F9Y1iv9kXSW8NvPZZsSwtFvk4WmO4MNPlmguIy53H3\r\n5VfDvSlWor6L5PRSPgI4+jM0IC1PQu+KloulgIY3QZg3yLHxtCruM8KV42WK\r\noRacmly10JGiUoITIcbTxBkGmsLt9zE/kfHd2jacCvA/IqolVC0MSks1Tams\r\n6XmrmXgEaJ+ixILOOkRqySXWg8DvYe/av60=\r\n=sGtW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"f5e96f4dde195c3f4c44fc6c373583df1178a29d","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d_1669936612601_0.29512682940882473","host":"s3://npm-registry-packages"}},"0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82":{"name":"storage-mixin","version":"0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e83b2e228b282e0ae5118d7947503ea5cac89934","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82.tgz","fileCount":23,"integrity":"sha512-+DlP8SH4iz2jaKmBygb6Nm4BNIGQWqcO36vb5z2QTQCL3yxjFESs9uhavsHnRsZUns1cMcpXDIpdf7xEmEfzLg==","signatures":[{"sig":"MEUCIQCAljt98aOR7WvN4GPua4GWbzbQJzbjVaF8wIVIinf59AIgdXEED1TZWKNNnOG52maqh8RDyNuyez0duTUMYv2B7tE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjiTifACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrWWg/+MpNkCaLPFNzcxyfkyQOpC+08vYOu22C9KgIEOXRaUeUmOkSZ\r\nXze12rmB938EwipWyIDLuSnBswppe94Scgq6GIBapOTi1E8yhJiWZW0mHj5o\r\n7+EOlarwMDdV3vA6j9rQTW9+AnATU+wMDsr9thJSiQBFvMQSI5TcDtIDEAJ8\r\nj9KCB8aRU1rY+e74dDbx/5urKGO67Q+C1D8IrE/JgD6sTuPvPWvGiFaBrMCh\r\nQCjSwxQeeXFANBjLaWvX646di1fXQmxskw4Y9PfY6A9+8DEwU7OUcPBeFh0I\r\nbR9XOqoiHAtDR0IPSyythu6UMxzhv+lf5aXizE8QKhquEuPmCGNE3fq3kt9Y\r\npF8oXtWhx9aGsTVQi1W0EVedVZd1Ki4oC7aMSN/l6f6utMIxkinTFny0hvz4\r\nReazK8oTRV3bG5ldvsxm30YLZtG/DSS0P1QeCBC4e3ANZOK7znTVbwx7hZBF\r\n1091oaB3cu9oQhRi17fY0BGeB8WTvJP3jFhoCv6nl/DhSrVQSINv+427l9MN\r\nOaWLhMNWvTXS2i7iZEnt2ai9zAWMWY7puvD0HyKIhOGZQvpFJFZepghj6xuk\r\n3EN0R1OM1hDeXA/v1SbbiM1s7w4ETAcuawqWxyK5DYsUwtBSyi5NvAnn7WZP\r\nH7kq9boDwFNuM2i1DyVep3SV3jwz+/UcUQI=\r\n=zfFD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"21edffba0b9d147d7a297a3e4a69d68cdca09b82","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82_1669937311343_0.8969713124186656","host":"s3://npm-registry-packages"}},"0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5":{"name":"storage-mixin","version":"0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"faa563e58b9e62874661fa8bc22361e41849a51d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5.tgz","fileCount":23,"integrity":"sha512-rG07P0z23eY5igk5dNboQb+h1M6tu8TwNqflYip8YhSuO5+MCyL/390fZiq5xQhDHK0EoKlnI2AJdLyTOwT2Yw==","signatures":[{"sig":"MEUCICDeQo0ciksxkKXTIdj0HDF5+CSUWFiXHzGdK/nY2gwqAiEA4QD2+Z9jouQbZatAsPF9wa54TXmwgfH5AVdL1MHmPMQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjjR/FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqZOBAAlS8ZPVNH31GhWPxuCSHN384GltU7+QHiPl4frJQy8hIYdg2w\r\n+yv57hXsHoT3zMcRBpuw6cYGtDo3IHQ5YkG+AeWrxyf5tya+ZDWd2m5aNRvy\r\n6aC8a7STuddGHeqGH54U6lUMYR6tz4tYJlA5ckyXYrJ5so63v2NMDtIUr+yf\r\n82MHXbDHj4RG0FsUGXLjSYozf+enWLfXQB+A8XnVZHg0WjotgAM2KyIK9wVg\r\ny1XwzEz6OVNZMQTvIBxz5XXeLXFFUii1iRpHw6WU7/hdWebaxMQLugka65Jp\r\nZGSaCsgUGFUfyk1BcyCAVho0Hv2iDifvnp3iSUYXZgK1V6hj273yFlWTEIkH\r\nOcly3UIYWd8Rbz87TpOiv/wk6Jfwp7a1EL7x6khJdo1pgQKjlh2+xYwTuLb3\r\nEfzDpMDJSL7odf48m94JW3elWdaCKessY30LNv3OeXoGyFqdSkyPo7MmcPGs\r\na/YvLL7+57emIiuCbY6y/C+W9LZgwAtFRvubkQjflFRJXzzgz65lzEjAM+0+\r\ncDuXTV0UrwNdV0TGivLZGN5cwThvMs9cT1Jaeik4M2/sehI97eN7T7RdkCIr\r\nnphffZYca2UejzgM0+IKpKlIg0g1pDlQVbXE2+zvtz2uvZGt3RneikFg3eBK\r\nSMOizYPdJyZJr4Bpf4c7WaI0+b/5fj9QoX8=\r\n=fPZU\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6a5d526328ecfce1da82bf064daeb19f1c2bf6a5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5_1670193093554_0.5303154418303921","host":"s3://npm-registry-packages"}},"0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b":{"name":"storage-mixin","version":"0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"38112cd5e53f1fe69ffea8e6e829bef2ded9a94a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b.tgz","fileCount":23,"integrity":"sha512-Lah7ZC/obqniKsuKnr/0RIE/w27j+suwWjsAt/ChneLKOzebEN6OKmFzc3YzFIbmm+n/INm+R3u15056aNiGQQ==","signatures":[{"sig":"MEUCIQC+0weDPJJCKFRvOm3QIvLtMETOSSMXUclwi1iaByAY4wIgexT7nXLaMU5O06dg+573K6wC1XZmdCYg5Va5i0oQJ+Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjjpJGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoL0A//dq5b7kSL6V2mfYTYWhpvsPNlLyLmYa/3NenGjJyCcYLCVebz\r\n+QrNIMMHWw3HpFd83DLjq8YIP8uds4EzBj8L71ViZ6lgoKgcw3ezFezP6/so\r\nA5ihbB2b8LotyA3SNyNBWZl7wWr2vd6EC9lxRQN501XFbRNoI+3ySX6+xnt8\r\nvkk5FfPgSiubEs9a8MJY0O96Kuy2zlQA17iaqsqPx9aprnDxTN3SofN+8Exc\r\nmzz4G7cUqgoUMHQnmxf0IwLpFnl31bX7zYVgATr68orwmigexj3HtRKEuK9y\r\n7WjJiv1+zeFqpIgLfAUw4v0pt7Q79XekRz25sLKoSPKaHoHZryDfQdDOTRA+\r\nqO+VR57P5fIBPfCus7ttNNIAHZ9zzWLvE1BQyNBDtFZkhSytaVo/paZwJq3o\r\nceiLAV9JFxbKH1cWxYhwgR/d+mvhqlHvKvt3IIsxNIIXjavYjq4Xa8BSBybr\r\nZzunPdBUUR6TO6x17I654gTRWAGDrK/dbkWaRkhlDgJBfFVRQHu7uvnqfnMf\r\nAUXqeGrbJm0RjsiJIc0JtUufxcAqjkHeHHFXdnZYdd580Fitz7csdrOL8h3D\r\nF8FXcZUxUwoTodjRxH8j1T670JUamjLCKimHWUcjhZ/gOcNGIU/X+97ZXzKa\r\nQLIlPKWwaJiBPL9cg0hQfP3qKugkAOcUHBw=\r\n=bsZc\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"2f189f8218b434e8d36a7472a2ac843f17147b9b","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b_1670287942269_0.08691497582038021","host":"s3://npm-registry-packages"}},"0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0":{"name":"storage-mixin","version":"0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"6cd87b6bf283257fdbf61fb7ba1f75d6644aee41","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0.tgz","fileCount":23,"integrity":"sha512-fgvgBwiz23IjQtS9IS/OP/JSIqNUlQfLb3zxqj5GYxKmLVzXAlceQfbpIU5i91shuSD1kKXv02rV+gaj/Kc74w==","signatures":[{"sig":"MEUCIQCBQdmMr9jSndZXwaYPay3IYJhdVFN+hOntacTpk/fn4AIgSOJGuEktV3+eauggvxMPw7W+dsZvJFOaU5bdWkAl02Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjjpKsACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmouBw/9FSMeEV8+NAPxJQR7QR5fRW7OJWK4HZUupCNVR0U1vWWVPveK\r\n3L1qJLh2gf2SeH23hZ7wW7uquivfw7pASTe5R1QmHAyw0VOQhW41gAW5x/4H\r\nzb/jqWSHOwki6JY97hchlyk4FV1qSm72c1YOpPelZ8hSuLOQVx7BXDicWZcV\r\nXCe0YG4yTaQB+Ss56kqGhkpg5232RaNEnoBQWgkVvyUyfguWb5EQSTuk7eDv\r\nMTPBbvZ1iT0uv2oWPuELAPc+ySCOIcudHaxmj2jc6eAnGBxbBCqj0oJeoE26\r\nODKaZZcZMZFG+KGAQWcNNVSm9FNUQaU8omxb7g4wcwqHiD5T+jqqt3+K3DMh\r\nQRpIVQk58STRr1VWPZCiJjfDY0CpzSujIq19aqaidYvQOCB4AUN7UJNRpk5e\r\ny5wbWHWnSxCDrsUVUIpxX7X+8VEz4Fi34DnQfz5EEYu87hVC/IKgCQRhesEr\r\nj7rPYrQyxc8+Imo3aa9nBbpTzYLYVZQo0Yvo8UX5EwlwpCO73EURYIoFjZLm\r\nITqPTj4T7986hbXQRevmfigpzL8HZOH6sCRJH7hBNXxG4NMq4zR3Opl7Lmu9\r\nXQpoa7mm+XTT+5xsVE+RPMTa9CmXM3qFV6EmN37x8Rpx4Sece9pX8snARVpQ\r\n6VIoCnPl/Y0D0vLK4DleNV2iLZsnYZCfx1I=\r\n=cthF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"faf899c161858cffa138dc64f4fbf9c0da2145e0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0_1670288044168_0.393583866740983","host":"s3://npm-registry-packages"}},"0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49":{"name":"storage-mixin","version":"0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"fc903cb71019a1816659063bac91140ba781bb6e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49.tgz","fileCount":23,"integrity":"sha512-uPBOfUPsJMEGTm7/iHkfmllDH+UHvSDC5DBuGsENbjp/bq9b79Qr6GHvvQX6ZKcHl4xxa5BP2SVKr3Hmn5KWow==","signatures":[{"sig":"MEUCIQD+0LQa025Sqrb0KpH0hhrnw0GcTy2Q/oEsHGvdkmi6JwIgKxweHC6o5gCJnLB9nD++dD1uLZ7nv+fLHSkT5L8T3Ls=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjkMnbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmradg/5AFdizWp6VgoVBEHyzCRFpcPwDM2ntnYnjJQdgWTI82aDuFlp\r\nGT7iLgGjwiHj23NmidkbalCIUHOPbeecA64bwzEYMmLiJJnjE0A2vw6VKuMy\r\n5ijlYYhrmMw1fx25DaaGyYvfblI6Ltc4RsX9xIAxBO/OGzTSBXlVIkUhHFWo\r\nk+PmdLXFbm4rjRA4iQVSxyIhgKGhs7Ek8cGVjxdhv7QsQ2Vl6UwrCbpKOxyi\r\nV9la6EWbedrPPyjgSdMOzkBNZzoMoBaM0NFfAD548EnsEffm1+h8MHbOzVN1\r\nxiNJGmDTiESt38+nD4kUSCxUPo4UNgJgO5i1NuFpq7ZqTpj+jTES12VNoTsZ\r\nQP8vT0kOdYVb8UmRrH8Cro+4giWXqmjgxwblRHZ2MV846zk0+v4pi7PmBNBs\r\nmhQG0di7aZF210WzDI39eNF8aN5941aHt6hpndb7bbmmH3B9n7hmsVZ8ks5o\r\nHtF5qHC6assFKiy7MTttpH0cB0DpMDuXtXp15JysW+Afo7vBPAs3TyU2QBxN\r\nAys0TBaa5b2xL08wy78hGb4hpJCD1sYYaC44/tRgovPRh7/xzzcDgGODh4l4\r\nS2OFKJIr6h6Qhxc8xNargBdR0NnlgrJJGWtb+2tb35nrB78cbJ6nSQLGI+Db\r\nhIlumUEBBoY3NgVrC0W+KaV9dzuZj4k0ed4=\r\n=tgtI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"f5d7198f71e9d27890af5dc79d01c3950c637d49","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49_1670433243821_0.9200709903635647","host":"s3://npm-registry-packages"}},"0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557":{"name":"storage-mixin","version":"0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4bb11588a5631b8d586f1e544cabf008d27f2e55","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557.tgz","fileCount":23,"integrity":"sha512-V2gxEUCOuUSq3Yp6MHtMOS0XzC74efFUJM6RChKApRXokUIwz+HZRQdInhkO7kjkENA54Uvu+xoVgI81HLFskg==","signatures":[{"sig":"MEUCIA2rBpM38bZGk0PDC4uJ9Byn12nNOdEc0ca1elZFyJk7AiEA054B7Tx96nps6hXnSGXrk1sdasaBdEavFaf85ZPQCUA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjkqEEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoYdw//dyIfVSVqHqeLpEpLK5/W/4gj9QwjoI0FC2KupZyqig4zUD2/\r\njE2w8l0WLcKDv5ZY0rIBuVUwilxN9IwRrrbXKYebJfHNlJuFM4TQaCbkWvWu\r\nA04Z62Qc7BfwCz63SxGFexHEBRwphvguqqmb4rHhR7ElG793rOIS05jchbC7\r\n9aC7MfBIQUI1CbYIizP9zsOloQAl9imVlWwFyimfU7O4c74TNOZLwne2/vIw\r\nyTjOa2UH5cCBIgOQI94rRXTkBh40epixr5Ul/Ap9sFfnCtheu/JnQrskt0fn\r\nMMRtJvbQQIzeSYm9J7bREH67OMZ7cg2/7FDy/RqeZXFtrfC6ypFXcSyMMy2G\r\n6XqF3QjnCGD6PVG2er3vvDIJoWjODcOZ2nhbXbbcvP85dClNNT5o+ChnZy5F\r\nRPjBfGjqrvNS47lKFbg7hi8B5vehzun9utEby1bos7RiwKvRNnmGH1vag6gT\r\n2/35pUhBIyW5RhlkHRcBFGIQCQq7vPnyxiaJgA54Up+aNSgHSnUelzgOQjgp\r\n2WK8w4z5kpvzwp1x/3D3qxk9VzfvtyaFg8inBUPoYhj9U6eEyNZpf3hK9kgy\r\nRaLxloK71cXB+vAs/fOHggM4xP/IrFkr6sGNIiFSrmVN9BaXCi4wxUsj5iUh\r\nScO0YEr8NII0/9u/PyN6YTCqHCAofi3Mgg8=\r\n=GXeO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557_1670553860076_0.11922802739830884","host":"s3://npm-registry-packages"}},"0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179":{"name":"storage-mixin","version":"0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7b192e2837e5832b71a3fd8fa90f28d93a78b176","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179.tgz","fileCount":23,"integrity":"sha512-dwsWpEa0o57DsvNbVWml5Gr7m6cTZ9SKRmyYFrQE2OUsm72F3ffL6nd9GiGMaRGBPLh4JflxWDTKO3un7Io3rA==","signatures":[{"sig":"MEUCIQD38RinxeH6NqRmwjYAKnwyRGxCD7bluiX6Y6JvJcoUJwIgTouPJkuzFJhukVNHN2gT57Y+DbXhqmHerRPoajUilUM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjkqGWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmprxA/7Bv0ugNeoEG8vU+37s4HCi67idgEepQ57KswwS2U1tU+g3UJz\r\nQt/AFBo0bVh/HOj/DqdYNUOhk3jSThth4SNAndk4Bcf5nvv9pWg/SkHSPVOb\r\nsQqLVHsttaL4d5ig4PGi3O2GXn56Z46UJEo5o6K/NRST2dnCcaDvpvWAMnFx\r\nU68lj1hhteJ1EvYSphsQP7wdLSrSH/+fsOPYfk2AAFJSlqj2YTNuxUbLtoRn\r\nLpG2TnZiO3N2S1RgHFQbgD15Uq1PcEkncGDPe6QsmQ7x6NFzUkx7VyI/QjRl\r\nImITJSBPHGVI0tPqA/secozbx2wQczsxRYQL5Tqnmb8AbMoyC+xealr7lXGp\r\nM/AixqRUIuYUrMuJkUXc0Rw87jiJr0racks8aiMNfWwSlkvXtLHzSBXr3Xih\r\nOrEA9FG4eSmB1v7KPh/ACUhIWAxcItsxlVou9eaG+ul/iFV8ODsbiiFW3nhS\r\nZpcT1957oMDrHIoeo3A3PS6XRC5lXF2gbsBbdaJSBiK9uUwKUSddBp936vuM\r\nDSxUQmUYz8vUjsAWoTlnoCYbhiHFn7qW5h5jnBIsaxceU04mxJs8wSYWWAsY\r\nkI7sYuZ8byiK/dbLWftbiz9tatEv5j/82rnIIz9yENjfj1Y87H9QT2Q75HAa\r\n81UNgpGTam7VM2vev2VBIaeGP7kOFb0cpnk=\r\n=dG33\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"d43728ce0cf99f511bd2d2aebad966bc49276179","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179_1670554005884_0.31626447854774864","host":"s3://npm-registry-packages"}},"0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2":{"name":"storage-mixin","version":"0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"b59fd8f0abdb5b39ed7f73d1dfd245ee483f317e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2.tgz","fileCount":23,"integrity":"sha512-ojgj1SyC7Sh87XwxodSeL5emIQ+g5i2S4wjRrw1G7zBePom5OBLeonGIt33FktxsjIXzSagfEPZMz7wplKIw7Q==","signatures":[{"sig":"MEUCIQCEAXNhvWsIp4fNOG05W/DP10p+ukyezFYL0H5TEpGnWgIgT3RMYiVgxhPeE7bS+FWkq6/NAjOHuUj/kmxz9r0KyLc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjkqPZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo3Ng/+INgapHQZeAyg5EurTi8hQ4Wc5LTFCNjdiB69/JFzQhmQ9DH2\r\ngi4Bf55PIA8ISYYwwLLZ9vPKhtYEXtIpQWaG+ZiROvQIzxUSdHvIQQSQPHtt\r\nfirj4L8YFVVNX+fDrDeFoXsfAAd2NWatQc4WOb14Dqp5U9IdhZ8zLR3DpbvJ\r\nA1PX01eD18bT2HNVOqPD/9Ev3zhH7fBjYAlMArfWG91ABW2XAdCbPWJqMCD1\r\ncBwLe6tlgJNAhDiWL2eeuKsEbz3R9/sCdXYNA31KpIOSsgTHuGdqH9mhC4tX\r\nn+E/sQpF0TdpBxm1wzhXyLxrYmjXranQynJkxq7fOMpnxH7ugiF75Y5/UmWj\r\nxMa+uYsQjyCWYuQWyOrO++X2NiTYvtL/7PgpswdF95hnsOv8IMhDJsoDEkam\r\nDusdZkvKSoSkA1skI7ia1c2FSCN4h3g7+RcGnEg+4vYgDKag9U1kDuhOePyb\r\nWoT7p1acMjaLRdJVFvK8mlzb9Co2PHztkDw63By4sNCA3XJrwuFICrjJL7/L\r\nn3RHq2ZuNB1ImYuItHp/Ppppxu1TvdlljxT1Jp79Ja2Uik+kWIq4iJFXgMUc\r\n1Ahp0+1GaBMyTZ/3GnhoaRqthS71iFJulea19uetMYBLtk4BjoJywwknzFsX\r\nozo81d14FrE5MDw674JW75WyWJi5rdqeMc0=\r\n=fi0r\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"0d9e77c42a99b49fd4ecc7167d0c769866f92ef2","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2_1670554585208_0.9690436540712986","host":"s3://npm-registry-packages"}},"0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9":{"name":"storage-mixin","version":"0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"23b593a123edd538bc31e49cbb578c349e96703e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9.tgz","fileCount":23,"integrity":"sha512-S4kfLdDvoaeti/pxs+6/JOkx3qCbR1sj8xOufb2S6mlJcsqCHdFX428qHxDBVjLmWyWIqAYPM7kWkJiNLlzqUA==","signatures":[{"sig":"MEUCIQCzF0qcACNKCNiF6GLvvqNWBtGAMypivexy/K2telmP/QIgAoig1Nt5o1YdD6B5RMT+tvEP2/wE8bI7PNwov31H1lI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjk31UACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpLCA//YqJjdpJWSxu5KmxL9Ei7nK/50KiuEXY3/UzVMuYF9yw96Gtf\r\ncG/jUZ+Z22r0xqcnVQWXuPZ+NN9CM/KMniwSEFxZHrl3tsMUr9LMmeMn+QqV\r\nuP1h2S8iC/WOdnbPNswyCCTeFmhfd9CDD/iyIOHsorLrQTjSw7sxNlLTATc7\r\nTyo4Dv846LkjZ+s5mOtSMlvMRZ5A/PqUz4dr2AgXGlS7CKQDrxAEGs2OXyjr\r\n3fCXQ30GFmdTF2xcwqenF6QIWR5iW2Hie3WQvMDx9rUaiLW33qJuUR2iaM02\r\nvLFGYcGPB//5HpWnjMbOCWDjaoeF4suALRh7YBknpluok7MOT8NPoSpqXBfs\r\naeUfGAGgYsT7XRmElnAhIjDVLLmUR0Z6v6ze+4dRU34eH/zIVnpNGCgy6TRw\r\nzGnmIpwh8Xp3jSGON1dFb3AVk8l0xsBQJ9cam+MfjPULirK7nf13TUdJTsqv\r\nmDu/xl3EbtfdtQpKdRk7QiUtb9C0N9GLvQtpqyQEw47Lr8OnoyI6rnINi4D6\r\n84sDp+ndxGI59lCIpx2yHU5mMx3m4pDbru1U3P6QNjfm7+tqQQ2jbvKTcoqM\r\nQrmzto0t6KdD3LEK5ES+AtwBFCdreDvgAuhcKCZZYRT9qEFiNK+EmTxtoRG1\r\n0j7i8EWIJ3kA/2F//1iONo2pDBc1O7/nbfY=\r\n=UT7E\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"7db57a9d912a713312c9f79acdfcde9e49b554d9","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9_1670610260671_0.11055482132174932","host":"s3://npm-registry-packages"}},"0.0.0-next-907430527b638cb96704541b347715ec1dcc648b":{"name":"storage-mixin","version":"0.0.0-next-907430527b638cb96704541b347715ec1dcc648b","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-907430527b638cb96704541b347715ec1dcc648b","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"d509ea0af9c20ba0c969a1ca63a5a30c7f14f89e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-907430527b638cb96704541b347715ec1dcc648b.tgz","fileCount":23,"integrity":"sha512-nhzPKvgtL8YKnhQF9SS+T0fejbllcLJeGSCw/1NuEprlEC42kdKiUtHnzgTN9RfcBhF3h8vgIDGCG+9x7wITig==","signatures":[{"sig":"MEQCIE6YBcLGSlKMYoyEE4NznrgSAQ5gGJvce5yotr1AP38nAiBv1njMIIbkZSSgSCAUgvYwU+3YzWkAXyQu+SoFSNUHgg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjl54TACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpUbxAAhcuqR0qcuRivItDVoOrvsxucPZBNWbVepfPxAOFWuC//HYg2\r\n3I3YTm3whqsNliXBOuNswCueta2X9NsyOnDd1BTeQ3IJMrkStZaCvrNInE0q\r\niTmD7+305AzWZ9QgRtOy1p9QR0jwVpyUKS6W5bWMLIysoiLO3z1Y+vFVZK9h\r\nqOhr9PLOQXLTFvHcbqHkbvguYSHp0XYXdLCZDJhAtPld/+ZbQGdCbbtJsc/V\r\nY3qLqmsCEjWLDTbH9xdRe3+klWzZUhT28SKxRCgt9xmUv7YY3QMvuj293A4h\r\nRrNHuagKbDGX/KevbmwZ5lNSwMObvE9D5/vQbnNfGiRk6BT3iMq/elX3ixim\r\nLV71LcYbkaRgkJLN9/jWkEcT0pu9ta4G6ySzJhawT0xjycJqweIwKgUWNpMX\r\n5en6LqHJ3xeWwEEwF+n7ICnN9xyb5k+7iPSt1sg13QtE0ZT4fAaPGQh3dxxW\r\n9eVEOzQxGp1QNcOGrkB88H5kiQzDO/EDTZMren2GsXMsy1KRcSkH1HBtUItS\r\nBSdXfppvJb7g3JACll/byAjT60yuv2+VUJTRPKuh9W9pmIHImoM8uitzehfc\r\n4nUrgnftZcOHFH2o8DzWgrtIodLAwBBY2KSwsaqe/C+Vm9UTwP3dYQr0JzcS\r\nWSOVCGLoFdMwGIzRMhmIYwJNvM4346z6SSA=\r\n=NazO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"907430527b638cb96704541b347715ec1dcc648b","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-907430527b638cb96704541b347715ec1dcc648b","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-907430527b638cb96704541b347715ec1dcc648b"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-907430527b638cb96704541b347715ec1dcc648b_1670880787703_0.027169669671787577","host":"s3://npm-registry-packages"}},"0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0":{"name":"storage-mixin","version":"0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"11a032e17dbaf8bd565b5f377c471dfdb98ba9c7","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0.tgz","fileCount":23,"integrity":"sha512-oadxOfZ3FpDH/AzXySyPpKZEbe1+fUwMkdYpLtHBT5QqfGw5XqzT9OYCW6CZiE4HJ/TizTidD66aVwJBwkvYxw==","signatures":[{"sig":"MEUCIQDawpxhziXVzBoXf1utWR0JiYrrC9w1fXG3WG4JXoKMgwIgEChjLG6f9eoSaV+Oy0HjKRJFJO/cW6R//y2QK0Ku/uk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjl59AACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmowKBAAgE8kWQrld1IM9MIxx9Hm3fn5SMUldRXoRmF0tSU5yWtlGvxy\r\nRJ+KL1NVMZ9hmpAjUzhRb6uRVH6gBIBYj7jbC7gaqn1dakrpC2I6a+3f256X\r\n0iFTttaTXwUSoEQ3/mqHYQei6LnCGJHmfWszqv4gxQSN81hhzi1msqGenMZq\r\nCboW/JeN8nhnyk60OJl8kX/ffBCmHu0xts4JvtNMSjMpD8OurNpBTNGje1zH\r\nxlq/I1C8fASfZggLMZHsaplLJKjBxs3O3MmOrK0JbM3mkKCQASZFm8wEKTsd\r\nwVAlfjNXvxtp8YBwF9DDmAvHEOtJBvdxbomByIuGJIsZnPNV1DhfPZtNLaGR\r\n+MkbvjraOaQnxE5Cq/SEbpNkV0GQRk9EDjrJjv0lygP2/t/KUEE34TrG6P6F\r\nvzdyYLf0p2MDEmCE44EyJTImqyxCMHUHMFO9obJ3Iuvl2Jv0Eltx4bdB8/kZ\r\nn7eLgdreuHrpDnyRax99l5D/4MLW+CEmpP61C8/ewN2nZyTHS4ZYgJsdbCs+\r\nw8pdVuaOGYrmhc/Je6i4mg8Hwo8v13RWyxGDcJ/e5DjwikMNjVYUc8mrc6Vl\r\nhzg+YFED3Gx6sJn+H0yVhScwEKyZDjXzz4OALaiFRbQnF7rQyT2nFoiM++ik\r\nUPAw48s68Ze98cW6MRHvsWNSB6xEaAXzrQE=\r\n=j5vF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3888dd701d06bedcc2b043270c5dc626b9997eb0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0_1670881088154_0.5273666071571317","host":"s3://npm-registry-packages"}},"0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15":{"name":"storage-mixin","version":"0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15","maintainers":[{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5cce4a315dd2f534bcd7c30043bddfc4b9d9657c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15.tgz","fileCount":23,"integrity":"sha512-XWO2k7HJ8w7GW02PFsca1zXFObL4rWRj9WMyAV/pbk0APqqyMkiLlhj4Q5Ihqe0QPbeqyAw26iDoieK8WcL3qQ==","signatures":[{"sig":"MEQCIGAEMJKXyonrEVBnx+2KJ6FI6FyjglhGekkQzX8vYW8KAiBrSv72FJRUxmGms1c0irT3ri25wy5l4hzLGmxiRyq2Kg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjmhXHACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmriZA//WC6J4T4ljZ4W8GKNpA0V6eirq029V8aVGXZCEAwNyQcyYIdS\r\nkMvBB9Zj3UGG3oTO/srrGBbbu/boM7u+He+QsUn9GVLrqGc/LrnqU9YJc6Wz\r\nH/ZCMByamub1lusowHyito+S+f0wPum7uacy5YQzZ5yb2hiEdgj0YSI+jSOI\r\nOCPlcRe7Trt5Nr7RsV+JMM09zMpTx+MhpSIcFZMviXQBBZDmGzTehWapZkua\r\nFKcBvLnY6XA8iLz2CZfO+IMIsu6ex2sLGKYoAqmr96wgnZtw+/hS13KB+qXM\r\n1b4WR5w0J1Ri3dQzBkrg7ctGqQYJz+vgzjH3cDv4ozIZimSEIVXBqWmNBpEY\r\nS4ZIFssGq5cCamnAp1oc9qYmeloU6566uOqwGVtWRMK0AtmGoQUldgFJ+tjr\r\ngP62Av17MFxN4jsy34dCfME3cLWmKo93Pi9ROjOe/AFo5XkXlOzPY2Xr7hlT\r\nKHUCNh11Yb5mU+CzfglCrW6ufrl3ovt0g2bCa7FDGIlG5zdBxDWTTqjf98w6\r\nUiSQQaLPCVFdNYp4XufyTaWLgPvyq7zZw6UqdZBFi+CYq5kZAiJfuctkWVfE\r\nSy/t18YxnK8dOnXIxw7JA2ax9p5DCXkDA1617SjXYLkvp0f49BBFvnher9HP\r\nRAGmM6oGhualpWH5pnCB+sBpPlXChJLEhUs=\r\n=oeyk\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"dc4590988660016a4419dbc587f3182af207ed15","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15_1671042502804_0.9081712768627692","host":"s3://npm-registry-packages"}},"0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200":{"name":"storage-mixin","version":"0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5be3e74501f65e41c527fded7544bda8d5f9ddf4","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200.tgz","fileCount":23,"integrity":"sha512-oF8eDtiPoVBMqTOyjp6uGJgg5VSqLjk7Mv+miUyc63u+PWI97KVMVk0Q4bCFJUOGFaFRAfelEhurP37A4E1Liw==","signatures":[{"sig":"MEUCIQCfEeAYOgpQpA4EdnblOptN7VFhxGsY8rKU8lLbu+KjmwIgGBptryvUgF58QSADLA9Hu2DE+FC7rk7BFNkmxToh6VQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwXR4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp1RA//efoLpn+p00fnI2ITpU9UMuMcs9H33PCT8DbYiz0I+2ospVRw\r\nOT5OawKs7rgmZv3Gt7Ooc0dWwW3TE3vTPu7mDgHGs8wDH1kfVftjUbX15wKA\r\nOHvVeBKYpVYvgJYDR91KwgZijl+qy+iKFHJcaxxJtlSwM5zKQEajYFCKmxon\r\nkYyyyADpAArauOeSu30RgepBr0HRx5Fvy/b3K0+8rZs9nk7mSMVo3agWM9+p\r\nZdFY1U9gZxfvUbmN9q3jWJLWxOs4Oyotc8WfXInGsKfk2F+hle8nbGq/1+n8\r\nHyjbHBggZ81oTx14HNRnkQYq/zAJgaqewvRjD8KA5f3f/y0PxtDXNpFv3Wqu\r\nMSxnJoBbd/Cr5sxRT+aMLWLb5skxQ50KwFyDgaxrpak6w0x0ZQLax92Xs1F1\r\nG5KKIAjzw/I9JLo9W5nC1eXps6G+aNWPP5yqDBGhCZXGrW/4cTmZOIZvU9zZ\r\nYccXMhUWuIIpf2jKHLx06e+aVthAxhvExxysfVj1Isd9kGCx0BfoOu5Bnba7\r\nLqv5RfMAH6AJxkma6dR71QFyTi2xT9gL7LUy+UDpN9rGMZnl3bGTnp6Ru47x\r\n3rZkoFvLT2KLvwoOPG1jx0j4etn6hi7vPWgg0P/BI8ApGEhgIgzMTbIWZtxS\r\n8r84QvLu9D7zDkCc62V+Gv6en/0S45q8Vr4=\r\n=S6MF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"cbaa086f387b9c9b62aef9381297773a9794a200","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200_1673622648243_0.46528863452971647","host":"s3://npm-registry-packages"}},"0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81":{"name":"storage-mixin","version":"0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"13db705c77c5a31e6675bf4da69e3416a7ee83e7","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81.tgz","fileCount":23,"integrity":"sha512-CMgd4fwwTyoBB9AJuo9j622LQTgl23XOpWTPM0fgkTFrk0AkOO4PHkH8iDZBd1qrKufrPv9cGMsqgD8U5DhS8A==","signatures":[{"sig":"MEUCIEYSwv3Trdj9Lq6jq4kFKNXw8QxuH80Tt8zuUv75hpxLAiEAwEC4GozbyojdaC/+GhJXh0WwfGVU6k7ADeA5eBZJMzE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwZceACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoaQg//fWBPAmXNwTAcgNVDVFRXY2+ccD15fvgQZbstOC9Gaw2eW4xn\r\nyBmxuNGKxjapqzMTpCuI6GSwNh0FuEmtRnbr5S1Ilemj+X2Ypr5HbP7KCrBY\r\nB0CiwLYT8IdvTrTMm6vHdt4bUhj4WZjUfEhccFXqY33w7QRHuTue/6P8vPQN\r\nSaN4MSS/EyagPppKzQ3TCUm972eVuzBKGh9HUJG29hegufPBwyttsKIrmmsx\r\njLz/JrrO0nSgTYRSjzTkEiYe4Nu16XRjnXiciUheBi1iepoFplMhm0Ws5IUx\r\n8UWgmb9wUYd3MBYW8V/5PKDBhM5oZgS6JTogZ//6Kk2Js+day9uMZhbj87ju\r\n4RfqPVv3HjfO+fPFVf5T/4lja2/Nl5oWlp++vO5v+SaLd4Gf670BMbD83OSo\r\nZ3P5AtSC4+5m7/vEneRaI/cQrEdABs77XdoDo7HcgBjMWN5FUicugEoVAuVf\r\n4FMFUxmduCMi0KPeK3mN55Wt2GMdXMbJ7TJWQpSIfZHsorjOU8pZB1NjO+Ii\r\nGONZWL+PA/UHU83TOP8yaPoaYkTrVxE4uttHnraHdczf4GAW9jhJO894KBw7\r\nvLcZnbsZZeZRJWcym9MUMx2WfrgQEJXT9kWx7XbFMjW5Hgtvz2IrpGf64b9W\r\nsKEU0UR2Y72E9ERSjC2ajOx9VNkG6rJXCYU=\r\n=bTyk\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"cb3371cdb3289f37402f09c6388269e88c943a81","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81_1673631518448_0.5369703883678638","host":"s3://npm-registry-packages"}},"0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3":{"name":"storage-mixin","version":"0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4790c516dd8adbdb031344e81c3948d28331d84a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3.tgz","fileCount":23,"integrity":"sha512-dVfKqxUH9F07hGRsookERPVsBLYTbiWe7HRMluYcbAXllwdCMFxbZhVCK5TCSoelHGhBIAXMNpp3NI5ElOSFgg==","signatures":[{"sig":"MEUCIBL2Yc4GYYfLqpXikdvahD/wqmqDcYiKK4NY1xAME97sAiEAk/ZCJEZkYVoaX1x4jK2KMhAG0FYpctKwxV/JNpGNME8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwwceACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqxDw/+PVHPPaEqkKEEqAFfZgX6qXY+PnXpIW0EgEKOCeQeJvdt+1gJ\r\nA7R+w3Ip7XfHUx2cZwp8k1i6ZhtK6moTwJx8x58HVx5h5JI8APfS7vziyAY3\r\n2ibV2nTzA/Fn6jtaj6344bB9CsgdZ5ezmex0KIkrNffznfK6IgyT4UIONM5G\r\n+X94hskw7uQEW0w0y2FrsoB0TfrptkSkmuu/z3Qyr4vzzyHb9KokrZfliDU5\r\nCyv0Ug4/ivcnL2L4jlGWjgV3PVTzp0BTIxhWIrc7qxxbntAGPlwO1DhOMfXM\r\neOU1dYsV13EPSdhnNIaPQEB0WK72EGhbCzPg2EKs+YqsQtQ5x3KFArGFr36R\r\nJE+d9bl8Tom3nhy/j6gnJ5IEupQCRL60M+nkHHCZD0VV5cPmbVLbIqsGimRL\r\nlBgrKtEWTTClAMGI1upMZVRXkun3xxs8TPr78xdxiDyVltyxMkregMWs8p1I\r\n4znGhoFZSrIeo4cMD2/fkhnulSv+LcyPsHa8G28O9VskLOi7Zkp5HVC+kkZf\r\nG8dRbhl+XfXXgUS4zNm4g/QVfrPgX7lETW3vrwHZHa2vjTdgl2Hkr1xQn2XC\r\nP/byEIJxf2ftgGV5gh2YxMxuh5eM9ccBOi7v5U3iXkpuDVWB6WNAdRC3ttbT\r\nAlo2Zs/Rul4LPxvwn0+3QOvMne0nch1KAsM=\r\n=bfal\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"f6dcd616f47e1d3843402c3e0f47d541edec53f3","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3_1673725726254_0.3005176436023098","host":"s3://npm-registry-packages"}},"0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4":{"name":"storage-mixin","version":"0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"491f5f16b9c5281ba0feb08557ef90547204ea55","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4.tgz","fileCount":23,"integrity":"sha512-daD3tsMzG32R+7oS+e4Ywe+cR0Zj0ayU4QKkoE+KQNqSj445woaQwPoY4xgreQE7iW++zYlbtRufNJs2VHuZkw==","signatures":[{"sig":"MEQCIDDmLZka8kE77qPd79NleeYBWTuAMUObIoBTHipXn1MgAiA8bALva8dm2HW2m/TGCadjBb8nwBVvQudC4D62EBFLtw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjxWJuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqVRg//RBN0UDw0N56GyFzD8fx1oZ3rRL16aoihHt5oZHJDVZ5+AMH4\r\nA8FWC3xv/7P1yGIsuYz3c/UJfhDfy3aLMeKwRA9j3RC6H9O2xJexlhhoKsrh\r\n0tIcNm+wn6n6zkQac7nF0QiR6v4xroM6UFWH32ln7svbPk61KXN17dYwn83S\r\ni+bgtBSJ9OIAIq8QLjflQ8P/r99zjlEPtgYHLFX4kEtMf0gntJJ0HHFTnIfJ\r\nLuNbJvihBBQQ5pDYrThgvsNpTqJ05pwcXct73pMXxwf/GBVb98qzn9ssa3Bi\r\n9/Muw/cDZ3bHdLiX6GmsldRqDiwHt5xbFaX5VnFP76MSWbQr94e9OBxWoaxZ\r\n+yI4FGNXRJ/c107lvvWVMTV3nXhQ7cwS+snnB1c3gZWnO/X6oJliNqy0FP80\r\npbiZtfXZDplRXh4KQC+FIGy2HNgWk74D5W9PM2KGlKS73lwXDub6GKEBtqHN\r\nt9hPtzVP9UUP4I+nYiAHtpR+XMmjAYPNxE2RVQGrCodg8iT+31KAd3lclYi7\r\nmva4+PtJZ43ON4OjYIgqcUe9h5abPRqbwU/0gM1uN2hKulNnXDlEYY9nhPu+\r\nkMj7PPwnKRr51sjHPhqx+JOeXlMYPUKORirQLnZf2CC0KL1135li6j+1T4WQ\r\nxWOG4Bds7OJUaz8UM65D715nhmQ1KoHPcnY=\r\n=83yL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6900ac52ffc5e2e7ef959752bc33235dc12946e4","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4_1673880174105_0.08286086117398406","host":"s3://npm-registry-packages"}},"0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7":{"name":"storage-mixin","version":"0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"427c03dc20f4f6b5f0835872da8295d4b9abf4ea","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7.tgz","fileCount":23,"integrity":"sha512-d5XLG2p4QMdVUa5uhQ5W6bGFisLswJmkmuje8lRJJGpy4RCap6yj7OfsTNMz+2PN/eQyaDIebUiDyLNxUBcGOA==","signatures":[{"sig":"MEQCICdf90D0LuI+CpNMrSqfdgORODqu3qbd1vfAeoQpPq98AiA6EzGlgcz/WgjS1buTkOA5/lyLKY9zyr5r/8tOf3kWFg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjxcjCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpIsA//YcixIXTP4XUGIrEafDiK55P4YJcv6/2iyh0WGuiy0M+LUg/f\r\nVWxEIK16Uwhmt+wp1ZNDzgz0okVwjtS1ksSD1MdjqnpA1/E0O+35zWe7zImA\r\nhybabLlemF5k2yOAR3er6Y1ai/FEsqQoYnG311c5gwFuS7CITZ+xh8aj/dn8\r\nmgF9OknBidgoQS79Ai83LLNJRucx5rtFB5j8AxfsM6qaXXFm7TBnBvmMsKd/\r\nK3XqfWY6+yTo7qs8OMrF/i4sK4R1Tz+N9G/r/3AR6C19QJboEwUeFkx4wkXk\r\nkVkfjHCH9Gv3WRxAWb6s294KdJN5EGuqeO7JV462hXPE6WNdelS88nk9vZeG\r\nuAMTNYBT714vjaIiujmlnBlVjne4wBe/+oMNz56CwKfmeV3VF9mgt6bVn67T\r\n05xYQtGydgDzV+WooTnrP5Kqw4PbQMZ+7e/nebToGfg00rXxWxa8RV2DiaSk\r\nRp0nuk+jS7TagH4iHJt2IhKP1ikRNP5lcvyGW/Dy6FFq7Mg2sFaWWIlhp51Y\r\nAbvr4rfG6pYOqvt31CHEmj2EndZOJCbUwgagu6uR3xwsRhMjHgxh3u9qTB2Y\r\n0ig6/fbWUSE3nhBqVyN6QqNmiv4dr9oddvSAyJXO0/eYXN+5UwqiUYmreNh5\r\n+9Ue2bxYc1bgcOjC/joHM9hKNOxLu+g121w=\r\n=AqXp\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"d09be9dbbff785d6692110b819e06b0186bd3ac7","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7_1673906370126_0.09840281059990508","host":"s3://npm-registry-packages"}},"0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560":{"name":"storage-mixin","version":"0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"c580910bfdff59e5cc3ded1346271e58629c4538","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560.tgz","fileCount":23,"integrity":"sha512-VbNSmN+EJi15R+F5aIS3gu3fAhVeXfazfQd++TSwfOoCpUxT1CHFsic6/V9n7sr9XKh7cEsyt2ft1vKJajpnqg==","signatures":[{"sig":"MEUCID9Cx+ajvnfI1NNQ3m2QhgpbRj8e03MFx9XeuUWauHRtAiEA8FnNAUgsDqtgN4nDbmVvqGUoWyb2wJdNAfMzmuklNJE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjyq/4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmppfxAAn7+3uDNzuwEIETz9mAAk1m6LEC2QFIf46qYrhcsWHPLdauFS\r\noIWg8yHtb32mVDty4GiGTfX1OBGnzzy3RkqSq12Dh8VzIeo5QDgNqJQAtH2Y\r\nGg/0L16TjVh68KuvLDsek+DsNBjiX618aJBnvodE9cfknwbQrvnQ+3NPXbRB\r\n4i5cgTJ48Ni64QoJyZ13jawtVLd479gbq4iLknXPrkQr6yzmz4I1iXZuES9p\r\nc0kN1GBAjnYcdG8lN0WVihBL6iCv6XjX8TeNIGuJY76G+Tn7OC92y9ha3CuP\r\nZ5HMlOv1WPMOo22w6stp/Tn+nyCBJpiweUm8KUKnteDYQBCwfQzAxntDv90M\r\nVL4lgqyARU9pKhaEPuMCosRRBcdWmMIYU/0EYhkyh4yoZD5QXX79FcovtAvS\r\nMqoHCSHaBOoFpDSd4CQs2Zwg7caJFHTBjlZG0vwjtoxAHyewGv5cIX3gVQwt\r\nQYw1q0RfUYCflrMHCcx0t+ywtNuiUpeH9PhXyotdwHVPUKRgQOHp+C4+usjN\r\nuW61ZFuY+s2g5A/BwH9MpCdaQU9w+7N78+qCiSbXIFBsLa59gOhLwEZpBf4l\r\nTvRmdZMVpa2IP6MvAiPcerHJl1jf1K8KeuMEc9plYoxzQ7rxfGeSSIDsmaCM\r\nRBmpK63HAl/jDiHdH9rVOBF++SGoTuyGJoI=\r\n=ukyT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"b72d7d0f94c6cd6b83966a08494549408ed56560","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.7.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^15.5.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560_1674227704530_0.8345551829157136","host":"s3://npm-registry-packages"}},"0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf":{"name":"storage-mixin","version":"0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"34402c777d440e8e7c14641c37870ad89054b9ef","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf.tgz","fileCount":23,"integrity":"sha512-sMW3CHMLADb/RsFsneH8NR9VS9gjgH/B1Tfn4PZ8jsd4N/iK1IDGRpN93HvM2q2AQ6+26SRhjj2jb/QnthW22A==","signatures":[{"sig":"MEUCIQDvDC3otwUptu169xmPy5JW0D7xsG4kv39sgUrgoThNtQIgMEd2vchrKoUg2rTzym9V76Bc74mOceymm89/eknc2iI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj0eRcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpd6w/9F5h8blt8dhOxABAby5AqdhB6pENtKKGt9Y7Dp6cmxElT8lzR\r\nL7WDNkSV8zrbUqZtooa+EfpEFIeVQP4lWkRfbI4TIx2qghNFCEJywd6+/UnC\r\nrw1QVmyYwX97jxQQzbl1cn+84nvS/igkT+17XtZ26ZTsbZbcwAf6j6npxWO8\r\n9mr85l37STU1HmYTT70Qy58gvdxuoZKPE0Tnc54d2I90WkMSRYpXT0fidUF1\r\nO1301SflsLDRN7SXLnfoXiE4iC77ZrlaQHZR9cUAGjJ6fm0x15sWj2hckrxb\r\ncb2QDKxWx5YBeLlh3mgRVUHEPO6aJ3qM/0tbHJSghhjeRdf50/IQbWDVlAp6\r\nYcbhvWirkoEiO3Y0YFZiPIn3+97RdfzQeGnpvTSy/ei2JF+QdXbOs2ZFLKX/\r\nS1/e+u2R9NKcu0S6E/P5iCOCwEO4F3mhKoE31hFgGmIP6KdgOZEHvusBWey7\r\nh/L8kbWMt5hBoSsGYJq2XmTEnSrj1WJfZC5iCxxhYDTInVaNa2uf4MwIwHAV\r\nt/2s9RlGSfHeUvj/SLrlvVbO3hvQaZm3pmyHt7wV5WKQu6F6d5FXr8HLN7yM\r\nWOnPdiEvSShmy9YQh3O+qkDaOWpX9Yl9S6cRPvVLhRm1BSFjcX1hp6hqmhnb\r\n9qZxrYtuz1wtJm3sQCOm/6Fn7ml8vuHBoUM=\r\n=ejx+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf_1674699868384_0.38224816803563755","host":"s3://npm-registry-packages"}},"0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b":{"name":"storage-mixin","version":"0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"3d43a80ac03e85af0431c41b7fd1e9373fde4658","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b.tgz","fileCount":23,"integrity":"sha512-KHZ+P9VdXYWg0A4SLtI+slJQE5H7gTxEdXa+6c2mU2Kw/U1easADbrvmLSnvQnbUWamWs0/KdxDL1JEw4+ryww==","signatures":[{"sig":"MEYCIQD41hWLQqdrWuqFVPgidTt0w+6WW6yLG1SzXwPho9toegIhAJMAueRtIeirYDOxavehVzJy8vLPkfSBt2W2OcJFWM1l","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj2zfdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqwzg//UPVIlKYwVyZFMikNp2zWRACGxq2w89jvz26vBXWFGra0MaOl\r\n/guwNQuBIhv5cpDr7N18J7x/GImIpjxkVFHofdvDuL0RJaHZkcqUH3qCTGLO\r\nqJqtAk3EmFmpa9CYAaIS/JwBvOqoKfZnXWchS26Ti9KnkPG18UFBX9LMSlbi\r\nL5NbnTSmgCDvMXgR93HC9UVrWuqzMKzB3o/nkMzUMWRCMZZtV91PQ/p7ohOK\r\niEbZTUNNGVjTHYagrXIWjm1dp4Oe5p3BRp81tpEvL43NCD3bP2nCpIO4/2qx\r\nWoO55noICkT8mvDkYSD1eE9nodRho/4CcxdaFy0clw9V1Zb27jQgBX43eIgu\r\ntbBjsml/Ppb6haNt7jUsmYI25exFLEkCwOa8djpNW8cPSfZpjqjJ0edbD7C/\r\ndUHhJ74ArN/x0yTtUTRePQXEL3D6cCz9i4KKR+0KohHjUBFja7ZkRySv70aY\r\nwuXanzgBRJa7WXWCsKAxgIVBd0fGqrAAIXVqYhcooYiXKG5QJw/0FQld1ojI\r\nsBwJ2Bz4e1U8WWEwxZVY7A+jLSBBGLKng/mwfGyCSdlI9vpRMEt6frS0VhAJ\r\nNpZ/HW8Vqxq8EqGm+0Qc/2airLXIqbAV0Nu+k11LDKRlpLtKxTO+C2aJxm/k\r\nby6f+FH1pe1MA0MOs/yBWLG56ef/G58Tq3Q=\r\n=tsI6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"9c2b4b0b01c61fc3051beeb16fa883130e745d9b","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b_1675311069528_0.5122594749080847","host":"s3://npm-registry-packages"}},"5.1.1":{"name":"storage-mixin","version":"5.1.1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.1.1","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"86400b64042f5ea7eb95f7b15e84c298a03c6d0d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.1.1.tgz","fileCount":23,"integrity":"sha512-gg55rrSpd2+2zoc894+kn8bw8tHdahXqsQKNcZqfR2YPVS+3GWoQVW3hekeFFvqVpqFBkKkELoi/7v5YG9j8mg==","signatures":[{"sig":"MEQCIBea2WXeE7TbgYTtZ4tj+Mrv5EIItBIFBZE6BBy/iyoFAiBXeC9QhORBnpwlBeehiJE1YGW432jMg5BPU3DnqCDGbQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj24Q4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmonjA/+MLnI5gwC3wI99W5qQuMAqPvlUpNePdvqeWRb+8/sqXxa/Kco\r\nplbbYDNvHbebqQn/WUH2V6nkCbXhGXJk6SIB2Hn9cUr64GRQ8o8CEMdYgW0m\r\nfwJBYHvAno+MGmO2k3jg8Wh2t1qTevAPNPlcXDZ3c+DSwUJppbGDrpbPpMCx\r\nZ8R8Eni8COKJLN2cbHFYzI9OYze+bngMagvnwZZmepOecoa4jyAAyafOKf8n\r\nwEa1LkSwdbJGnoo59Ly4k/ybOAxCPEXtO3u0eAY3ncWtZgiU1zkN3VcfzkxM\r\n0JnKwiWWv9taxe8aNfAyoGlWEmmxqIaTZoTRGCp6wKji3JTk2IK02m3ysWLd\r\nnuQM8M+PQRoqIR6HtRzne9psNytXcPteE4a0S3DWRfJLri5snjbs06/uehY7\r\nUJ7UZEgETmZHr2ey68oUWz4UhuvOwUlirezR04eLj64iloPsfHfnPOlZy7X/\r\ngd/VeWsfrbCvFHgFSOj7I4lbuozOVJt9EU6BzlRydivL+BNlIsnGhdineA17\r\nJFNRRc/s+M5epH9FoHvB6wxQXN5bIbwb3siEALqjIIDCRcObQOU/yAMXDQ2u\r\nLR8O9jt+olq2j7gHXs3i013nLPnuyGBJlct471kyNvRSLsd2Ix2NvTHSWxas\r\nUV/4cjdG4jcgVe7GyU/KI3FOQ6FXa6cenQk=\r\n=CUBB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"cfe9a829fd77fc84e090f2c7b38663167071ebc5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.19.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.19.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^3.1.1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.1.1_1675330616460_0.7569657991471044","host":"s3://npm-registry-packages"}},"0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5":{"name":"storage-mixin","version":"0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"c75207a3c53113fbb61473ab53e587c34ff7aa7c","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5.tgz","fileCount":23,"integrity":"sha512-EPq9uAhlAT2JZW9zmZIIq3+j2D3GVaAtLJfZGSOdUOUVeEHkoBtMRC2du03bfPWx3jXbDhZ8S6kB00oMg6uBkg==","signatures":[{"sig":"MEQCICD5bs3JD4nkvTSvZyh9c5t4qhThydb9iSECB3S5MoKjAiBAErcGkHYD+Z7L06Z+u+a18epBU5dkJICp1jiq45ImGg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj3DwiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpaJhAAnwJCyP/B4Snzpo2RBAzcAzyIwywxgXwkFDFABpDSPY2MflJ7\r\ntS18/BbECPX0sEORlHn0JJLIXkeHrbay5sQ6SKzBxPQKDU+IiDYMMKd5U9yb\r\n/45r3wUyUPK17VSAs2ZWnVUYsLtWG+HsjalWjRiOoYEF8JkWlSDXvpjAXDCO\r\noVQaf6B+y7gfENgTVt3L3jovo/SsPWyfkbPNUrcSkUaZPAxfpUnvlVBSyuN7\r\nsa9gG5MZPnMBmwtYYAr6AZpdkGB06QXvlt4VlSPpS9Aw6ICPNf0Su0A1msv7\r\nKZmN5zPjlEZsUzhqZA6BgFaWidPBiTDMznmW6CZ9Uvi36YoXR1YziMsn7IhL\r\n4NRs+WGePKalmKlLfc1gta7g/OheZJsSbtK7CfOwrGnTBTJz3vZNYxr6u+6t\r\nXhC+h4BRSIQ4C8Jlof1EiZQwrOXF+MFv1sTz9qQKu/ORvv2UNYO+f9Wr4Gis\r\nZ0PB5HYUm0bkJFvT5pCKIomzy6h2w7aeDsR0fH2KBId9QxCwdjSD0snXRI+Q\r\nD7i07986AvPLISUHbSPhNSfahH1fpPe26UfrTbaqK9e6LjvQ3DMpxE/cV1aJ\r\nYjKWXp9/nk4BOI3EPI6nJYAa1AuahiOpu4M8OvG2K1YuRkMkEh1rSLvpnXaL\r\nZJdK4qGX0C3WlkPRS0UR9qDbV2nwEmmMVME=\r\n=Eyfc\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"cfe9a829fd77fc84e090f2c7b38663167071ebc5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5_1675377697866_0.34512454344966637","host":"s3://npm-registry-packages"}},"0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5":{"name":"storage-mixin","version":"0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5a4725baac194a5e18c509a3ca1dfe00018c754f","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5.tgz","fileCount":23,"integrity":"sha512-WjrWQ31fJpRhFH4gxcEv9nt1VwjDfo8x7dSQnUo6H6UAVBhvtOZwXbvIpTV2eZ+M+hLyaT4JVGd5hdyHTIe5zg==","signatures":[{"sig":"MEUCIQDA9ReKd3Ar01ZP5H+l/BckeZdSgYi9XQKQ4FUSrfMatgIgZ3A/4uLxRzZmjrhvb/Mxoer+XiVDft/qGPr6wXtGQSA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj3EZNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpcLw//aE5/IOuPLAL/mIPMYZ2L65a27/MA5ynX+cC9Qyl0MacMQFbJ\r\nnZv+sYihjlubaS7yBQOO/+v5VFdZAzTCIuSzZN8IK618rhcjn+ShJaCN0jJx\r\nIUAis0rFnrbzvksT6IB2jlwcSWOJ3GjEKfATwT+zFzAH/wk7mHbWcYe5HBm4\r\nKKux8U4uHGkfGQmZwYTnkpzoD/8aMyzlJT8P1Hl2b38WdUKzx+zN+F1EjmIl\r\nW0zlVUTC82QbFZeF+jiJx2tUJAjo6rqJ+3PmC+KRc9EBI8FrxE4z/SFS2FgG\r\nySBUJo9tkLrdSxAO0u2g6i57MIKWsJAjfdQJzfvtwFpTxcdyjnuzp7NWgPZ9\r\ncJa1JD8Ia5UYb9c0JHoH2todS04tOX3Ey7GmBwD0LWFTPiKqK5/2GrleOOfK\r\n0fYy2rUhW1QYFDDTVCiFfbI38oWQrwA0u/ubzOYpZLas/YYJqmT7viP8x21h\r\nBoIjij4fNXXmzf/jRkas+Eku6naj1f+uQX9wpDXRwMJOlDe5Q62DjD3ImCLC\r\nw2jiPd2a5iMxUYPXcwiXX2stJW2H3LVkGY3y2CCt0NgTUZnkmq4cXnHjJIfe\r\nH+SwTjx9FBev5cs47FkJ05hAM3FPlelks/CPAbIvDGr8ySEbSRd4BrvDcskf\r\nukb5cKR5keZZOqOFOA0t7iYt4Gck5FZUvoU=\r\n=iXUH\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6e4c984eb458cbfc675ec138ae979303ef32bcb5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5_1675380301128_0.5510705799319044","host":"s3://npm-registry-packages"}},"0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896":{"name":"storage-mixin","version":"0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"b718320ad15e639908cf558eec923dc9c741a1ca","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896.tgz","fileCount":23,"integrity":"sha512-q+yBAaMvARo7V0ek7D4VGmJ6yKa66aM7c45jHQOUUFfG9IZ0YwM/lH4Qa3TQP2hqtQx3EaP9awrecmaIeESByQ==","signatures":[{"sig":"MEYCIQDX2TVqML7rPNBJ12Amq1Kuxoz1HBbvTs8iNsBJejT1OgIhAKrzWwjCSCp78in/8uBYa7icExwwG/8iWfTNiA1MNayC","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj3obQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrVnA//UP3zUZrGCWfE+t9gJlH+O+WIUllQ1F1NuZbk1Jo2Z+rBXj9U\r\negNhe3iMOV9uq6vdfJlJEBpCluCRYTtHKHCPvYAeLSEkGBMuG/nxVJzWWWUu\r\nXOBEZmR2idicwGgQk6umkGRlx19iMOpWzV8UlS6tL4xoH5vqSHKuxEsR7d0q\r\ndHRPF9GJytK0KVSKhtWqlOpGMYrBahkOab3KE6wxJFsHf88VHyNgMiIRqQ6S\r\nrp35jBBsKiSl0HkQKCz1j1N4jTOzYIq0pdBA4qH+VEajeUJ02K6yBd7bWGLJ\r\n21Pqk5Ma0D1qIDMX/MCtmm03/SlAof9q/dUTIbqHHXMDcgbggrFeMAJn3Go3\r\nTyzaFIOpFxmgYW0t4b+or41eJpQigygRjWQ3dlhdqYA3lFTrd0bPes+ydBkB\r\nSJeD31mpxcDrG4+50TVPHQjd/e4HjPTeDZSe0kqKnzG1l0KW9T7r+0YuKMzy\r\nRrmuo6o1/QCH1c3p4BkAAEmDK+aO572UWZgd7VcKwLG5k1DuR3gsQfe35RZP\r\n9Btg/7VT/v11TCk/egNJwSEyQy9vR238RLxYNb17GN5vK7jZoY8U0kZpUgB5\r\nstvo/cc1bibA6Sx4qGs/qkZMZljlIYmAacLhfgF5pSyeVtMtTC844nyPK00Y\r\nJPNk5wmKW2vOarjP8zc0eQO4yO4UUsK1RcM=\r\n=LKA0\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1638fa3a4f457428151ba0ef06b33cfc4a77c896","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896_1675527888260_0.012460349593155229","host":"s3://npm-registry-packages"}},"0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a":{"name":"storage-mixin","version":"0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ea86ffe3d5cddf6483035d85fc505487d73768fe","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a.tgz","fileCount":23,"integrity":"sha512-NmpZLZYKIANfMvauREjqySPyfs2NxcJuhfxdXrEOOGfQ3INDUo0iCOpjQro2L8JsCrFEQ4icT25E5Myu10Ed8w==","signatures":[{"sig":"MEUCIDuZP52FPw1Ew8pao4eq+2Pqz+xBG2ubDjg/AEu0PJhEAiEA6UWY16X0IAAr8/+jKjEIwQZ6IMwPOOyhclyuu0rGiWQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj4WRdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq7jg/+J8eEiMcQ0CJlCBWiQHQltOeZko3e7YhR1ysKUd0Bm4AXbx/7\r\nRJPIHQu67k5Eil9+zd+IBQ7tBXTKp3jmdtBqPapUULPzqk0LQM3b8CbEv+Eq\r\nsdyY+U9J0Q+H7ObqtrKV+N1cVd5qo7VvteEKbAd/8QapIDaMP94YqlzJoT1H\r\nLUlCXLXPNnDlfJ5jT1EoOMfyGa/840YhuHZ6KDgX2GleeYdCWuYNynf0RBC0\r\n/mE9VMyxhrKsGtP0jKn9ppkQEyxhfpOLMGMGY/t9Gx3OAenFB/AYnABc4rwP\r\nNS+gIz5OI0X8y0WTBUG2TANhx/6tU7daA6IwwTc2B7ihhi5NHxYK8XSZHjS2\r\nUCv1zCxecaQOdwNKXJWMlNKOfpFJx/B+N90sazWKStslkoRLUcmSpwpxYuVq\r\n9/ha0U7vLpv6gK+aACaeUES4nfZMmzNbRIGBccXNFhs1b8g7FT98gUJ/d27y\r\nBpKgHILpe1DY9s3deDzlsavpliHyBqi2ZlJ7ioduSv21oc4a5XRZl/DVZW4Q\r\ndb3/pqWO2L8UQaGyNHpLIXzoP3BwA8CL6CBxNI5XtJD5QsmZNc5KRGKG27pf\r\nE+L9OFgY11+cy6d79LUukwcVRLzLD4r6b26brWpCI1H0vgAVpxLustzRtAyM\r\nycSpssc0l+++ZWaJ+9VhncAE8a1RRTQCZC0=\r\n=ulrQ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3e67b8063fbcd84b0bfd6451e2568968fbdba25a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a_1675715677627_0.5559539271166609","host":"s3://npm-registry-packages"}},"0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e":{"name":"storage-mixin","version":"0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"288595775584cfbc0e48c2dcf74d0a7a38f8b094","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e.tgz","fileCount":23,"integrity":"sha512-YhQMdeDxcWhsMZoNmuuTW0lF5YTmzXu1pdZ9kTGO/nUftKV95xm2dh9nXr8Fg/tcoWM9yVezAPpEIObFyehBAg==","signatures":[{"sig":"MEYCIQDff0lAqmlbLAStclBCy356HUHtRg4Zp1HKRQidDHTB2AIhAPJ+UIjKbMd1z7AnHq3XWphEfA5e2JxrttvCFnqcpqaB","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj4WSEACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrViA//Y16eFVJQeQjBWpAHe3GJlj+NS8hAlKtwpLB7tVuLMNZU3Gkp\r\nrqkUIUYzskS/+G2PikUtM/nmatiFOYXq+mRQ3n7jtW58fDwTXjHu5sYzg/n1\r\nVp7KAy8s97wBBL5J9oC9NYdDFn7hPsH7Q+25QolOq2T06DDfYbwto/MGeBc4\r\nvf+f1oeKAX39XbvB+xZ7vORsozRsWEVVgsQEXvD2K8701SdQpMWIIvsCgwcy\r\nRq7V66eMLuGHCHY5c0+sI5EqyVjOuXqUpzsEteyv0VJbPPXar/OjcmzpOSg0\r\nZ3SJaS7lsuV09EAukpnJOSDRZzuVBdw6yBvkBtyC9Zl+UnWLrhPDEdL/fcbF\r\nr4579oRjQkoSNBtgphFus3jG/0/xgStnt1QsMZBSXnW2yuSRfni98av0Nds5\r\n0Sga+xaLcHrSn3hnu05NibW/NCmyVmI2leluubTcNV1VgS13LEv7i0GQsOmg\r\nmD9MLOQjOzoID1Uge4r9r29s7cxVJdgF4iVJfkhKQQt2GltaOqZJ/Lv2FEY6\r\n7WGIhLZvtV//gkKq2uj6fnSyWtPI/ybvAZNF0ddIJnBDxJNLDgrc6hg0qRnh\r\nbrpXVICT117mYZfN5IRpZejvrsS6E3HcuqAMFEGcRJO47zEvo9K+pr2ru8xR\r\nnzM0EL/5Y3jMbIJoG05iyv6GS7gSUlxIBEs=\r\n=4yu5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"920407d9fa8e9bc60bfc2577492e5be59254432e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e_1675715715964_0.29308735700813004","host":"s3://npm-registry-packages"}},"0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1":{"name":"storage-mixin","version":"0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4b5bb9e8aff241666dabb323bd8bd6b693c14c59","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1.tgz","fileCount":23,"integrity":"sha512-bg7fgaaSNZBWthNkPMex5hJQRE5zoVerwmpiwvvziw5q/JDvxyRcfTKsnhh5dnx93AMvlBdrtD4KeOvzYnPeHA==","signatures":[{"sig":"MEUCIQCuDOlSMXb/5BlGws+u/tXkDGS90OzxvULGEzcnlaUKRwIgUTEy38l4705235PhlfhzxGXtQxLrQ4XJ+cAqdpI7sBo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj4WVSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr4hA/5AX8PXhVG5bJPi4uCu/k4Y8PRpzs1x/7YBH+NGn5I2RndIk7M\r\nmvhaY8mTLEbo/0kaXdE4n+2QJp75Dy1uVidU4ebhTFOZl61WePl3fk9CAUTy\r\nJnakBcSTWL/UXDEz8bAwaKIUoKCCyXBOP7VG1MwNHCSPly8r1E+mjWgZPpIT\r\nZPI/oMLy71XnqyVg9w0eGjBsKczoh7T/QlU/zvIozRumaDKjAcSxO7xFZaBt\r\nghV8zHfARl0UcZDXzchIsZGDPmrgcRn9vDkHw7Byh95GkrpnaESs9wBSIG64\r\n1jqafHK/dM9Tg5dSfCJqtM5Ox5fItTzZ/GWJvmkbQLvkn1g4rxtzaHFIf6QN\r\nWbxYMB0uWgi3SKaxJan7qa8xjAldyGtWeNqZibsq5c0S1k0+oUE3kCC6Er7H\r\nGYWuqesYrdj62oD0uMFBfWb0CuIZSgqtwDGKi0Gkq0QR36Lxapjfkpn0ji8c\r\nTA4lUlkJS4j4Uo4kBY8s74DGqp29UjIEtgJ1xTpUgOg153BEo4fnULmZVloj\r\nDVQ0JGHNbaZDgtTzpuGfd3tWUGDecgQ/tul5Z70k4sAGB7jVD8zfhU1SLdZn\r\n/PkNEX8QYAdmGQdN2yyTok1ZLuCkyxyczj2F4TXMlx7R4txrH0IpD+euZfUs\r\n1zPiqA5VIGuMRHArarcWLydUYBba/sj6tc8=\r\n=TQw0\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"7bfb57937adf16eda85ca92547ea5711d120b4c1","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1_1675715922027_0.3729855640878097","host":"s3://npm-registry-packages"}},"0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84":{"name":"storage-mixin","version":"0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"dd7e99c8bc9ef2cd872d09530fbd311dc2947aa3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84.tgz","fileCount":23,"integrity":"sha512-oSSFF2l4KaUU0Kq+GN20KHoM0kX1NpuJoQgigXUX99EoBgONrbI6sWZqSieyBiSyTMgKuIlwz19r3Vdumj7FtA==","signatures":[{"sig":"MEUCIG72MxkThDwxN3VK5qdcI3H+X+/WIVihwOEkGviE9xe9AiEAvnakNj7M6EnEnTSbbb/XWxm+OFyFlSNsWiZ/TU1U+io=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj4WWhACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpHGQ//TrXUraTwOCQfI+UQTgqOMbSgEmI6+lK/Y7deQZWMf881wv41\r\ngjLkN9z42f+6BV1+vl1vlj+ScJEseZaxKcpzUf8R4AsH8LuEHOCYRQ7rE5ux\r\nOkflM4jWsyPi16JCouBCzJX4UD0pFezonFG9pSu1BpTtZVli+bdwKWJGSZB4\r\nfB6vuyKM27bo8oQYvxr7CVtS538/jwCtuvVC/ZrPTW4Y9wH290hqhnGBKnLa\r\n5GS3g4xVDlcVySk4KgsgCewk8umrMvAPpB4HqJxHfT49eIS89P4xqO7zh33H\r\nbWnvAr5PT424vhaheZLfVewDOdZv7eD6R5mn69WtccuvXMCSdP5ea1qbO2m5\r\npngDWsEPFqje42IGOXTXNK0EIRnjAc3gfp7vDRbt1pcbsg27FmL2qFw6Bn2G\r\nEH6eFJbyCWWqInxXLTOiB39S/54wWSZD4aFa4VnCKPlnHr6rd2r1Gzp4yS4T\r\nNdsxgRAP4KoWSdzFbH/jBQG7iQtIY2o6qrKo3RQjnTsIesZoTTpZPdA/m3IR\r\nfjZB2TUmNekMXmGsoVl8MHVsKVPsC2W0X5lhxrAtsJn++9HV2sNChvTlvVoO\r\n5b8H5xpwmiR/njcr1CKumcfP2MAR9VVrB9yBr4h99D/wb9IFb2g2ftGPfn5N\r\n6pnR86E/oU8nzI2pjDePrt14VW8N42uFKoE=\r\n=CaXh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3b389244f7eb06219ec1e923cac29b45a6ec3e84","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84_1675716000859_0.46691699784771346","host":"s3://npm-registry-packages"}},"0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052":{"name":"storage-mixin","version":"0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5d78c2ddd7276e6caa5e48a3ad373569100f73b3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052.tgz","fileCount":23,"integrity":"sha512-H+iluwZDMT4uzAQ3GcyBtKlnJy9ub0NdHEkB7Vh3t/2BGa0L3Rb1NGnjnkwsjb0ljZKEBJvEKokuCzI0RRZvAQ==","signatures":[{"sig":"MEUCIQDG/AZxpPvRPmvmvYUX+F037NiuijR6Mvqg0HZQAz9LFQIgQe0NI+sAptwj2JNTNfdDcuJL12oSZzeg73eWzugWir0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj6siWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRQQ//S3VsBO7o90c2UMr6l57MNS00z4iuAAT+wyiZkBPu+QhTUCL8\r\nGzswzDFjeW5oQIqlFayWZMq5zwRBnMxB6L6rjTKNRILG4uftgTvo8r4fLiD2\r\nuE/sIBf0Im/9/6ErKqBYShxhf/cBl8yu2S/0lIW65J+NPyfZXzyAdsMKZOAi\r\nY3yYrtTNIG2QfJDPWBpw4P2jbJZKtTBnM0rFD+eibxp8Uvs+388iIFQ3O75o\r\nzznHqyNCBN6sBxQHFcWM8QYYgpQdqsq3mnKxX2DschffL+nw/Gf2DckuJKVg\r\nCNYc8mQ7uJZb0eh/obvNZ9W6BWoNOLeu9BDZP+l/e11Enh5PGKc2Le6oYgfK\r\ntKQETJDDDfXo6hsQBSAF+eoquyTAZVpz2GcnCKx6fMxlKg1vxRyXqp0/2Eol\r\nCJ40E+MC0jIfIiLTHp9V7AfKcXAwueiYIEiCG8EuDVWYPnBBFLQEfNAtdCln\r\nQGIY0QQTG3LGmJcLkIMK14wP4wuQTf0SRZGQSLQGRwaKm6Liw7LtCFVR3oYm\r\ny+RolKM/uk7lANtNevd6cMCXBm9guCfagyYBoQv8PVjzwfqrwFt2Ev7k3P+/\r\n5se44iMKh+H2OnThQ0ger6xgGJWgvpVm/R0Ti3nU8ChAXMQ/hQzWrojZZr5m\r\nVfm7KD6LayTPYU82UyRvoBznJ2HCZsWmp7E=\r\n=ZThM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"014cd3f52319f9c3e62d458f4c10e0af7ae98052","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052_1676331157813_0.9042993896835907","host":"s3://npm-registry-packages"}},"0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5":{"name":"storage-mixin","version":"0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"9c7217db34e6eb020ea9fce16a7e477ab851d4b1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5.tgz","fileCount":23,"integrity":"sha512-YgTHMNaScaMdddHgo6fj4bwoNkuro28GlRqRE5t/gOUki1eJvnnUCP+8SuybKki3ATBjfgE7tzm7K0R9yluFbA==","signatures":[{"sig":"MEYCIQC1L1ENFfTqH7FpvYu1FcF5DNorhbqmHrKYaL9+7pAoFQIhAL7kXwBjNvQEhP3E0EOZGSuBUBuZgW5iYeDNvp25xL8S","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj7CG5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqGJw//Q7qpedNCForGiK2FxcsDAkb+YLZ0rfmYr68KYhyjOjSr0w0S\r\nIQKeyPc+RFgASL7R7tvXZtiRzzY1Kwt3wETOcBpP2K23jzRcVQjz57ogx9rQ\r\nAe860xEy20wX6BGjKRwHUaIewDI+NtNRHOwpJotNAE7t4k3WNivaCviqZWrU\r\np+3DZIAKojW0hHlOQh8urqpXDtbneol0YtYc9Ic9qFl/JkvAy9qcFGiaMzxM\r\njqEwwTC+mf7Uh3poHV3zAq9Uze2CfNHb77k0PAOhPGp4IxUTotWdnbu2ObPG\r\nAOTIfh0ko1v05kYjgu1byH7x7jAoMwKogvggVbtDMILBcf7rCYxr4GSNWJgv\r\nIJ61rivKOb+/HpNCsvwOc5dr+KxPoP4fa8tJ4G6OOuzkrAjsiiks/MdEbAvL\r\nIRenl32OU2fQKfgceA88bSlakptinDtfpPdJx0cClQz56sHaKELxzSG5ItjG\r\nTJYo1WNti6CIOgNCiELPs9mJGJxKo9Ve5fDZOoY7FEi14XvS4FR8nRewvWtp\r\nlulwO/VHjwOiRfZsj0j7wVh8zqCBLaDiVpKVy+ZcCqkGviUkIuqGeaHtvNLA\r\nouFnpm0oLMFsbMiWZ3n10gwNhQPsgFdES+JJqw3WHMQbFxGuZY9PbpVdo0po\r\n6z74bHHP/ET0+dBPrKLK6PqMQNt5ySwnBlo=\r\n=/y8V\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"887a3dabb2b894331aec6aa894bc425e2dc591b5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5_1676419513258_0.6262660628025667","host":"s3://npm-registry-packages"}},"0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463":{"name":"storage-mixin","version":"0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"aa88d6b2a08e81a535e0e170681a35b25b58a949","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463.tgz","fileCount":23,"integrity":"sha512-6mEEK5zrsQ4M7yOmGSsTvniW1SNO4khmrPn2J7i+j54kNQssmJT/sLa7IcvvJzctK96XD+Wjk5/jjvBfs7MuVA==","signatures":[{"sig":"MEUCIDN1oQL5jkGaydDx1N5ROJotXksgkSvRpLtxo2SCids4AiEAuLcyToXmaIW6C8CFD5WlYvUMtPgXpUAqbUA806GH2a4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj7LitACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq2Mw//Zsx7AeaxmMNIetc673znv1apUb/U3bPp0xWrekDTaWHEz7Oz\r\ngQjLyWa8p0YOs9rVdfwE757VwaFyT7KCIeUDKW1wV9wmPDtgv+gCca8TnOu6\r\nCsFeeohqSDWJOHuTtHLy2QXtsAZUIi1wjs4uOs2Y2SE5PeawAZYkPkB9w5JV\r\n3oKiSob7wiD93LtKBpUViNemsDzF2FJzbNMAazG/4sp2oG+9roBaO0LsrkC4\r\n+EY+Zdb0x9jj8jslWK1McrcOcAC4PacwSHKtxnOKPQb55HLuBbIHjN5Liwea\r\nSI6DUo1wepJ7tNFWGOFo32aip/FsQxEKiohjlISxokv1ZK+XeSQiII0pZdxb\r\nE3s4kml6uhiK1dMB/RRK66OfxWG/JN2y1B9slRgmqMghMqjhuK229VNMFXDW\r\nRYJSeg2jNqI4p60ZE1LYJ2RnYx1iP0dhl4NniQyl2wb2C0fXXyCU3EFGSfw6\r\nFWbe+NSEA6BqFTasIUX0gKbZwgLUu7M8lN5+CTojK9pm3Jc/Lz0Hg3iUnXYH\r\nsnk20DaCgT9CizdgGM1GOrqJ0pk8ObevFc2ANfIxQz/bGlZwPbIaNYbniGk1\r\ntxC14IKmxQ83rGpRwW0I4xGrOB9w5TU30OUbm6r0y89hyYwnkeq7qv7Q1z4s\r\nSc0gythFhJeIcngDvw9EBGeBZqwWqDJFANo=\r\n=4vYd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c5eba7335c2da0b9754b4e52495c98f48ec15463","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463_1676458156946_0.30812500900936834","host":"s3://npm-registry-packages"}},"0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495":{"name":"storage-mixin","version":"0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"732daf14be64021c53f2fb5e4f8b766b11523b21","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495.tgz","fileCount":23,"integrity":"sha512-HcLSp0T0F/UhiNcHWF9ax7/8K+SfP2PU4OnOMFPPyxYUMhNgdiOO/jiS+WrxjJtkw9+EnUyfUvxFehPEo44nUw==","signatures":[{"sig":"MEQCIBwx5ffbiwsFtUL6OOuRlg0rwAm6yvhtHSCSFmUcjVmMAiA5mfknf6tbfyh0Ql2iNOeBeZ6zM/zBOUbE0umnAJTZCg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj8+dLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqKmg/9FNGUYp/ENKcUR2zeEKK1u3C+Aw1JejlKb61XobN8l+Axp2dN\r\n50niuft1PiTkdFnezfwvJ7eTC1vYpjeqRyqLRi+0ip5CI7RKCGQBnR2KP85w\r\nIM41RLskICU4WkTE/J2zgvvT0VGNLNay3+Vx/bb9MG6uEc/5+8jqqcjtQ3Qe\r\nfdvxaC2MB66y3vtoZ5qJvJHfTHgLZP7AmgL+mLdemHTBdXC38vQOSpxlQ64I\r\npv8WqLKv/mbBiEeY4EL3KReQrCkRvbh3MDqCdiw12APxev4yVBOb8r2NPaeJ\r\nDD0l8khcNrbMm5ZAsyGomssxL2Pw8KLSKOV47Pa5hwSRmqA0rn1/cCQiMStC\r\nkWI/ZRnZooWqwTp6eTCW+vA4XAT9BuvZF9diYR6fnLWaJL1sIayfeU3xhWGb\r\n81CeYb1nP6D3utwS4UNDqsbTZHXNbRFx3lWHi7cu0yFQWm7MYA7SyHR6RHDS\r\nGO5zS29EqFCLudkcEE/wXYfPMOpQVyMsWBfl2Dlusj+Qc0Zpz9nsi9gBVedr\r\n87iF7OKRwuZNgR6i3Rr598E8TSiF371KXkuWsNnxeGwisgp3tiKifmOD7evU\r\nAOC/g02G3vSwXY0hEiUd1IjcBm9oTOsB3Oey4UDe+eQkyZm/pA1FV/FaEM/O\r\nNkkWlFeuWYDQb6T5O4I2jqMplpr1+FthjK4=\r\n=98YA\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"9acb1d074fcbf6aa34b275f617178f0f155ff495","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495_1676928843246_0.7228027501872036","host":"s3://npm-registry-packages"}},"5.1.2":{"name":"storage-mixin","version":"5.1.2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.1.2","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ef15905ab15f6273b90490a4d847cfde20c18b2e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.1.2.tgz","fileCount":23,"integrity":"sha512-ObgJH7kSjVXczaV57ezP21skD2QsOeV2Tt6gBM93J1IEa7DVyP9sc5dncthSDlwE2V6kM4FaOPU8mrf4dk4T/A==","signatures":[{"sig":"MEUCIG6Ia79HrT4Z68gCymQlrwwRassPSLTYrQN+qPRHifnhAiEA22izJ8NU07gzXcL0jUmjfdX0PjSnHfp0b8Qfzh1TluA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj+SIwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpoVxAAk9ubfq6SHriqea4JSjZs2bED4MCg8m848N8QwoGm4dfqdsr7\r\nnt2MOYeVQiVzho9z8om3OoZp4O9QNncwpnQKpVP/5foHB5PJ7ogAJOGqPPR1\r\n1tpSZG+uvp7ILkHEGg534mdTexQWP5iK/8p6GOGRrf2qOHlo4aLsvHtw1biF\r\nXRBQMPsX1TiYwa2HfyqJAsSNAYgoabURVyuVTGwTa7oaLuDjGEg1OGl5pjfS\r\n0SL6kxfBPjulBaANNomlDLLDurn1NEEfACPPJYcyBeMcZ9NSTKaW5c1P05l7\r\nGhCLqLo5AQXmF/2mDSgXE0iTsFJHFuV4l3IeUaoOQSYIeGQAkKaFocaW1pzv\r\nDNpZJ026WGxGdsl+OhJ4d987t7O9V8xMO9XTW83KQ6jTWKcdzV1CwKxfQkjz\r\nBD/VPqE4tA8xp8KkrNGBpo2PPnX97C2ZgV4CYFcPU8ToqAfmDMAPeqSt7pKm\r\n+w6dWn6ycCQS0zP+oj0GAWA0tfjc9NqOnVvREErHrnyC2bGa4ZBGj9XpOrTU\r\nSpxe8pmiI047weJE8+hM7lI0JTMSKqqbZXBJu/7b1NxMnHr0LgqmJ4W8WPz8\r\nwej+U1QgdaoeAotI6HbrmGpxPvYF9Ijg9lHfIiKTO5vLna7vQjSSd8aF4nYE\r\nN54PkcO+ClFIg5kvUkhdb3fv66eKaHZcFx4=\r\n=g570\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"96ec6b32140254def920e2b4a8dba9be56633f75","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.19.1","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^3.1.1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"^1.1.3"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.1.2_1677271599966_0.6065252486796431","host":"s3://npm-registry-packages"}},"0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c":{"name":"storage-mixin","version":"0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"19fda86410f80e47a614a2e90644d4a225e7a593","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c.tgz","fileCount":23,"integrity":"sha512-evCPIp2HKAZI5OdVWchAUi4MgOKa7fN4UeMOWPL8GEEyqtRs5ge8UR8OaA9pk6OPETVtPu1t5rIxH4SZKzGtnw==","signatures":[{"sig":"MEQCIBizxnutXHWOt/SsPdpzjppBnu1FuOkvAvftEwMxaPNfAiBavjI70j3Nj1ZLr+9erBzbH4Ri8giRvDEQlOHBiVk4GA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj+6oQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrHYQ//ZXphafDgvyJqCyZheueC1Ym+AM2dMGxQmbYryWCODWJ4hyZl\r\n1FePYwNr1+65TvLLA6wI7NSBaX7wKHk90+CAjwFaRIm79L26cGq53pko5clM\r\n090rpzLqgnRZYgTQkTpgMvEjQGPKurOpBaMA0A879+ebOuGUH8N+nJHaTFWd\r\n8jTz4b9/e451DKk3VXFGhEE4F4DVFutRlzZBu8KQj9DDRuxOqgzZPtPvFiNP\r\n69xjBAYrvSVru6Hz3tSb38O/goir60vgp7WW7F6d2vEvJFVgv1ovWwNm5J9n\r\nrU9bMCtclIRtjm8PPlp9QJhEJBBUrawIBa47CjmtwAtReFq/zvTGq5l2j+VY\r\nldU87GRSkKVZ7v0FXeiVJyodbCek8wXO1JsZKFJ4issDUZ9jSbWE4VmMm6x8\r\nwJxPYMxV/RFSgEE2Nh+BrYiRtucVmM/5TEA9P0g9ewzZ4mLzRiSaH9N5fNje\r\nK8l6IeRRJ5d2qfCkydZeU1Jc/wF2ul5Lut1OEhkDh17hCAnqgEb9s8o8nvBo\r\ngr6+mpX8NDWDedwJwzvlASngEyffMPl0PEwRtA6h2EyPw4FRb7boBR6qPEab\r\nyJ5RAswDkYisPnyQn4wqmi9wDCyG6bLDr9+Deq7fMnUKbpOj85GYNeUcTkB3\r\nM/4Y7DZSkBnCodb2TnxpZURwwE2r29c2kTM=\r\n=gvex\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"7675c98b3881009dcc19690b66a6e63e65e1a13c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c_1677437456470_0.011343231183766678","host":"s3://npm-registry-packages"}},"0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24":{"name":"storage-mixin","version":"0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5c1b289ed3f168978a259104a777dc32e8e8cbb9","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24.tgz","fileCount":23,"integrity":"sha512-qHvPAMgdEYUTVK2bIshXRuDkHTrOdhNaU6T1knWFpsy8Gd0MoiLDu17DK2Xc4pit6hNtf0Mr7uiZe4p5mtocIQ==","signatures":[{"sig":"MEUCIFshwscts78+JfofDyDrk8EJy1ZFkIU+bm3JMDQC4EARAiEAsQylmkxFKSKYKA8X5V0Xi7OnaVxtEtYIn2I5ajru/u0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkAGCRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqc7BAAnMIFkqaqQAHl+Cd8v4rk3ivYhbvaVs/8B1G3wLFDAjbKuTjQ\r\nAQpg2pecTz+CcDTgp3Jr0LTnggzuHz/WEkTzMR/S5QW96ZYGKngXFLSrAWQz\r\naLMCZG5WIvqgHwU9DRxw2ylivKQ6rrjsJYDXWOGF5lz167EwrYwSroDOogqg\r\nYVQQ4Nhb9kFImWkCztKq0NKK3y8iKkboU8W7W7WKwL9xqNP7QzDDKkbCbnBH\r\n8WG25lN8ZNKMQkRF5jAMvWww2X+Jd3sjpNmdun5uksjlEYva1BPvaXsu/bpf\r\nGWbF2WZWSi2iEfKYTYsklp2O/aI8TRL4mMmHmv1A22RmIxHsWGwmKh6OH3H+\r\nO86/9teybKS4Nk3/7p9Pz66oACvpPirVwPMZ8DeTgSdXgkjZBVmW0r1tSmyK\r\nCUxGz0MpDa0giTS6fM6VBh1n23Z3POkCqJL1yGF72qg6nNnUUW2mcDIoR3Tb\r\nwsCS2j9ymhxYU8UMCC6MYmIKVxTTuy+S+KaIHGz4HPQTl6U9+EZMEGvvPl71\r\nAjR6c250qPM0k4qghBpMrEWhEtvmTOuEII96nulPnZJnZhbqN6cpRXEruV8I\r\n3vH6sl2KbWYUEub8j8DczXoZQI3IGFYe3fh/pFj8bztu3uS0FC+Z+kVdr4di\r\n4SZki80F5ayT11EYOsgv2M5bMpgPK7MbqkA=\r\n=fq0/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e5f447d1d4e3c5e91efdf6c7e380240ff610dc24","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24_1677746321114_0.6311770559709331","host":"s3://npm-registry-packages"}},"5.1.3":{"name":"storage-mixin","version":"5.1.3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.1.3","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"60e760b93e9f6bea804a9061a8cf5eb7397893c9","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.1.3.tgz","fileCount":23,"integrity":"sha512-SHkmTv2lIJPE/s9eqptd+rmPi+hTM/t1V1wJ/P/hkUgj39PwrHzXuG+wN1GLls2SgwfHrjOspjYQQwiOtREctw==","signatures":[{"sig":"MEYCIQCdbVbUWqZzvomhuo/So9zpCw9WwQ7p+DxWbhIqCfgNDAIhAJI5GUKIVmg2HvAxWBKDFFAkOdyU0zNu3M61arOCa8mH","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86547,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkAcDfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo2CBAAncxAPSKCXR40C8/J/3Ca1W8LfasbysrVB61308VOlIMIh7f4\r\nM/noZBUNpGFDlVMypwKqDm2UDmK0c2nSw4ugjsvsRNq2mOy2fFq6UD0flCKA\r\nX94RdygRNKkITS1BgFcmL21D1QErjvU8sKF96VpiqaaoENwKeGRoTu4EeLmh\r\nHZ/3ycg811zUl2sWjOmUyNBcdOhUhVhOgfYTztsPnonl8d4aYQgBC+TbOjE+\r\nvVkIiCQGt82H/iSQPpieSxWNdSM6NgqH4g8EJI9c3/eJ3WhUeXYghZVlh0C1\r\nVhq9nWVF8M+aLgd0NBd8bVTU3+tO+EMXR7gx6UTYuhp3l5LNjYjCIDONgiR6\r\nMH1d/IVgfgLDYW4D4M3Rbf14ubsJtvRTjG4fulsD4+zNTeHEYvSML0uuFz1X\r\n4NbO6LlgzyO8DjIg4Q7uhuHkqAhCcJXyb9jt4z+T3YRK68oXZGCzcJh2V9LO\r\nz+uxMh1wlsBKfXnTnBiOfOLUYPqjhUym5834ZZR2gQDOyN0VYbLoS504/09U\r\nqYnwL2fU6GpjPEeqji2/8WJVEnj3jd1wY0fatuEXD3wCexSCZhcKoHI8hZ0S\r\nQwEXNi19vteIjyGnG4L9QO47kk5kEil3IHbVoIF3nTiiB1Dy8pveS+97MaAJ\r\ntv33Oe6mypD6x4zPvLhzDXov4uNEDRCGI8k=\r\n=SU62\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"fe181eedfcb07251b9b9a3dce8254a4941d74e42","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.19.1+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.19.1","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^3.1.1","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"^1.1.4"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.1.3_1677836511185_0.7314845306942774","host":"s3://npm-registry-packages"}},"0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad":{"name":"storage-mixin","version":"0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satyendra.n.sinha@gmail.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"adb17f089acd712f4e479398346baff9c931c43d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad.tgz","fileCount":23,"integrity":"sha512-Ng7Llbc/Rx7LwBDSzIkEeO3i0eZCxsGOXF/qYKxKFJWqAXAQC1XFJb+GEIKXiE8Kp7biUE/RjSJ7fvSNvpe6wQ==","signatures":[{"sig":"MEUCIGDIbR6e+KeYzcOaRF+nsLZNJN8tdDgTuqafd9oteb6yAiEAmu8nhw5pfR5OIRbZ58pGJ93H4Uo3fHUhGj+fhD5AWWU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkAegcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr83Q/+L+bt2hF/FVxYdcQQIyPzUgiDpDV5OKM+BvFGJMwgiISTwayT\r\nfhJhWQM8+UK3E1sLHRCb0rGhj1juawAOqLrK36fOUJSCCOqHgZ0zBmaF54zl\r\nptHCxeU/+VaWOtX++oi6gMxO4e6ARR3zl2IPkY+8sGGF7m0B0kYwYObUnlQQ\r\n417L0woBLVBINtj7EtZ2Gg+/0u2izJzFJM6urhkyUyY4lSfWPxEbcONde6ES\r\nrbPzVzamHWuNNlYqDRDGMsfI9oKRmJOKsn6GLNw3ygdiwR1h54I422n7H9T3\r\nq34NWbrnyHNkMr193KZk7xHwpZHUviI7iLV3v/hrK/8c66MSvNK69h/voC1M\r\nD8JB/FNslegTdpA8/q9kDmUJCk+Tx4LUTjRHFDs7BJ5D9qDiMg++ivMq5M3O\r\n0W1+jrCVXaPo5wFJ0509dA6YAvNtMBI0pv3qwGNRA4/TSnivIOWMVabznjsq\r\nB1L2yHFJPBlH4r+Mz79MEcgaQvHBpvRRx1Bysb+X0ANCqRPjMKPNqQPwqPkd\r\nVPLs1cMAUXFRuQq06bF05rAJ0kjnlT/wM2qXuPKoUhdsZatKaiE5YwEd9EH6\r\nZETpD0HDYLpE5OyTOHpRa3qSdhdGbB9oOzPHrRbD/W8gB/K94Sj7eX9Y966H\r\n2WAmF3UI+7kItBKTntm6I5F+wdm/61q/eWw=\r\n=POuh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e0e7275f55471eecce19ff3b75439fb06dce1fad","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^7.0.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad_1677846556680_0.6766628758810596","host":"s3://npm-registry-packages"}},"0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e":{"name":"storage-mixin","version":"0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"bdbb47d9632c8899e1d34cc4eb452f1737e81264","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e.tgz","fileCount":23,"integrity":"sha512-3AcaNHn8lIYO3YCYtmULOctTSmRzq+4Cq4ns3mxT6Zd3CquOMHFLyMkgh64RN7p9QFHIP7ANHd/kMlNI6WnIOg==","signatures":[{"sig":"MEUCICw7d42ASLXZm6XIZG/QqN+uWkt0pMMTYvU8hLZ6MYIEAiEAwYY9KPvlCi9FDkqdbVyr4sUGakW+7ynIuFPve/WzMII=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkFa+fACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmouJw//baDVX7Dd2d8Qdblyp8YYRCBqbUhimIJqksWd5zFHkpkahpdg\r\n9fJs9++0b2lxMNuQvp5uko8um/GSNdjnJBZqE0IAYvA8w++W6IAeVNG9wv/t\r\nOJ3ZtLQj+GnpfcIVbm1Cs94yS3tQYXoQIHpW9d3iN0L7zZo/QWWNU6il7doP\r\n+9o1bY0YWx7GxA1BEjwWoswMlAwril+Y6oUCOUv15oPJjOeM5Vlg5b1o9Jw7\r\nlfWkMpKHwwsm6jB7lL72nE4IVmxVD9otIqcyYvEPsGLPKzdu44Aa6LRRbQM8\r\niAlcccz7hFBTLyjphgvxtDiBqT6ll/11BT4x5AGNm2jZ6/Dkht9p9ryOPnBM\r\nULGkAyKEpoGwS0IvoC5APcQqlUT1mtOtSgPIuKoying4uElXtszkIEULgjuZ\r\nW6o90MO8QJLuFSJFE7Cm4uO+nNnarLT+bfpp93crefvUa/ct40ISgBqTUUYA\r\n3w+uU6YFrIu3agNtLw46Zdx+I6RG9ScWYyhY3z4jno2fFQ4Q8Dw+7g3GGrEU\r\nYiO4/s1mdI3os4CY2E3jMtfifB4iQiFYVSRybKia8UTvFxh7MDsxGUP8jXGw\r\nGwsegsLg6Q0rum5jPuUwspQvQHBxj3koab38d/ni7uXw2qfdSxcpq8bUIbBZ\r\nYLSU2R2VegfIFMdAz7lw59BH8M2hMt3XR5A=\r\n=lEXe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"04ba59a8ace9d68fd90d540d8a8936985115e22e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e_1679142814854_0.8405405691765819","host":"s3://npm-registry-packages"}},"0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c":{"name":"storage-mixin","version":"0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"d16df6b4c976c5b726f7a78cc75e768a1a42236f","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c.tgz","fileCount":23,"integrity":"sha512-mH1E3TkPcxV/YlCykbKbQ9R0IA/D9HtkRrx5XjeDfuJRhm/kcFeu1vBwdo8SX3ntKo2EX06IWUGj2p3EIw74mQ==","signatures":[{"sig":"MEQCIBcsIPOI9ieS47J1Ox9zJxNPdHvCDgHuSlcJPxdYSbE1AiArWQ6mKXW39oADiX1Ajym06ANxkrVdpJWhNhOLze47pw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGMiYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmorqQ/+Pen2vllSdPfkjQl149DYNo9miHp9sOe7aV7G4B6y3ixUP6G3\r\nkPxvuTFKE/oUa5lfVvQfMpKo0i2XIBeCv4qM2H8DftiFOuVdWy26fBH6j4Hk\r\nvy8IeFEJdbt3Xd8s3Q/SoI4Fw4e54GGrJ/53I+EKdBmVUySUdB1mDEugAexp\r\nfbpwD+t48iccydlMXLoR8BcZPWvh7iKXY27DEfZOA1Ye5GvYfqBsYakpCFbi\r\nKQtR6J9ioxNAEY+tlekNr8od4Tq4W+okiZaq9hcCpj7yg6qYAXvkPauoQ5lL\r\nns5QTsj1YHPz2YGu17uH/D+3cM+en5ApaBC4nLfm6QttH6klWWiYOaJLmW5J\r\n9utvSm6cNzGwEMZI6Wfz4hTUo4YCVqO0iiIQazV8gHQFPypS68yCL1ngH2Lo\r\n7mHIm88rEze0Qm9I0QC5pdQUgzOIpkrHp8aPiAcjlTR0dPy0+eolWPyixFC+\r\nVsvSEHiuwgN6TV2T9vKkiSirBcTEO9bVKu8ZE+/Iyj+/RcegSK4EcrRq684N\r\nKQhY7weyvSvjHGaG9xkO3F9UnVJYOgmEc0G9ZkkoTJa1Aq6aK5DEnoVWwrYk\r\nM9qMlqIRi1pibYInipXaZvSsvzj6T75RJIA8KWvOCDDK6bJ2nU/VIUxX4yOY\r\n0THrkZjEyFNl/O56zFsf5N8v+Cti7gEF4kE=\r\n=JxdM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"ed8f90bd71f084cb541f99b15caf3833ec6a953c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c_1679345816116_0.5229326373027277","host":"s3://npm-registry-packages"}},"0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600":{"name":"storage-mixin","version":"0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"62aca033326cefd19c81796c02f8c844403f8654","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600.tgz","fileCount":23,"integrity":"sha512-5qKl/F0d8/LFE10EAzLYDt36Q67g7EUpVqMBT39JMtjYNgBx4g3QHxtmvmrSDR4aCpFudtv1K52DMBfy3a39Ag==","signatures":[{"sig":"MEQCIGncuwlgD/ogIn/Bh3lWYTutePWBZLWNrHiFc+C8aGntAiARvZ30Or+tA3M/ACFRA9ksXI65k+pxueR+v4Ny8hWqkQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkGMjDACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqEbg//bNUFzCx+NtU9OS2Kzxp3Glp3Jylj78F7PRID4+e1tbAXTEfr\r\nxDZoQbJQ7uDg/xw9avZXDmMnUExWL5rbVQ54QLQU2Am0kuJHTV67yymHQ3i3\r\nLU5o0KNE2fe4hHldZUdta4rz+t0SS5i6KM10VoDvQgUsHDepwdV102ZCbz1d\r\nxF3e1xyecWHnXYR2Y4PrnJUL1qPjoxU0QH0G5QJaGdt/b/HgaaA5zyCP2zjs\r\nebujvyR2ypw20Q/YilgrxD0LkGjmjnbFVn5g0K4NEc49m6uDFXY3c2NdEC4d\r\nhkeTF0TNzlKyZIKfmzoKM1lef1UNdjrq/bgHlCMxMoGwKgov0qESnQ7/8z40\r\n5BdCG8Z/Gh8KEdVV1Shn1W65dX9AJByC4f+m4cZXzgtsxWBaYgWckiYxQYuk\r\n1Ev9dnDRi5Hg9MvKXSIW8oS1k+uQDz+BofClxgfbyZ1hy3WZbdcI5k1jb33+\r\nyWeaAjQgEMknLhyX/i2A7SDIfV/Hhq25yR7JD6tBPRq9lYIwLBZM8Y7cMB92\r\nn1Apmy0CHELmd+ZxnY7jLBfVDk1A0ovAmHr6z1h34V1WjmUsoWb6S5dkQHf0\r\nhNDYO+pApK0E3xlrMss2gK7sLKV/uEYkVZqdavEdSr2L1bagZHGoWu9vO0Iv\r\n5CamXYwX8dWDwhgDYSuaK2oEH5AzW0M3nQ8=\r\n=tIxy\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"97c3945c3938ec09f9aa141b791f53d15bd47600","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600","localforage":"^1.7.3","ampersand-sync":"^5.1.0","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600_1679345859249_0.3987369006371013","host":"s3://npm-registry-packages"}},"0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75":{"name":"storage-mixin","version":"0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"65f21a451529a799dbd8a6e0914bb7b172ce3569","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75.tgz","fileCount":22,"integrity":"sha512-YG67YOENkVILypdJVjVyjjOG4H01C4laX+X4OYcuQo8GHayrRIEAXGIuOAkS34XOj5rgZZtI9Zb+qpmpEIc6DA==","signatures":[{"sig":"MEUCIQCwBlHjuaG1MGRHxG8d/3tyxg2rkl5kLmjhXov9FwRodgIgSef1XyKFYWJdvHJjuLUtCs3Zw0S+zAtbyuKPmg74pnA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkIwfxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrIZg//VwkgwswiMlH58mpvUzSpdTydQOTDospOmqpz6HxinvTz8iXj\r\neReFhLSv+aJOW0uymqKWtW++XSR0e8yaUZzKqW0BsJpTIETEbOUeLWLWL49f\r\n7u41MvhctroZ5B7Ur1l99WbXF8RMxn4IlFpEIa/FWOeo0Td8WI2jON4eYhUC\r\nAE2Roz/bGdt7W+IEKfIY2z59KqZG4TIWlmp8DcmlJhty8XE1Gyxk4Hv2Mtrv\r\nYkIllhvHq4DVxWOZBYWkT0mK0UJ+Wmq0o8gVehIeWdXb3fwQgqAMJW+ehuOj\r\n/sUDM88A7defSDvmc9/rHSNIlc56WVw3MFEr+peIOPny+CkCVGSzkcFgCaZG\r\nnaVQH9IAZ4NJsbRHuePdx5PdpghJRp3KeGIHf/i5SnKZcHZDyoiIWkAUcfOC\r\n5efiWf43VrTk9QfPzMvkildw/KKxRvtfBdJTfsQFzF0kfk5Fv0Z4brOccte4\r\nd04OVsQOh5YbHKANH5fvtipAXNXuD0z8oCNmoRGfPUUoTgi2B3lppvjbGKhj\r\nG2eaSWBNc74yJFVOj5QiTDMds1fqKBFBA+xXLSVJiloEsx2IRKFwvlaA/iN7\r\nnWNDJ0J9oz6XiCROde+ZN5gHYdv94pjgucpiyrDSgdYCuCuTAIwR277OP5Si\r\nq2vaz9nHTEwG/3FgWoSeioVPl8WQwwGVcHI=\r\n=I+Xm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"d4e65fe0ae295543658a34afcb1bd79b9b5ecd75","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75_1680017393228_0.7994345487687786","host":"s3://npm-registry-packages"}},"0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded":{"name":"storage-mixin","version":"0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"b00f1f34145b1a34f38df4380142d46f39d73108","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded.tgz","fileCount":22,"integrity":"sha512-6pgiHBj0sDAMNtuek3kcVBc73NqN2plVI2ndszJO0E4SLg8VsWRd17IGUfixC+xM1YAeH0owz/adMTlvgbWJMA==","signatures":[{"sig":"MEUCICqKC++MB6lTWbCJun+A3feYtrpCoUy2xPy6GH+8rkwDAiEAoJdXafN2VHKemW2nHXwNBY7zypB8C/4EPd4J0BNR+lw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkI0GPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoN6g/9FAOCCuf+uHlbo1TxaJByedHUpyHM0L/BYwX0WvpkW5qKFn4H\r\n4en1hOdkz4pJymAOOZiT84L9NnhDMKDxIvq5tJR1YX3jQpQnvI+c6INZVsLK\r\n9DM6WnrbCc1ABRbxGBOIvlxhgNmoGGGzQrT81nnYnbQ1uQ3P9CsYvUQ77Lxc\r\nkw8xQ1m5H7sDkf0HzXTuJVovwtQmcr1yxorcOh7ol4xgjHU016EUXaS3w8q8\r\niMi8ZstXxKxz9XDEyqzoZOMqbDxL30P+kpNIGl3lwEuPpVBroJrEBZWycWua\r\n9lA+7Cg8NrsGMt07IAyKukqL5/KuQvk+H3sYmG+U+5hjqO6L7bJFPn64g5nd\r\nYvpvdnOCo+LnuZNIq8rpMgI9FJTh3PL9W53nvdcrM45fmnShfhljMJp484tL\r\nRrerIHAAx9zJvYj9JgZUbtsPZPeqIUKKgkKVAkpvgsmPcvaqdVRTs0BWvr/z\r\nkY96dzbkHL7hCCSllRe6tyDqsdHIbYbsTNn1OmrGQU12eBhoXvaMHAQEnK1U\r\nrReYaR405Gov9s1GUxzvQejUBSSIQOHAhCg9lAqpd84UW+ZJoGTrhZwUVuJr\r\n+ihwDsHTyQXPHv/3UzfL/NxFZs+ryXJP6DjtPDa2DHh474GhckIaiHTtcZkM\r\nQqSgSlmpH+AiwEpmpEP5lYbsd9cRGlTDSwk=\r\n=g+wR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3904cf8445c3449f8f87362208a2b0448f57aded","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded_1680032143614_0.8888842216445607","host":"s3://npm-registry-packages"}},"0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8":{"name":"storage-mixin","version":"0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"bbe5dee700e6a66e3c84b4b7bdcc62e94f59ebc3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8.tgz","fileCount":22,"integrity":"sha512-18P7jAsk3hAxq2Bdm+fbTD8H+qivYJWBu9KzcJJg7RIXDJuNoaAfJR/7zddztgHGQ64jpe627/MJwpcPtAcWnA==","signatures":[{"sig":"MEUCIHDwflUqAgbNpK+PsbgY7l7tScB+J1m5VnDnK8l5LiFHAiEAhzsvrkWtsgtXxsyxdeTiqOoKKVKsPQHyckqBvucz6YE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkI0LSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrHfQ//dnyiOhHVykO/InLITbGM90iSckj2lTcCVghtUFCEkSyyLdH5\r\nWkf6ADfVQHePTVTIEUZICzOMyyyrEjvkQ9IkRy33NIO90Iw07JjrQpHvVDqM\r\neC/2KM/WC3T1ZMnfW93VzQLpKKaBqCnVNLx0U64j1uqHz1wH9qAQysO+uqEO\r\ng5WueqI0gMDMw4moaGOc5J6qgSqm5HLZKI9pT9mg0caSRNi3ocXAWAU4CAqK\r\nHgpvnNCdnvKo+odvb9S1N/z9avT3TSUU4GOyybgelGAx17u6hvHzhWzXP4nk\r\nAC8gyJTsHAu6NehoAMxNuFtiYtpmhDKIHz14PPsmum/cYG2pkLQRXvw7ANno\r\nuKwSgpj2wZd3rFm1+00t0xFDu4knqWes2BD8GFw6/6boZaAXfy2Lw4Ca6H6k\r\n3u3MeMRmqooscpYFRGte+iILEWTlGjBhpcJlc3l+TV2r1k/5jvB4ZKAU1hcI\r\nNJTHQemf7MqSFU91ZuVLnrovuhrLocC3cexc1MfkNqCSWOaxc5JTjGViHvgv\r\nDsaRWPKsfGWB6u42f9aB1uOMeOcr74aBhHC9C154DKcuB0fGpjaVxmfyQiIh\r\nfNVvkFL6XS10075J7cUfFd+WLfDEH49YhpUI8swujPhyBEj0034+CYT7WnTw\r\n/9+7+WQQ3cquQmuN5lj18P6RHpSstSi4Rkg=\r\n=MneY\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"a863ce6adfb98ced08f9644a294f5b63b110c7d8","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8_1680032466542_0.07134941642147008","host":"s3://npm-registry-packages"}},"0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321":{"name":"storage-mixin","version":"0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"b1f06c34a4376c3c7350060d6572593a80e366b3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321.tgz","fileCount":22,"integrity":"sha512-JZfxhdCnSYrQUlAZqjPkQx2EQcGkH+/5tPOGJvawqDimy1oi6VdwZRrlSeGWEvQSJyhDwr7CEemNWZiLo7SdAw==","signatures":[{"sig":"MEUCIQCzdULypoDUHlz2W7Z3uEkZOqoG8l8NNk5gT9w2AGrevwIgCwmUprPCEbgZQphC8X4NZp5H+Xh7XSc7J1+z946k9Kc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJVfbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpUAhAAnrWvMKPPpwHMqQC/KcJi4e0wo8uWMA924afaMBqPT5UA1f7W\r\njXiTn8RXTjd/gBhNuayEySQjGisEpRuacyNKDCCKcM52uXkKaKw26EowFEZa\r\nlmzCirZg1NuiwzLtabwvC0ifDXspHDTYd+SixiUwf/tk5sSA/4D56DH6KYB4\r\nGnOHm8c+FCDf2no00lTipTS2RkgF4hZ+lYxPTM/Qn3/vOe0oEOBnL6b2/S6g\r\n4BjMKwEqhWUhwQWa2+qqvQzdhT8q/FErJ8TL/JArgAT3c/PM9snQ8ttt6ZJB\r\nBve2oe/xqdBHaBYPZ9aEexHOp44vzWTVEghj4xsRZNXJyiISV6dH9wLDw+Tj\r\nvvIM9674+swO6a8R/+xX/Ji6f5gJKk7oOWUPuYouXMkphFvpN18Xq2M2iKhQ\r\nfSdhU1dDl5W95iKMFvj0Pib5yLYWVP0fnOlTP23r5X2HS9GZB2hqL1DPKPwm\r\nvepOndBX5zNoHZAOkT5QyHX5T0hjzQG/rnJmhO4IAGSxeCF9wEi1rMbWnHpo\r\nXAup6bXERDm70CVcLF9lodC/wGLzn/K1mk07wMzyzjHcfIDz14XjUhsA/ZT/\r\n/70QPDipZV+9tYhopo5PraOY6gtf/cuIFZD9yQ0y7L4G05lUgBoyzqI/FVL0\r\nyXfsRFR1W7c4kuViqn6kc4UEqmPD73kGfQY=\r\n=OtGR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c3291a871fc2c07d3e2038cc1ad275c102e1d321","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321_1680168923175_0.3244114158479996","host":"s3://npm-registry-packages"}},"0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43":{"name":"storage-mixin","version":"0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"1a0702229d66ad8edd3d4dc6c373222e41e1c341","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43.tgz","fileCount":22,"integrity":"sha512-1J0+s4UqRTfqDNrbE2RIC0+rZiS0KamYfNGDcEe6sPbLXnNI6cA914ewWwJxKEiumcvJKQiMReWLTLf1Qy3Mfg==","signatures":[{"sig":"MEYCIQDuctXD1GeAdLB+e+urg9tnFX3tvmyfHtLNECZ2gN52IAIhAJTXN7mXwPDSl57GnEddDgLCqreWZTgXOKqfVD3MtiJO","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJ0lAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq7ew/+NpG1C3wriRZ7Q1ep1M78j9r4z/vB9LRrn/dGio8SAai2sEeu\r\n0Zawat6AHcjszDVvyTJK8+N+DfI1KFLNOpzoONPiThnQhAASUNLIss6l6swm\r\nyJKb8P1/3BoPBjzW8UAnS6sp/TGqwXoQH6qRvQ3ziK+ZTsdBv1iowUm1AiE0\r\n3j4R540FGn9FO0mYhClPBTbYGDZnRMiQjFBb8ZoTMabWJdyhpAnzxnfpf7s5\r\n2JmgALhTxZq1Sa5u/R4ypkEIbEqsPODYfrtv0hYcY68E+FjIrVmeUAxEi0Dp\r\nVrDE21lfz2YJOxAGJCDvOrfaTboAfXb8vmiVEB5JVp0Uex4lrPVY5Ynkjfkg\r\nU0F00/DVTgpvhs8DI8M069XCWBvUXdfm7nBE7y9mJtijQWuHxzKFsKUNhdzr\r\nk++CEChhKyaLbm/wEHfIXo/xjgAEr+ngBeRPyzkO6R2SXs45Odyqdql6/cmw\r\nB2EeFU1ocfy99dsRcbpzrJjsIjk5nGD9WwVfqb227YsUGy5jp+Ej6bJamQZX\r\nSHwENLaqBY6xI2iQVraoNNCw/2DPfBmg0ByGVzO6IRPpJW8a0wQHwTRWmgkG\r\n5p+3y+8ByHY8WB1S+udtxAcH/MVG72MdwzsW+VEzv5ONBQsCO5vDF3Kc9QdO\r\npMoU4hUa2YTC1cPm9MP0OCAnzVfoZOatYxk=\r\n=xeBC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"da0d016fdae6992001ca3f3347c293c36815df43","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43_1680296256339_0.7108079289974831","host":"s3://npm-registry-packages"}},"0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f":{"name":"storage-mixin","version":"0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"6d68b88126b7deee27ad681051bb312b61fa7277","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f.tgz","fileCount":22,"integrity":"sha512-tV8Fj6LKYw49JApU1TwG0fSPxtMDwADK/YCvFkn+cWAgjxBBH/bTS8bhlhAVZqQVTCCKrlkatTg20umnvN87kg==","signatures":[{"sig":"MEUCIQCqMRTBw+UyooLTPWnPfwL5OGLg9p8qtgN+kczNsL7OiQIgYFUhRJ8KRwYPN1aaH26d/573UVTapP2TXp+WFnZr1GE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkJ0m5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpPLQ//TG8AOx//BnnLSwaobkp2G8Jz354uqQ7eT0RR5Zyh8+nG8Ahc\r\n8xSE54JL2+MYYhoKwOuPn+OPyms7+diDBnxPrI6x0oPg+dvUJYO+0B1A78wH\r\nI94cF8HcUONuFnJTlKdDfz9rHGXtqwsJfkfvUH950twEtAndvxHzoM/vy0n/\r\nX1apKwDtn/N7V7MySPRcsudpNUnF6DH7LaJMvhWqZMwMlqlvNy1qKyuQsuWq\r\nLfKx8t30HmQIpWEi47kEvX+ZXUbRAUP9dZ18g6E7+hQSdLecmEdm5yg5VLAQ\r\nXrQJs16IgefLPzS1uB1+Bh1QUA59JIaNG6+5ruK5tk0d7c+8TdehetICGXq2\r\nmngqSKTOGFiR5CyDM1klhG25lhySJX/v4N3q1rUCF9O333O3oupkiVBU27ij\r\nQ5Yv6k8T960YcryCd0uVEtEuNW9f6Y3naee5ldOIT6+FN8xPxSr7pqVcAwtu\r\n5ufL/hRUqwPp+loBIPj1QQmisfmbAuxRf7xftQXq/fuuOrbQx27EVCO28OqW\r\nCA1oVcj85XMRD7r7KU7BBmYvXHysEbVxOeARl1+YZuUlr9ycnYfHQD7zQSyM\r\n+niE9BICLyWdSu3HFyQ32JgOqJJ0rLe60fPhGhkl1c+zajdH6acSZ+D1VFsw\r\n/enIZIA9JLUvFiIhu5dGns6bltu8Ypi0Bd4=\r\n=Cc80\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"76532b01c39fab29385234ef65aac28c9e7d3e9f","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f_1680296377041_0.9263560298281692","host":"s3://npm-registry-packages"}},"0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb":{"name":"storage-mixin","version":"0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7a309372ab9f691073bf51d275453532e1cf8a55","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb.tgz","fileCount":22,"integrity":"sha512-n/HMRtEyg/RvwZ4qSoC4k17k0NbfuqGSRtHLt56N6Crm8T5/VSvWfmCai/MVqk9298rf0DThpQVDGQoDkZwsVA==","signatures":[{"sig":"MEUCIDS3yNZil1jqVIX5EF9xwEE9hFLg/rcO/9VDVWEcUHOKAiEAifeidQb7qTY8uGf3U3+zbIXO7sXPcqROfnBvD3kgF4c=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkP975ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHuQ/9H3fOGJreDFXQOrzQDlvLJRTMRB0cC67n46NuYpYWE2IF2ePu\r\ndy20DB3f8jFdTbduedp+XDGkLY4Xr81K5BirWyH09kgVjZFLC9gMnefuI52h\r\n32qWfchKiHKfSAKrKRZrqPLx2jjoAKGhCzUdWSenwjWjshQdKSFuhKhPUs+Q\r\nqowtNbuRs2z67neagcI5bpqhf8WqGa0Qt4JpxCnAXFS9zs9EftyaC7x8PLRm\r\nmXLUUrSkwwG6Svb2VY5rQMUYgfxSMcVkn7dOkXzRBy5/73DMa++235I5SrJY\r\nZEKYl510XW1DkSXN7g/Mzz1uuRZTVAm/oLMnS7bdnDuQifQpsku1PyPhEFfn\r\n2zYuw/3KUgowEQWYR7sK6QIRJiejAtLEt8kiiGP4M6+QZWXVSsq2VqcbRPGD\r\nvdrTmYwvSYkdGaA8ZqAkqdgRBbIyu3wGHzb4coTZw3vbI2KBH+80IpjY4wzT\r\nODyxqqFk+jQK99CZgTBdsgeJ8m2wcB3eRkDpfiRklUGjJOR4DHPemIXMupce\r\nviVFp3vbk6XFSO+H3y3DkJYpaJi0yn/eA6ElZin9K8Ls//8SbpDGmoWJ9hbz\r\npr6Px+a6gp0bztUu5StQ3xKyql4tcFHG56dqlKei0/QtVaSKVimKvjMzNGpa\r\nuATzhhNQb+RBsNfgskln4c6hDZx+UXXzC34=\r\n=jvyZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"30478c108fea9fe7d84759fb032faee28e0bbfbb","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb_1681907449454_0.36862518594876237","host":"s3://npm-registry-packages"}},"0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973":{"name":"storage-mixin","version":"0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e71efa037001e1752e1999011cd966224891e869","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973.tgz","fileCount":22,"integrity":"sha512-Ng7EF2FJ4u9surBx4XoS+LHm2ftb0oSn6klXIJ7eNnbQNm7ciGgGhFG5ja1jMNeY+fFencLTvIMRQcIXdtZDJQ==","signatures":[{"sig":"MEUCIA+EJIAvXXdIuNH3GrHn0sLflb0ZxsB5F0H1NCCQFnrzAiEAx54OTlL5AF1dkdmKWF/m6P5qufZId1qNwG+OBK3CLtg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkQFSPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpucA/+PkJw1moCDF0cEyqimGOr9csZZ5DC5JAC4P/5CUiD9rSQOisY\r\n/yNDXrweBlnGHO3fO0LZKMiECnKc9E6uBMq5dmzquqjB8JRGy4ux2palS338\r\nDAB9Dqw3EDQutReb9BLAJq/VMBfAp90UOhmLOA98st5KcLwsmtxn8zvTKL7m\r\nQ+u2ovTk/dVC2XVnr/VjdeMJi/gE7phhWkByNEkMXVYfnxL9fsgg/CrXjlCT\r\nkpnImxkMHYD1bc8nO/bWZwujHZc1IhKLTdifOnfopPB6nMUCUNc61Frl8jZE\r\n71dx6EUkbedtpXkmUuHufvq2T9zUTJ3V7tf+c4pNgQSx2B/5s9x3pPk4fcqf\r\ns00WVJjQ9YWdPjAbIU+V34/LhfiZTA7M7QEtDJogATueKf5anzhnx6pTzQLU\r\nF8NdDIUescFSZk5Fn6rUtR5osIpQsWyJJ/uiBgKEwLoqCpnmivd6zwt58QtC\r\n/SfSTJ53WBS7Xp2vmugyJ8pHQG2gIHoaOJ5qOunRlVX9TErrqVw6ahzGa7vy\r\n5itBry2P7hkRhdWQcb0t+xYVJK2f8GdZf43kbEr5nTSDoN9eQ5S3st3VPYcQ\r\ndfLq25hR35kcRqfDeozw5eo/y2uNakz94tyFslZePSQPp19jQoE7ufpek64x\r\n2MPUWWDNn13Uy4Nfh1MTT8JlfMCk/mb4qXw=\r\n=9nRm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1f064ba7669c838cc646f440aedd0cf45c4df973","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973_1681937551266_0.8450156281639312","host":"s3://npm-registry-packages"}},"0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e":{"name":"storage-mixin","version":"0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"a8d9bfef5df84c566e36e18951a51f348defc3e9","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e.tgz","fileCount":22,"integrity":"sha512-0DQD0ZRHoRL1FVEJS+HRUg0NeXnGWoimY0ADENK8lTKgQevBqHVJ3DlVycN5cKaPVLOn/7UVhxi8Y8DBOkIPZg==","signatures":[{"sig":"MEUCIGvmhDcCbn/DlU7oztJ9v2bpI/zQCz/52aD6iP9qFFvHAiEA/oAn5i2Ap8B1p0sJXi6msvNW8cTiDLT89RVErSo1rxM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkQJnlACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRvQ//eYmUr5UWKD5m4W1/+29+j2QH9Yk71wWawTbTUfRG77AUgznl\r\nNaTKOF6VtGLIpnD006KABBaI/VG+nvfmvtFXbt+F4gn7ZJDO6FoGy7V3tEaT\r\nNJ61sigzJGgVRunMnYxibyIZQXSXQmnrwz5ftXSTWGs1rSV2kNthdIArDmP5\r\nzMRme5DrftirqKcUK07YRcD9hK0nx1oyZCEJy2e+uwz0Rps9gaD7XsETzgTS\r\nK3aau0PuQ0JhUc+PfTzxa1CZa738Njkbd7ncuHxnsgfXo8VC4zILpbC94J5K\r\nmuhmH0Tao4n/+UPM08qSAZDGi8QOx1hdqLyC1gXRp9VX5jAHCcHP2wRua39M\r\nDAkkCiXAS1Pv0LZ7yljYl27TyJJZVIMThGmA7XLlubPcKN1stCu7gPP5++3e\r\nbtgSv+s5UML4ddmQC76BmkUmVe4vQ9LK3wc8wROvk4Ufu7vtNNKjj0usBDdc\r\nrX3OVVi0EY6jN3T7h7vVhlhCBJEXCvFcpK5KUeBCLwCNLieqJNNApyb+JEu4\r\nl6UWLy3vi378mg6h3FXS0NRzU75mVBqmq3JNGXZwLYQGSzVPhGRMXbvxgN0G\r\n6pJBZU7fHIbUKaFo3Lm3XZT7PxejoD2DQbRXYo6FtyT6OCqUB97jxsUudAgl\r\n6Oyx/wxixo/tqV11y7srScOskXwoH8dqyNo=\r\n=ZswW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"259fb95ccf1d41c3210676266488d0705f9b544e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e_1681955301123_0.4404574125675993","host":"s3://npm-registry-packages"}},"0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c":{"name":"storage-mixin","version":"0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"0609a4eb446d743a38f13729b8ff1e7db10085fc","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c.tgz","fileCount":22,"integrity":"sha512-eb2WNMG9BjS7JiU38sf0mNAYvtUpP2LhUuobMFM4qoV050IGY569GAObmoAZE3QHXW50TAhsp5dxis+qJGd0nQ==","signatures":[{"sig":"MEUCIFE80Mi6lr0pvQLScUnTr1m4W7ogEW+8mPHyMq1NTzdPAiEAte8NmnLQxkl7cADjhhPewlvVuKoHnRQB1OTFI80TBvs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkQYOdACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrpMBAAh8dQbHLFbGUtf/vIhiFpiILiDyHMF/zMH9WjFd4v5T/iRHJB\r\nHaKglzyBhRyNlziE0prPmuNHExziQBB2ENLeuBUVqNKlb7+jhU1f81vCX546\r\nsYxqxB3eWSCGX84nj82E70gnkRiEZ78GEg3Yui6oddcQfF5CeSWt4UvdOI9M\r\nYP95cT1mgTUF7BW0rDc+V72JBbc2Vjj06yqhKHp+QTfrDVWaATVl4aISI4TJ\r\n9EDDYWDiI2Eq7jG1fUQnyD97P+hLb7NqjmSY7EEvAVjcrLgmpimmA9t8Odls\r\nZFe/Hred+s1CojPSKi7tdgc7505ibjn/CSu4DUjX5BnSuVYvstXPkB9eogZq\r\n4OQJMlVZiI8ktZv6HLeUNFnk0wogFJUQaGelyPX261+Qque+jqmuRkmKIdn9\r\nL3622j4PI7POsXB2ztuW+vDdGBJiZERGZEPW3ua74LJQLHp8zy8cZMnfqLv8\r\nq3xJJx3uFwG0LlFkD3+au512Xa0YAPz3TnyIKxrfSkJnHP3lNzTGW9h26yPx\r\nT1FehAO6vv3ZCEZYpN6uPkA233ADIwrbG++2sYtGfx8Gl71NdVRLfyD4QXnH\r\nAGhox6ZPUyCxGBF8wlsyJPUKlPtUbr7DT6Vf3/usfzg1zJswOvj9NGG14w22\r\nUBlFz8hXWTAPr34PRWFu+Dy6s+0DStdltvA=\r\n=Z6uQ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5e29b9ff5907de09aef425352f5bb129b192e22c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c_1682015133299_0.20212283533919018","host":"s3://npm-registry-packages"}},"5.1.4":{"name":"storage-mixin","version":"5.1.4","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.1.4","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"c39555c57e4004f9312b07ce5b80d59d1e3c66e1","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.1.4.tgz","fileCount":22,"integrity":"sha512-eBVjMbApsHfu2Dlt54N2Gd/LuPYXodhxPBWtEJiqUqsZ8pHlUsGtoyMzRuFRf3n+LrXGGBa7WKVED7p6EKBe1Q==","signatures":[{"sig":"MEUCIGjCVaGjbbDdaerMYb6oAit9DorO9+3VYj8J68XOzzjsAiEAzK7yDtsR4DYtij5ikms1l1C0wW38jmx7prfU7h/LtzM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85696,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkQmMXACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqnbw/+NugKd+Z/yiQbHam5zWCZCdn6ANJPfQyM+4eOrvaOMu/bXe96\r\nDDweoHBGa5uQNsig9ntZcK/xkOBN6XcupyPfJI4aKPWOWEwtDYnLGvLfJMSu\r\nBzBSQdJXRvQ7UNWRcObVCR704wfudh/wrvZo7CKGtrwMFrp9+uvkY5oIv+iy\r\niVHBwzRVx6h92RkDu4GPW+ht5cErH52jRH0Rd/UD71m6Q6HYyg/z8TxkYH5v\r\ndXlYY9+zouT4COPm3AzLhi8d3LGxG1yEzY4eNzKV/wOsFLEE1tqmkKaEeP5G\r\nNaSYvK4I9f03oy0ylq7Ajv4iZmssZe21I9qKXZYYU0CyfwHGR82RisyFpyRJ\r\nwOntaWkJDPm4F9tvS2yhTHFK8QER97vT8SRYxP+M0paraMbPKrZAF9in6LRz\r\nyzHiuZib6cPw12xJVBDDGpQVBiVbljJy9eIupeXidYqtHpA4BFKN+QaUqdWq\r\nLZixOwc7LtttRRmVmOVTLvahdVa0JzaKJddMD4LgoTYgqxIEyJhy3dDbYSJ/\r\nWVZrp53FD7FxXiE3fr4DsxEKNh/u18bOGWGGwGKCXcyuBCVyJfflO1TFzYxV\r\n/KN8wU47zAAUuqL9k8Z+EyGH2MPDACltexboYc/lp5LM/dn+fTbwE22F7URx\r\n7Usl30qBrkNK2SBbMlxJVVU/NW8IbXh3FK0=\r\n=1YmP\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","gitHead":"e4f2643a437ce2407657a63246e303d13ce8297b","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.20.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.20.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"^3.1.2","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"^1.1.5"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.1.4_1682072343578_0.07913467475291092","host":"s3://npm-registry-packages"}},"0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400":{"name":"storage-mixin","version":"0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"eb3f0e15b72447c2555d0a36f0b2c8cf31e70392","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400.tgz","fileCount":22,"integrity":"sha512-BgZcbIoQsshoGm8wy37FllAclnjSUcyB70ybU8gs/MZj+aPybPz5n1JnHehteV4gEDiinXUdNbLOnzboSOgCjA==","signatures":[{"sig":"MEUCIQD4d0nsGMsSgqeD+fNTwe4GXZml7AQz4Vyr33+nbO54DgIgWkP6GrxntrDa7VdA8loZ/h+w5s+1jaGQvKgoJx7YmCI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSO2FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpUdA/+OL+OmVTuES8qxlB4B12ai708L0PUbubzg2Pm7h1b2ZUrChfj\r\nEBB3BZb2mgDsb3GsvpBBmOrpMmHIXwhdfmkivhqaYW4Xi/tf/DbequXLQlWw\r\n0fkznEAtsAJpApaq/SCv3z3AxoTLX+2f44rryi+SJp4TY1jgg+kiJ0g7iKro\r\n7Tc1fnJ9EKCzTDXnlngwl8p/g88omuP2cUw8jp8PfyQD6R8UhQH7jXNtsFCL\r\nj4JZ/McgHIaKh1LwxsHAg0A9TA38iHGtGOvDc/I18VFc90jUwFjvfunFLU4F\r\nEjqwZQJEjDuVQjNQ6PRKJx4mJ/6xZ7+ESrZIVa5zRmMjuSoainhkac5bMwfq\r\nhnJ5WZzcqG19uEEJZ9tQiL5MvKuebYZyk4RBi156Iv+SSwTqFwB3/d+MknSE\r\niAYIZz6fd1HFphpsZ3eAH/QcxNokbFcTSgT89UgtLtv8PjC8C/0ReCA0CPS5\r\nK+hRIOPJNQBzxo/vQL4lXhJWuRzlHnhvXT5xWcV9POtvJR3yEwy3trth/BYs\r\nHUD/rfTSTWt6cUS5AEUpgBAbdlNTWG8GMOmevAXwvj+BpByJGKKHYM0cCfzf\r\n6mWCdP8RO1LkGDO/pjBZGH3T1E17kmGDTuCH0gWsYHWo5N7k18Oa77GSISjn\r\naKZUgT9l6qE2cWJhFSmY0bQD9/KQnZ1xcG4=\r\n=M+JB\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"604fdbd72ed8b3cb7869997416b51ea07fd77400","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400_1682500996795_0.46135915607840894","host":"s3://npm-registry-packages"}},"0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e":{"name":"storage-mixin","version":"0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"7d20098a180683c08dd694137a186c0f957d50de","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e.tgz","fileCount":22,"integrity":"sha512-4E9RevqhKRdl2OCvcelBLf7cxP+p9IKDDoGVdufxi0/qiV0rSTmOd0LgSsoIyR8KMTTuhMUCyXzyerTQOkleFw==","signatures":[{"sig":"MEYCIQCIofQ4T8/iSBUaFwgdiQYkRcCARn+o7oTxe4UVptNdQwIhAIcs9QlZi9tASVRcWE7AUcLUdw8zJsRQQEJDXtTtvyhe","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSdZkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq5Iw//eKYPalqITsc1ALdUmWYEG90duNcmD+0wuP9UvGt3vXnNsSZO\r\n5rhrgBuE4dL32icjgIpzmQ0OMSTXc6hEPck0QdipGVUHmnuplepAYINoV37u\r\nRDQcH+3kzR12pqYz9h8ElLpmdMtapMazM0YcDLCLBygP1eS4UBRdKtUW82Sw\r\n1E9+b+c/v0Gm2yO21k4VX7uojNJxhg02SEkEuH9X5CW5qJxmryPVJtXynsVQ\r\nA9wMeWgDq+brBT/d2ocLJX8zIyxJ8wInXpU0NiH3MnbTkxFM7XAoCP70jGPT\r\n/uHqS1j64Fp0wtbYpmeWhiBLjmZRN0+D3th9a7JXg9S7dnqKs/6wFRaCSumY\r\n1m5rFqzR550w1gIyrlijcCWQiwi9iSKsg2ClB52AmEaWO9tWa+WKtBCwlzTo\r\ngS/SN+n2HwGExwPJ/OPHxNX85kQiW1QSAPD0kd0ZqLFb6BootrMMA+1Gb8j2\r\nVDWT+yTnZjkC0HRFuf6Y1bKa2c5PC7yzR8BQEXn8z1hSQNj31O5L6tfu9M8t\r\ni+RTD5PYclJlHPa79TzWOSf4UVL+m3Zlwu5oSP1C3EIIjBb79+18V6LXe7gl\r\nGVnLZ9jP4+PWq9jHNM3cj2hXcCuaLnR5/PgaBajR9qX76lCEQK2CYBn5s4xv\r\n0/7UpCrpQ7s97KFGOAHPLMLf/lgW/C/+Aug=\r\n=e+W4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"35420eb38f659fbfc4bff9e72644deebafef275e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e_1682560612591_0.22501309812610715","host":"s3://npm-registry-packages"}},"0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a":{"name":"storage-mixin","version":"0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ad823a84fdd6cd3f297db8e14e910501f1bc2b9e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a.tgz","fileCount":22,"integrity":"sha512-STv0lgB/nty0kLEbxhPTqkKgtNK+rg0AKVXLrSnTNHGSUwrb3gox9RV+dfc2e+wVtPY6i3PoaWtgAm21DbrDlg==","signatures":[{"sig":"MEQCIDUhXAerxlLjpQlbOojUEV3arJu5Tr44dkqzamWWbqhdAiBRJD3jFJqfRbJtu9FL8tqKFdVNOWPULvppxgFWxsarcA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSj4TACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp2Nw//bSyi7diJBMum+ukdW/V1ORBaO5jpm0nP6FOx5e0LlbVDxnIN\r\nOIC3VHy/IA+i7/riEZGgoU+XSKZ8zArt52oO8oMxYygF3/QQyVDdfNqhSAjT\r\nNLSxGJxNMSe/1XwS0c9S4PKblSU0OSsxtAWp7uv2PUDMvyqmWKFXvXdH5moJ\r\npuXrrLnsP5P3c1lGfE+UD8lwHd2y4Uq9II7jEFCJjO536ZRwnybFA938AYvQ\r\n7aV0lng80OmH+vrglP8AQelbiXfY6ayoVycGzGaJEXcg+bVBtvWXSypefO/0\r\nP1EOUozQeunTuLRAzV3Td8KJhzSECIhLNMr1nTyLGjcf3Yn41u+5P/UzmI50\r\nVjJZVELgHteu7AoTF5/+cMCcrqPuSZkNtB8pjsXvpw+QQu62Chw18+fygSGC\r\nL89j8eWyk1tZSnm/NnA6BTrnLbO0/oWrAbYgAktz3F8EF13jopzzq7pJ+dGW\r\n/ddcl78WoUjU8BpHDwQJLpWEpgi1xkXSbFjH86tNXveikvRz2lI/56X5Xr9D\r\nNJOeyVN5xuqXhuJOA3j5B4ZDiPkJ1zzZsm5icnN8t0tZpI+74L5XKzl3eVlG\r\nB31QtpkP4Q/ayoFVl0f5GmPi15PTJvM38HUpjl588IOVPR83xLQFI2pFd8/9\r\njJPdrAEcO3UWDbufeW6VipXhYoERQl80gnc=\r\n=+imu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"f8695ae3010acc2686c0a530f153ebb01ddb040a","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a_1682587155273_0.4360137419104626","host":"s3://npm-registry-packages"}},"0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c":{"name":"storage-mixin","version":"0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"632abd11e18d4f2f6536d084bee3903cd08c0396","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c.tgz","fileCount":22,"integrity":"sha512-L4o73Wvo9VJRJw1vzDsKzAqk0CB6yzBbGPRG209OriE7adyShHTlPi+/RXp0bsh0+lYjWyEW0/kl5P2x4M3cNw==","signatures":[{"sig":"MEUCIQCLuxavHcRZ3KSq2om4QDyvl9yqFhlwf4dxajRHbLyMOwIgGARcSuepHbGAhGllyv69UVtl3jCKzDe9QmAMz4eW4hQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSuzuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq5GQ//YHbKTxGAVaepUrBJLtiMt4Z/66L9gBIAI1argPqE1AFt/Avc\r\nJGDKS4DjtlFuRF3ep2ZOHTv48El1SP27STU3Y/PaSfc/J6uGsEhADmd0PFTF\r\nuN0S6c7tTq+GG9g95sQspQVZngmHe99n7VZ9T3cvwvHzn+mVARjsh5V9Dz+0\r\neDQARt8EgDEaWNv1XhlkEp9uMQPSOU2DIWwPfzblV6ztYUApfZAnxGw/MsOZ\r\nbtNkJNNetw/jcmv8zdagisjmNYVxqmamcRROOuVQWwq1bk6SQaYqw+aOuk/l\r\nHJwvrD0wyQRn7UK106BAaN2I+jU32enuFcXM5UDHA89rKUKTW0LDWlngF2Ko\r\n98J9+5W2kWpNrqwlmYTtu3jDYmzmgHr22Fw0hsxTDkv3IEpp0tlOfjmG4Z16\r\nyG7IE+vqUfkrK8sR23f0gDRhOXl0UcQGdEsGT17fLOQ/U3DuFQAcLEIqeTc2\r\n50J6R2kqOhHDctKpm1HeGyMoiTCUQcBPbPgqz9Iuk1ZetB3DKBNsm+k+GnyE\r\nCvfRpP2r74viBymMnbr6pLRslYxDG1Y4HwYnqCH7lFUv2xSuFtC8j9GYhcm1\r\n1W2h3t9GFbhAPuxlkj31CtotK/ElgWWTwpOEAjW/YdhSzHDiV0jA6uyrujli\r\n3xluRUY1mM+bqtn+fviaEpP8x3IFjMsK46Y=\r\n=2zUe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c_1682631917886_0.4475030846377104","host":"s3://npm-registry-packages"}},"0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995":{"name":"storage-mixin","version":"0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4e816c71132d0e608400232786d0b24f0fc3272d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995.tgz","fileCount":22,"integrity":"sha512-MvNbCVrL6t8U4rusdLKbRJVJ6hQGCsKYe3UWr+eLJkw0fSMlQGqDy8d7nJ7xgKt38STr+nSnYwKYf2diX0/L1g==","signatures":[{"sig":"MEUCIQDKZz+IIEI/bapwBKLcfaescdK2iacHiDmjeNmF45Ll3QIgSODGM0P7PVbsArIPKDhYCW8uCwa8dGIlymtRW3wcawI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkSvNNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpDtw/9F44178h7IgGeqX3YCgGtDMP5NF15qZgdy7yHWmRyETj3EuU1\r\nDm/LqvxDMfs0Ephy/BzhNqnXQ2dTP8FavzFB6bKtSOfoW+qyuqJrMAU5h8eP\r\nOII56qtioMWvOL1aguSYzk+KcD3wOQZdmo5s+iRPj1iJxob5+z5071NYZD60\r\nE9+WM2vMbqHHkPep5eVEhZQVdT04KfNVSCxkUFwttDugLtW8YnIlOGhfa5jk\r\nuA+xIpfXXJcjX9SMJeY2vlLoJeVRjcwR16NzCwJ+paaNfDe39fqcoV19Y/Gu\r\nkWRYCMzvx47B+TqC+65KdepJ5fc9e0c7pZ5cfsgoLbcLj/jrk4SLiiFrrTNB\r\nhRr3ETQlRAqJNRW9joAvCis8aXJCGYZ4dEFKBR/3eE53RZh1Y6MWgUh9fw1B\r\nGPzOoP2qeOVlVaoxxayvAxNbnHgz2dRw1OGOwI2w6agBjucsRxm4ldAuERJ/\r\nWtKe96jsPuO2ZpKdaehxSDnXgtD6KMpqSTLH3RU71zTyoo0W8wf6zH2zCsfd\r\nRhPAEXVtm3tjtspMOd76hLrwGEl3K2Rg73AzlVL+1cHE0cdEVmGjK5shC5u4\r\nksITW3lcCkWe7Exg/Q7b6Q4hE29ZLemjRfqYEoDPjPRvMIajZUB9BV1/x5kb\r\nRlGdGXYV9LjYWphvtV7UZWgXfSd3n3wiUzk=\r\n=t8Qq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c7e6e3b221454842020aa1a9adedb2461878d995","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995_1682633548832_0.7828645286582041","host":"s3://npm-registry-packages"}},"0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676":{"name":"storage-mixin","version":"0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"bd20da52722bcf476901b3988277501e5dd47910","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676.tgz","fileCount":22,"integrity":"sha512-vB374p3xvyj/ZvqP4ClA6jdtVjpPTUVdixYLyT8lGlAvdk9vU3M3TBFf1RbU01sMhPzrPlUDLmDLG/f+NMTDZw==","signatures":[{"sig":"MEQCIFVBxXo0DOPyPvJN/40DO/AiwgbnUofAOoFwZ4wd2qyIAiA8AKcLit9GzhPJBMODpQgQIc3wDvlM8KqNT3EyPJOaXw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUflVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpu4BAAgiTW0KeK6eK7jtbxj3ePM3Gw4Ab3W9hQtTyULbUxDqguWDm2\r\n6EIlzt0P7AHukHTZHDcNKqesY/z5qfURNYiLPYgj0hhbL5E4UBvkK5yGXepE\r\nhcGoJ6SMqptawLJ88x2vjJt3cYB/AESWtMoGC0TiVC1rBNRwYyMWT3Pnwtw6\r\nvRegiiNQEXOEUnAeOll3CKIW/3Ge7gCDuFmSPLS0z4b9pb9yHqo/+9ztPueH\r\nzfIgLWA5Y9AdueExIXkG8y5pbuDMcvNwoD0eJCgy/qGHtbbq22FrU0Xde/XY\r\nI1Xj10FOVo+bTenXWcBB6R51ngYRNMhj28Ynrv2NRkNFLzVEh70hDMNP+44U\r\nNUtRTLCbbCMDJK5hXORx5TwfRe0YWv5eBoOjfkMGe43X/bjmX3X4RdU9/ArP\r\n7m6Dw89apKjMjQIfR83FHjfL9SR12Uz5qqlFqJl3tvs+UkMsU2MPMfEcO4Ql\r\noDOBjZgvSycdGPX6tCWFVbKQM3qf7zM9dJJ+r1mFmsqW/rh8WeQtVdZp9aHH\r\n3wAhPGveUoJvPGcvJ4hYnQkph9UlJ7nMesO3FQFLYQcok3z4ASzKEXxfnmV+\r\n+Zw2ZRqC7nptglRj1ktIszZLLg+XNMPqDGOR74xzJRlNxv9F7qOiph6woxLK\r\nSLGlL52N3DNMn4bvxMYoaxDxo7ZHoIBHp2U=\r\n=LYVF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"07a892207f0c33a49a10f047b8e98d59fb1df676","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676_1683093845350_0.9500801563833492","host":"s3://npm-registry-packages"}},"0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb":{"name":"storage-mixin","version":"0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e537ce77404aaff7660415965ea4172f5820184a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb.tgz","fileCount":22,"integrity":"sha512-pqjMga9EPuJ/N+nPZMWoU+i1ZUUJI1xgNGCEhmVAJmF0zlEcToHGJIuB7r9udjJK/ORRH2qtSV74FBGS8/pyyg==","signatures":[{"sig":"MEQCIGTo9VGwPPPWJEhcqFSPozmDlmCb6jk1NhJE+qsopyWCAiAI5I8I3siTh+VcBZaIZ+xKL1QFMTcUm8+RzTn4/ekN3g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUp71ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmotVhAAmkPNT5MZci0LZCninrHNqBB4oZDX1CNMNRRC2Kh+DaxZRUzu\r\now5IeZnTgeDliWBRD6CRa+xzRvdgnqg6LwnKkDlSEtIx85dKhhGBYKiY9yUH\r\nFFOxkqB9fIoxAfR200RqoOOJkRUIHcXwrh9ymkaEx2TuEZxrH806IjOcrrm8\r\nZwppEw3reusDltkjVKvc+3IO606J4nZn90SqdrpbxHF5ROvQ4aSTubPhZCFN\r\nUSV9CkVbEq14aHl+N6967HliRvP8RtCtc2Iw/gW7T231DdDjAxPhq68lyb9F\r\n+7VFqxpxAZflLdsjNPzbeok9TcPnlEvjiuNp4mypn+GnCzsXRUBrwSYT0RHf\r\nX1QSnsSK2BwdkcAUneolzXQUhNFQhGDXu6rJDrWW66lT4vC//0oym7YTPVxL\r\neWCt0/IfvDi+hh0OYXdcfVaUQZunk8GI4mf57YVfN70GH/G9KZKykQIOTItJ\r\nmCFuLOs2tH9dBl21tDvJOQ02+tpo8Ck2sc/Pa2Gb7zKc5RPUi4KKccQ4lCBN\r\n+af7uxw7PAm79+vV9cHiaJTTfWQU644/LAMX5Rq3TFHeZcKpeLfSeLPtA0OW\r\noLGBr/11GAEw3o+/b9LYcftC7uOk5/eHfTILDVjw4e9os/cWnw1s8ZLcUdJY\r\neE3lLZ7BR5HA4uZ6DEYvzuxZfIh/GHikXQg=\r\n=aTvR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3871489afff599d3c0e5827b05c6cd97787625bb","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb_1683136245584_0.9200575303924603","host":"s3://npm-registry-packages"}},"0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d":{"name":"storage-mixin","version":"0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"f13c53cb04eb78592abf4f907667a6d4b1c72735","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d.tgz","fileCount":22,"integrity":"sha512-FEAkvxfkjLTHoK/rXn5YW7P2BLHkQnd9xJ631lo0aBeP91jyjZvm4DZJofNXBakOPhzFvuZF4vVtU9jUPN0jQw==","signatures":[{"sig":"MEUCIDBjGXgRK6ljOQcgDvduTZCFTRsUdYNfo+eXNgxJfTmIAiEAzOhOgIWMZWjcEdoGqxszWY0bLQsRhMjP0Ujs8qGZbq4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUp8MACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrzPA/9GR8x8WA9KDmLgn1pppdiTaTPrPXsMRBgNBr4VowPVsTFPqvM\r\nvupASXe9PViNs5hbdFrQIQpXGyC2x2SNeA0sADeA9iwS5RTIWQFWBdCCGulp\r\n2FQkN4xz8csQLaUv1MtZ54NIlCas6x9Rh7TBsBMsf90zviASsNjJlrTXcvun\r\nrc6jc5hmPa7m51Ycos2ySxxomysoyj/JGhPOrHkJA25soG0j9QNL2qEYsN9d\r\nZ4Mwvn2CDQueyyAmRvkzrLDwkQllwDnXaBf7PFK2DRfISomqwvZZSm3ISUmq\r\nzIbCI5yNfWVQAU/VNN8p+VGeD1qDFAOFBX2pNXKDUcG1CqhOTQnVRS4FmZM/\r\nsFwhejkFTaM+D8BEeMt3g8QvD/NQxEK0+FWfrCZsVFOI5Ks8rgM5NJqtu4o8\r\nL/OGqHZbq4AijQ/AU56woPqEe9VadVp/mDNmDtV7nEzHrHtcv/gKm6B1x+ic\r\nePk9QUT5fNEoMYjw8DvNyp8boq1d7yzuZ9prQC0eUly9WUXXEXXuMT7DgUd9\r\nXYLnCFFHD++ywuvIBE0mQXciw9h4J0VWuRVUQXBPmuRl5JCU0C56nDQvta43\r\nw/5Dlhecvax9hIj3MdZgstFRKJuqo3VstRZl3R8Fp/WYGw/LpIZZh04fKUFP\r\nmjoBZOAvfzAFwUQA1wjQHGACpXztvOH78No=\r\n=WBVT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d_1683136268783_0.4315288269998325","host":"s3://npm-registry-packages"}},"0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea":{"name":"storage-mixin","version":"0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"3567ed4a8b9b9f6fc94bb5154008f953d3a40c2b","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea.tgz","fileCount":22,"integrity":"sha512-cZUwOsUKSgDTebXeMrMFym4l3SXPucEOED/W/I9m7IRrIHtt8z1zqN4lHry/7B75IH47faxtkwIJgDUJvRYntg==","signatures":[{"sig":"MEUCIE12aLlUAIhhj4mz8hFAy2ejPXIQtEwIIOouH6TkVhtDAiEA33MUkVKW6zzyF3GC3vobOFV6SwS2/XK4bj9dGpJOOR4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkUqcCACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqYuQ/7BsjFYjve3lYo2s5pQ7YH8z+Lt53cdzJRI+PGGxi/UkiuIt4M\r\nULv063xnfaJcyE/fcWXWGgTF2kydDK5AsNihB0HN2IKjdiMOfC53n1eYSGXu\r\nNJks2ChcfS/zN2NuY07q+8MGcIKxW7sv9IsQA2+q0zZzomsRC4NlBXvs1SFQ\r\nvEmp5oOwK1HBiP5KrR5ea/Ko4CEhrT/LxLkHG44g02DCxkZ+NhJNX3ma0UuW\r\nocHfOS2LrXGy6+KRnfHDSD5G61y39QEifA9M8V4Ny9JbXofS1aODnRLuuSDf\r\n++aa7HDn3b/kJog1zDVpOigf1SatABxsUVnOHujg3+vL4m2jVRjG+lopX2dp\r\nXwO0CW4IHrh1qC6xiTFobasoXVKpZT5/dpk/AEWqphR8mgA0u5bvZIKbjojY\r\nlUhpgIo8x/f/POWfWKNjJ6g2JYBa7AqQWDOM5V9SXZJAuZnIhfxdt6C+oKtj\r\n+HKxgACgZLOKf3O0r23BsPXr0/707peCh+NpU57LGiUEpN69rE+rXkYhOEGe\r\njyzlXGKzxCz6o7CJZONH8PSbLgTRq2CuaFkM4IpHgvKw2hZg6ZTvs6B+nBIj\r\n5I+dX0p8gNfI5utQOeDF2Yxm//w9y6fHXbPkY94Eiwo7soU+gMh8p8HzoQcg\r\nS5HtlnCwFnd3x/w6PJtFli+R1L94oaXswYw=\r\n=+0cK\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"23c47176cb8ae215c36676e7e063cfda61b887ea","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea_1683138306456_0.9532815566203232","host":"s3://npm-registry-packages"}},"0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f":{"name":"storage-mixin","version":"0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"54ab0fef4941436a28a9b74043a8e33fa3945951","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f.tgz","fileCount":22,"integrity":"sha512-jKuxpnfyUR1uCJejMnh1WRn393JsdZwqaxYP1O/y2a4vawbBsqMY7kBxxdGwijheTizm9K9SgIDuftojFGXu0Q==","signatures":[{"sig":"MEUCIQC9wRiGl4p+BBbEft4A3Qgtj+WHJX+ETX2UZh9vDg1QtAIgHPtHceYqN0rPaJyxgspM8WAulhWmJV7zipw/J339xpk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85832,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkU16SACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrKJg/9EwdvZmzd8Uyd49MwoBBHGVsAAcgFzN81b64qJ124xkUHUt1U\r\nl+ISHYaMbI3OuiCxfoqvTRK6BTGmj8fLxmJAXms2iNUMAE1drvDQDVyacHo1\r\n5CHmzBghIexPmE4p/hyjTrVTOSxFFiCje6krDWfkw0wEDzAJenP1rTZQIyZK\r\nMIqRPfc7Znlq9EGdcy0I+pnkGOyMJgsMUKR/lLr/EmGiHSYdBrvvBRZ3e/e6\r\n4FTPV/p2XTZadBMZJc3nKKEpM8rMdQfcBHm4MkT6sbNPAccf4y3BZLsTBBGT\r\nRSdWL2f89XFQO+wSIPja1PQgbsnTKROBR0B/GwJn4PH44VJHUrWSKM2MdSkc\r\nzeoE6vllEGJe6wYJhlBik3UC6podtARqmBg3rUIZWalSRX3FQVJkVS9JYjjm\r\ngxtnhV0D8HujZlCFidkPVuxDte1b63ISFjhRKaKYsZuzdDGSsW7P3uKmHiAh\r\n1ZVuycMDYWpFxHWKw4SbSainSvUmr5FMIwJArXrsaHb51btn1/D2L8omvcKR\r\n7UYPwqvMm1Pd6GALoHmLYyF7Vg5FZaXRehGFwpgpGQhJAfn3kCmCf0ZZblKZ\r\n22+3hMW2tOAX+1rRzbY+ZZvHvKFeCNxt8sx3IVmxbWEhjpzwB2e2fm7ITLJW\r\ncCkgVCxdes8e8klAklah6J4kGOgrZ+m3omk=\r\n=HrHf\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.0","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.15","rimraf":"^3.0.0","hadron-ipc":"0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.0.2","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f_1683185298279_0.8680195756398308","host":"s3://npm-registry-packages"}},"0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0":{"name":"storage-mixin","version":"0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ed024d4d994b1a8a76b9b8197ffd7d47d76521be","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0.tgz","fileCount":22,"integrity":"sha512-ASPXmBs9PbufE0quJ736WcvSoKuoDdkScW/iKVJ7rFeeCI7w2X58QFgoFb8cYrPEm9foCHo3yjVpJAaEMEb/pQ==","signatures":[{"sig":"MEUCIBFxKAeWl0KEeVqxTl9sHT4w2XfZlSVe74qq1437MIMeAiEA+B8gzQn8Vgx4LBlvL2pEDwnLzoxpXSuAcXQ82702x+8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"6c80d388bff8033f8ad0136897982d9caae9b2d0","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0_1685571867922_0.6928321236663393","host":"s3://npm-registry-packages"}},"0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3":{"name":"storage-mixin","version":"0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"18b5080029c3ec519c776b055be49de03e0ca00d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3.tgz","fileCount":22,"integrity":"sha512-Wam4joe51X8dSVB1GLj+DR4IjuHE1arpcfvJvxsYzRBcDCCsKacIMJeY7d91jHBM+4pbAZ2D3AvAjbWVuZDHaQ==","signatures":[{"sig":"MEQCIGErC9mtoNI/aZQBtoj3VAoI/Ia5Yzx0eryBUSjuoxYUAiBuxgRv06YYSG6XNFl+wqKbQAQvHbdoAAqoEAJ4UkKoJw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"0189b6f6005b078db9424856c7565117e3b45ef3","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3_1685749287429_0.6675614394633356","host":"s3://npm-registry-packages"}},"0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054":{"name":"storage-mixin","version":"0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"dca0c93e622653c0fc7cdbae1c16ebbe90b4c2cc","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054.tgz","fileCount":22,"integrity":"sha512-YNsIS+H2rOtp9qgNbTjobJJiChWN9dBU547DJgC9yZaBfrHE9wNl3UVkn1PKMw+T5fvDbcaJ1FycbJRL9I+ejg==","signatures":[{"sig":"MEQCIDnqMAEstW0fE1IzqBgzSUr45Y9Fm/99oRdM8jVFZBUPAiAQBlUB9hjRKAniCqEJiR0OWHt8TAd/BbBNUH8Xh8ERIw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"2bd69249c64bee9c103212c46e5c582418f87054","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054_1685749385637_0.03950027711189552","host":"s3://npm-registry-packages"}},"0.0.0-next-e182f845553cf87006baf04d22367061288c5226":{"name":"storage-mixin","version":"0.0.0-next-e182f845553cf87006baf04d22367061288c5226","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e182f845553cf87006baf04d22367061288c5226","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e17ae6cadcc62cff5f7ab279e41f2c6681c1183d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e182f845553cf87006baf04d22367061288c5226.tgz","fileCount":22,"integrity":"sha512-XVduoruqSamvDCeHxw2G7v1r5S6jHZb7D0+InTqimi2T5tipNMn4T/n6LKIx16O1R2e54tkf2ISslb70w0KJZw==","signatures":[{"sig":"MEUCIG3Y24mYxNIaH5H2PoTCCuHO1wxQaJc0EdO80ZMZ3wxMAiEAwypTQDduPTSuS3WaulJpPniZMNcXxFalvNvXZUZHH+Y=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e182f845553cf87006baf04d22367061288c5226","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-e182f845553cf87006baf04d22367061288c5226","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-e182f845553cf87006baf04d22367061288c5226"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e182f845553cf87006baf04d22367061288c5226_1685752345975_0.6096292571185309","host":"s3://npm-registry-packages"}},"0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed":{"name":"storage-mixin","version":"0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5e9d1032389a504307fe486aef474c2dd323cdf4","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed.tgz","fileCount":22,"integrity":"sha512-GIZwIVR/C0+UfarNOSUu9aYt/4NBKGUCzDyHEZV5wNJyXUYnRugErFtEx4eA1fpuvJ/GL5JDTvAoV6ivZKXYSQ==","signatures":[{"sig":"MEUCIQCao8xGR87hP9XB4SszECfHbFINaduKfeSpfjTxiLrb+gIgKY0s/9vNhEKEtK2eBrvW1TLfrnZ/lAksguG7zH+DcwM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"2d8cfc600e1d4de8c32643b601d0c021734b31ed","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed_1685753622459_0.748904178278579","host":"s3://npm-registry-packages"}},"0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa":{"name":"storage-mixin","version":"0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"25b9166c8b2f0b500cc3898aa9b29be29f8b129e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa.tgz","fileCount":22,"integrity":"sha512-YZerJrx4L3P1BOXy4c0ULjfCG7Lucul+yZ1QKnNafHGvrRrPnGJLwbLRWSfzWc6mFIMknFWx8ppfhVKnZGpU/A==","signatures":[{"sig":"MEUCIQDUrkJcOT7BQJH/wGvPkMmngenCgAiC2MCBVDSXA+77/wIgcLBzMzpOAMPd0mIaOJJ5Bb5O3+4yV9HQTo+/mQ4AgdY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c2ee6dc98a012b4f4494e197ec69ca57d395b8fa","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa_1685754237959_0.06998381835596112","host":"s3://npm-registry-packages"}},"0.0.0-next-5d4d8579be24c292424443140492919b337a3b28":{"name":"storage-mixin","version":"0.0.0-next-5d4d8579be24c292424443140492919b337a3b28","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5d4d8579be24c292424443140492919b337a3b28","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e9ae3a91f7fa20e0c631fc9d9033c5f884077cac","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5d4d8579be24c292424443140492919b337a3b28.tgz","fileCount":22,"integrity":"sha512-MkSqlJNQTpW9A38JOTyzvvtccFb0snQwBboVaJA11vZON+YcJnRv7C3slnu1NzsiuOJEwf6JiCBjs2AnRcvuNg==","signatures":[{"sig":"MEUCIQCxWWA/6H8Wtx1vtpZ55X0xQ+uoKjEyAORtLYj4R1KlDQIgZiKWs7E626ZuWRmoPYwq5+6XjdOsBEKxKy1572D2g0k=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5d4d8579be24c292424443140492919b337a3b28","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-5d4d8579be24c292424443140492919b337a3b28","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-5d4d8579be24c292424443140492919b337a3b28"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.11","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5d4d8579be24c292424443140492919b337a3b28_1685781337302_0.8877328797501081","host":"s3://npm-registry-packages"}},"5.1.5":{"name":"storage-mixin","version":"5.1.5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@5.1.5","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"2bbf4bd2aa30b155b9722e202d5600d5499709a5","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-5.1.5.tgz","fileCount":22,"integrity":"sha512-KgOMMODS/dTEsgwU1qHpa15NN5UudLBR9ozqZ66OZSkXcGrOfC4p6oX1WR46wxn4kDkLLv/7V62L6R8JMNURNA==","signatures":[{"sig":"MEUCIQDuJcOe32eGo4JdVKLfQ6JY7JC/I4KdYPzbv3k+cXwL1gIgXyFslxVu1CIJM5OkoTlqAK+TjjXpgdfAAb5ETlycQvw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85674},"main":"index.js","types":"index.d.ts","gitHead":"129d5d5375a2815408e12ee15e1b6bd566f52600","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.20.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.20.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"^3.1.3","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"^1.1.6"},"_hasShrinkwrap":false,"devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_5.1.5_1685961263866_0.4064407122478477","host":"s3://npm-registry-packages"}},"0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba":{"name":"storage-mixin","version":"0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"1e0738ac2382922d5ec1abd4cfdac27595097d14","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba.tgz","fileCount":22,"integrity":"sha512-KLrL+8W/OWIEJjgIl71OGVQfQE6494QXc6m5ioVu1SvZe4N/PGKs1xk65FNg5yhhNc+7fYvGrXBvniijgj3Zxw==","signatures":[{"sig":"MEUCIQC7zc6ueaQyEDlatvlcMrGyjOWxHEnpMC2mB546HY9RJQIgRDL99KdRXO97hr8Wz+uDRxpKjbamAlrlDY/AEAYM5V0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e3e38f7d039860a6114dcb42a77f550e236b18ba","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba_1686040626833_0.5719703325090615","host":"s3://npm-registry-packages"}},"0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa":{"name":"storage-mixin","version":"0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"60769aaea16cd8fd9b93710a7513456cad20195d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa.tgz","fileCount":22,"integrity":"sha512-mA6LiL210cO76eCeN6Ijq6ZEZSvuvzj3+TsKRsVMsyT9lCoXuS3U2Ibk1pR4wyu8YykMyZilTlnIuYClkiCQ7A==","signatures":[{"sig":"MEYCIQCn2bEONItpjsj7YA7hJiY/x78guFTznHGBUhW3CVZ5WAIhAJveWJW7bUC3Pfg0HCKb5nNY45kKzK+76YOGx7e36uUe","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa_1686050771484_0.8071513733760523","host":"s3://npm-registry-packages"}},"0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499":{"name":"storage-mixin","version":"0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"9a96f802f44b7a1851b82577350ec51c97a24e30","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499.tgz","fileCount":22,"integrity":"sha512-LFxoG2NWzdAeXr3I71MpG0IgFGspQPwCAIaK5RBZQ5GqMU/0xVJ3hOSOwpxlEprqbwcflrdZY5ZH92key4LEgA==","signatures":[{"sig":"MEUCIQDeeCjAKOP4HvDu2sJI3nqi/4datQfAAZ8lrkgzOYvf2AIgdBcan+QE/gmqP3cFHz4KALF48HG22OMvbg1gmvCt5Is=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"52e439f268b74410212a0d91a5ee39021eb44499","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499_1686050848374_0.5405795757775644","host":"s3://npm-registry-packages"}},"0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467":{"name":"storage-mixin","version":"0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4d337698a2fb5c9aee37edd3220bfbe3f8ad87d7","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467.tgz","fileCount":22,"integrity":"sha512-tf7S+bkllJEGvu4iS+bEULH0b/DuV7iLqLsag7ZhYVKVBdg28hDTatxgNP6Qc/lSRuzGOH7ju1e552xfCFnvFw==","signatures":[{"sig":"MEUCIQDpY9FfILUmK4RCjspp3KRg64oNHAvRj+s8MAUs4/ATRgIgaigr07dp0vBL9smNHAEFw52TXbrWuGZ6NKgrXLRX4CI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5dfa7c0dfa9690d09de616d9a4839fde1ab0e467","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467_1686207509766_0.9253657697054853","host":"s3://npm-registry-packages"}},"0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731":{"name":"storage-mixin","version":"0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"55d75364915f1ca010bd3cb6f8f157d7679c67b3","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731.tgz","fileCount":22,"integrity":"sha512-r7Dv8wxnPHFqK8OV17v7G7XLHQSsLVRDG4ncNJrJizxLHWJm8d1Iz1vruJXvVq/qVx/mqBz0oShWSs4eiaVobw==","signatures":[{"sig":"MEQCIDFvi8Tx1zieUWvTWNx8EieppxautLl9KUpFexPzDE6tAiBFRmd4lROqWR95OhSf5z1Oti9/+9sgNMP0jJzjfKpLHQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1d02bfb24078b4391bee7a83e34cb3d7da39a731","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731_1686207708463_0.5884111643899048","host":"s3://npm-registry-packages"}},"0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04":{"name":"storage-mixin","version":"0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"ce868fcc7e888325bfac4b36dba083d584373191","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04.tgz","fileCount":22,"integrity":"sha512-iBiW3Z/3D5l284F+DQqZ4shQR+wbau5so/ibuIjyCSYBK43Rsu6rPouIl9wR3rlBnY8joIESghfzI/KPdrGbsw==","signatures":[{"sig":"MEUCIGjVlPbAkiUFAQusbxij6bvkQqjBy1FFXuVpmU/miiO0AiEA/IL6ydQqRWLh1f8Tkov7urkw3FJzBeccuAjkX0DMev4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"b2733835a3b65a4990e1af518669453fad1aba04","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04_1686207974450_0.24337088588279832","host":"s3://npm-registry-packages"}},"0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1":{"name":"storage-mixin","version":"0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"201c973a7a8cd1ac9e0d95f20d40995cde142a66","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1.tgz","fileCount":22,"integrity":"sha512-0t8f6jsVWSYLNyad6S55LP0ju81VJIt09h1IK6gKajYA8rgJyosekCeWd1x+zIpvkAhIs2T0Vv9zYx99X9FEnA==","signatures":[{"sig":"MEQCIBfCh3f+YSTxshLKdSfY6SnZMfn6jqimnhBCUSrkBulwAiA+I5gVn9US6Eba7Jz3Ods9WwTaE7IaZLtNLl+56xUYjA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1_1686211836404_0.8613120075515637","host":"s3://npm-registry-packages"}},"0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1":{"name":"storage-mixin","version":"0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"74e0ac073d6db7ee2081b579180015fb3421c631","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1.tgz","fileCount":22,"integrity":"sha512-qT0sQsVwjkb72dE8XUxmkuhBFQ+gUqqJIZ+nGxVgpNlNmHPzdjhBfxMJmCMLvOkfohfmSizlNyc2lLPvoGiOlg==","signatures":[{"sig":"MEUCIQDXLp/PrGkpknAnuIWpkZQUcXNoKD3q5ct28pu1db7RfAIgBvTLveAYYc0WWMycDxO/Gm6vetys7JvDpomex2oDCUk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"a163d3eea7baaadc9ff00f56212f6befadf68cc1","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1_1686365444059_0.4063394742628321","host":"s3://npm-registry-packages"}},"0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682":{"name":"storage-mixin","version":"0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"6c53335de10b0c75c0a38b0b3cdf7cebc7355d5d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682.tgz","fileCount":22,"integrity":"sha512-rH3eQ5XLB/7l4b5SGLfJQclu3npsU/cbubvw4YGTT0qisUDEoyOADIjap2TqRfgaYLjzmcFcZojVw+m3RrMzCA==","signatures":[{"sig":"MEQCIC9DcEuOnFo2bvudbUsrhgQEEsXhN43Xqcnp2P4K7UNgAiBdmHUd9EL2wxnpEpQqQjA1IJFO75d8KN5M7U3YNH9GeQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"e35a108a54700c3d0f1f8d937fe870db23cb1682","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682_1686369509440_0.022946677442424734","host":"s3://npm-registry-packages"}},"0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205":{"name":"storage-mixin","version":"0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"16c34463bc248a4d38c9e6f5c473eb8ca026f000","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205.tgz","fileCount":22,"integrity":"sha512-OMeeBL+G511AxwhnanhIMBpYDSXQz4EyWVsgRHlno164BtczHAdsDEF9E0ujXdzJAmgILenhvItUfZ4YsvR6gw==","signatures":[{"sig":"MEUCIQDY7RQsmhGF8m3pWEOzGV6H0zmAlfO6qOOVa0dP4SsYKQIgSS6zcwtGE/Mns3bHA2cT++1mdp9RGJldje4CO0vZrAc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"80a9e175edd3eabee53daee876d77943872e4205","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.6","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205_1686610386442_0.808882122458827","host":"s3://npm-registry-packages"}},"0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66":{"name":"storage-mixin","version":"0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"3309e0639dc28e7d0ffc944be6030c2a1e68b66a","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66.tgz","fileCount":22,"integrity":"sha512-Gz/SA4tlnwgkIo0/0llTEOHqcGc4j8aWEFqNgtOg7h61PggIkD4FlGfhbEhLRluZf3S6+lUkVzm4gmAbJ+4eNw==","signatures":[{"sig":"MEYCIQDxWMkXDBXItDgM/JR3hDY1t+mnJrF4Q1cPE4feEDXkUwIhAJOQ2OjGr4TRK776STi8utBoOki9XFfvA5RspDyd3OVP","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"707fe01258204f4be98f1b7a6cffef62deed0b66","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^22.3.12","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66_1686650968735_0.07694832825811004","host":"s3://npm-registry-packages"}},"0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503":{"name":"storage-mixin","version":"0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"877122cb1622ec7e0a5b83ced3c79086f09f11b6","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503.tgz","fileCount":22,"integrity":"sha512-cBkp98r+OwAk5ED4Ut515LRs+Q0D5uGyOKzfoeLre0gXMlTeh5hnA2Gnp+zhTXg3NiTl1uMfI4JeQ350Y0jTeg==","signatures":[{"sig":"MEUCIQDZS1TnushGJCtVlioQDadNQ7ur5l7cpkLwi4bXJxW1LQIgbCEMSuxV8t1ZIynOEd4vAXKOkn1TP4+I6pB1mDsOhyg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"58b07e3b9faef89f8f737552ca57d6db6e0ea503","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.6","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503_1686783968636_0.9753577622358829","host":"s3://npm-registry-packages"}},"0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2":{"name":"storage-mixin","version":"0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"fcfc558a65fe80618ef9b6d89038d5373af2d590","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2.tgz","fileCount":22,"integrity":"sha512-so3peqsLFcUV+edwOWpRGqLEv/MeDEddK/Huyqtq8goFK/igMLC5THKbLrfKvkmNbfvVV7+QDk8I3YJv9g+jQA==","signatures":[{"sig":"MEQCIFy9L7t/wIb3mXPJi4nnVCVzk+yAAP7tOZZs75YaNj4mAiBm2QsparwSTDppWw+JN6znmavgQvz4qR0J8PZDJPpGxg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.6","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2_1686784198443_0.8806556828631622","host":"s3://npm-registry-packages"}},"0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829":{"name":"storage-mixin","version":"0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"94ff4c666fa5f00bfc9dd1b03a4843e2d600e4a8","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829.tgz","fileCount":22,"integrity":"sha512-xowkI3ozu2AE9J/o6Q5e0dK1jCIQpoDf/s/Q9/SjwGjikAmhv2aG3wlJ9QclVAwTJ/ABeHAbkbPMalCxIMQBFw==","signatures":[{"sig":"MEQCIC4DS2ue+EHZ9XDJ8wJ5SRfn+DPgaOzQ1Mje9XkU4iLVAiAXNR0NJ4v4IrXkULvVXvnR9ouSAuxUFDsVGoQCjfJ1VA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"60cc295fd36171b66786a43c0396bcc8db207829","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829_1687419634265_0.9567165575355887","host":"s3://npm-registry-packages"}},"0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327":{"name":"storage-mixin","version":"0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"dcaa30d0fe465d1daaf3f8f58208a5b0aa1cad70","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327.tgz","fileCount":22,"integrity":"sha512-Z1Lz0YxuKu6K0jHrY6UHfWjKDmC/kYvsSm44HxOusRk/2XfLekDBW8gobeVQMF1OH91Idd2khaYHipY1BFHVrQ==","signatures":[{"sig":"MEYCIQC9YAxk0UgoJYXXioRAvYo4Ez/kdtIjQbZp7lUBEQUKqAIhAJtv8p1cfsnv9YViysktXxCQFjJ5+L6fgU5Ev0ky9btx","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"3ddf2b32a13c98a8713916c7c20185f8ae9a9327","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327_1687577962402_0.5207134459686442","host":"s3://npm-registry-packages"}},"0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5":{"name":"storage-mixin","version":"0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"5a40fb1b2374f5d3e5fb05751009ce188922fd15","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5.tgz","fileCount":22,"integrity":"sha512-+Sbl76V1bw1FTvXxgUC0MNy/OdUZsOkWgIhHmNqRu8B3bXEWVa8PjK0M4VFIQDSWcdS32mEwcZRxylZ6Y0yGhQ==","signatures":[{"sig":"MEUCIDujp8eIHLzXhQfl1v7kDPPUT1gtlt0lEB+WYtDRSsHWAiEAlrRGAtuGRNiHxNL6a56YoRDdlA+IRyvDBfO2iClb/EU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.7","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5_1687578117665_0.697279142660469","host":"s3://npm-registry-packages"}},"0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e":{"name":"storage-mixin","version":"0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"bd90db61369d201889e00fa7d8e4b1f8fe4befa4","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e.tgz","fileCount":22,"integrity":"sha512-8vFXaSXxASNNQasKmJBMsUvzuMBAVi+39utryReIEW6RrXM1u5EkR1G9bTcauF5kxbOjewJEjqulR11KrhACbQ==","signatures":[{"sig":"MEUCIQDbsg4bzfP6pC9fuOddqn1A9l3RuKwtT5kNFJxw96SNnQIgdt1uyJgllsjDnu425Azdp6bfAThK43Eow5wQ+HZbi4A=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.8","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e_1687970065336_0.8369431396484237","host":"s3://npm-registry-packages"}},"0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da":{"name":"storage-mixin","version":"0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"0299edda63e3f7a68ff2e928cca2f3af1c4d126e","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da.tgz","fileCount":22,"integrity":"sha512-goVolqpQz4QRFAVCtxs000HxsgBPdX8tsDTSJJ0dk370XGUq8bKlAWDxQmHwhog1ikTrtTn5aY8jsAbfgxSp9A==","signatures":[{"sig":"MEQCIBGABZPCtFasycMh/BYwrXnuDGu06Q5h8ZrOtTVKXnIaAiArUNcZ22JaOGlOHX6s3OlTkafheoU5bXiAArbqeAbXkA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"c584ad92337ea0098e7068e83ed68dd13565b7da","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.8","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da_1688102538472_0.902461180587345","host":"s3://npm-registry-packages"}},"0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492":{"name":"storage-mixin","version":"0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"de0e5517a521e8c8162c94cb6c5e93b75c3945e0","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492.tgz","fileCount":22,"integrity":"sha512-1aMJKtqMw9luvDeNRxMhuPhuUwOOkBgxDw4AW0lgQYRUiiSAzvjrZD6qVZyfGZ1zYy/IlUvQ5gTSQip99Uidgg==","signatures":[{"sig":"MEQCIDXdBT2W8oiPRYVxY2bq6Eahuy/rfWMNHJeV9IV1OKKVAiBLMXTZZCRWYdXQxmPIYRpEa3qV5zatkRNl0R7oR0pFmA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"835937ee6a94b541fd12d3d0c54d829fb2d0e492","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492_1688150063275_0.2574435258181986","host":"s3://npm-registry-packages"}},"0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37":{"name":"storage-mixin","version":"0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"a1192e74cc360f657eef8f5c0c1059763ffc6743","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37.tgz","fileCount":22,"integrity":"sha512-Gaht4I6xmjWiFwCkvndLZ/d8Nn6KJMgsOuxUxYb1hAWhKaHXfkZWrwvzFXoeCz3Plz9WGpXn59He25cNZ/Mj5w==","signatures":[{"sig":"MEQCIGCmIzPb0XS7d1wXmYqh1MIl07y01Ezr8PrCsU/H9YxCAiBscPPpiqUVwRATGR5qxFYeBTLIs9zW1Sn0+YPCOMt4nQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"a7eb730693b63501028444f9ef6b634620af6e37","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37_1688409920558_0.9295082919154369","host":"s3://npm-registry-packages"}},"0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128":{"name":"storage-mixin","version":"0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4e898ba4543732f321d6d44a109d7d6249bcfa32","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128.tgz","fileCount":22,"integrity":"sha512-YFSXo4bOLzRmOw9R4mWmJ2kjRRDL3dkFEkqrK+TksPwFtz8AKsi2XfOOV5lFFEvBJpfW5+zJuBT2wrj0IJkcVw==","signatures":[{"sig":"MEUCIQC0XupT53+Jy4CkB8xi7CvQXnumdKvjlm65XRia5duEKAIgRGaegA6MkEmHt0tZRYZIFxIQkYh9PllMx1txk7yMgV4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"084f1c20551b15b25b3945fae7547f5321bc4128","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128_1688410044418_0.4505936783557827","host":"s3://npm-registry-packages"}},"0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292":{"name":"storage-mixin","version":"0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292","maintainers":[{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"e3fadbc904253ffa7c001a462e8c5429ad26585d","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292.tgz","fileCount":22,"integrity":"sha512-VvyF0Ui99+/VCO1spAUGS9ArDD8KEohMbQzWW+H87c2CTv4VncorglefN+TVrKyg30s8VJtMdlQSoK1B6Q1E8Q==","signatures":[{"sig":"MEQCIDZ/FzxmAzle4CicWUvHwk+VliCVEDCY1bRWJjtPLzPTAiA44eXpVK5fvRMC5AHMJmvVfwYv8oBMnhlkyW9826233A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"9c1e839a379c1d7525de44084db049cc54c0b292","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292_1688587860848_0.629341689989722","host":"s3://npm-registry-packages"}},"0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5":{"name":"storage-mixin","version":"0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5","maintainers":[{"name":"c-buckingham","email":"christopher.buckingham@mongodb.com"},{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"4fa243e758b2b959b26d73ac2113e58064693cac","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5.tgz","fileCount":22,"integrity":"sha512-239j/NtLdIARyk1E2M2YOY8mN0LQV/f6ybyKy1OkQUTPjGliwBmNxgxlivq2k4txTbuPLKPuodoPejQxgN/t7A==","signatures":[{"sig":"MEUCIEbojMVL64nqgQ18kn2xxjU8YLA1Ms4ZQVnJWNx1N1xbAiEAuz2qceH0n14ca1MvhK2uxx8XjH+oHiROwlgEgbjw1hg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"247cba5e738b47e2c433fd1bc2e3d0ed48142ca5","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5_1689216237703_0.8908432714062611","host":"s3://npm-registry-packages"}},"0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8":{"name":"storage-mixin","version":"0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8","maintainers":[{"name":"c-buckingham","email":"christopher.buckingham@mongodb.com"},{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"fea899bf75ca6a06527ca554aa59bdb162c92186","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8.tgz","fileCount":22,"integrity":"sha512-yKqfR2dmAz5C3sayzxKUD+TEjOTpfjeBlrLPUXDDJZnyWVQdUW2uyrs0TYcrVV9TPPWku9KL8CL5uvPnbMPITQ==","signatures":[{"sig":"MEYCIQDOezSDMNcRTTk+xpq7ZWxh5xJLx3QFZAtI1gobRLH3aAIhAMfpsF6bEI7PDWN0MP52+VX+I0jchbfh4Wpz2EGDHx04","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"8c579fa95e9deb46d73653d702f7f3b0e41efeb8","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8_1689907303522_0.884835252607032","host":"s3://npm-registry-packages"}},"0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127":{"name":"storage-mixin","version":"0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127","maintainers":[{"name":"c-buckingham","email":"christopher.buckingham@mongodb.com"},{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"d1a5998f8411e569c252fbaa927d1c60aa925faa","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127.tgz","fileCount":22,"integrity":"sha512-sW6keSrY2HRX/MaRW0vVa9lvyO2vDFvQQ2fl2VBYTdh89lBMM3WcFVPuxIz0O5YM8oPDkcKXK+cfnMwNr/+ZqA==","signatures":[{"sig":"MEUCIQDlPnCQ4bzTlAaGpwqEIs4trrhiTFmmso4PTkMHfNPrdgIgUQ/Y9y7i0/30w5G5jM3DI6G717sO5kDzLuTRyNV54fI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"1d0257ec5ae772888fbfb677bbacf8cd7dfb3127","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127_1689909828599_0.223931209047999","host":"s3://npm-registry-packages"}},"0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac":{"name":"storage-mixin","version":"0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac","maintainers":[{"name":"c-buckingham","email":"christopher.buckingham@mongodb.com"},{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"cef932dd7775e2162e6a31f9ad0285d4e9c48396","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac.tgz","fileCount":22,"integrity":"sha512-Xdd9cBis6U9MLKpLBEBvPLxDizPHTT3UZrredotO2HyqdEqdoeggDIghCuSBxzYlmp9gzhX4KRCdzwJ3YHyXcw==","signatures":[{"sig":"MEYCIQD60NfZSds6YmKxBoiNBk7rVg7dhh0021L3+G1AEzRwwgIhAIUbMULc8sktK5XwV9HJkWNDTHXxqgt24eaeQcrszMP9","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85809},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"5bb899576d8b95cb24b170e4fb80a7a4cc89beac","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.9","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac_1690200345594_0.7219104223011132","host":"s3://npm-registry-packages"}},"0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d":{"name":"storage-mixin","version":"0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d","keywords":["mongodb-js","preferences","settings","ampersand.js"],"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","_id":"storage-mixin@0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d","maintainers":[{"name":"himanshusinghs","email":"himanshu.singhs@outlook.in"},{"name":"c-buckingham","email":"christopher.buckingham@mongodb.com"},{"name":"mongo-j","email":"james.wang@mongodb.com"},{"name":"mabaasit","email":"baasit121@yahoo.com"},{"name":"alexander_schroll","email":"alexander.schroll+npm@mongodb.com"},{"name":"chuck.kalmanek","email":"chuck.kalmanek@10gen.com"},{"name":"mongodb-js-user","email":"dana.groff+mongodb-js@mongodb.com"},{"name":"rueckstiess","email":"thomas@rueckstiess.net"},{"name":"durran","email":"durran@gmail.com"},{"name":"lerouxb","email":"lerouxb@gmail.com"},{"name":"fredtruman","email":"fred.truman@mongodb.com"},{"name":"mbroadst","email":"mbroadst@gmail.com"},{"name":"hswolff","email":"hello@hswolff.com"},{"name":"satyasinha","email":"satya@mongodb.com"},{"name":"matt_d_rat","email":"matt@mattfairbrass.com"},{"name":"rhysm","email":"rhys.howell@10gen.com"},{"name":"tomhollander","email":"tomhollander@hotmail.com"},{"name":"alena.khineika","email":"alena.khineika@gmail.com"},{"name":"jeff-allen-mongo","email":"jeffrey.allen@10gen.com"},{"name":"mmarcon","email":"me@marcon.me"},{"name":"jonathan.balsano","email":"jonathan.balsano@mongodb.com"},{"name":"mongodb-build","email":"build-accounts@10gen.com"},{"name":"jack.weir","email":"johnjackweir@gmail.com"},{"name":"stennie","email":"stennie@cpan.org"},{"name":"mcasimir","email":"maurizio.cas@gmail.com"},{"name":"kristina.stefano","email":"kristina.stefanova@mongodb.com"},{"name":"jarjee","email":"nathan.smyth@10gen.com"},{"name":"shaketbaby","email":"shaketbaby@gmail.com"},{"name":"devtoolsbot","email":"iteng@mongodb.com"},{"name":"addaleax","email":"anna@addaleax.net"},{"name":"gribnoysup","email":"sergey.petushkov@protonmail.com"},{"name":"mutukrish","email":"mutukrish@gmail.com"},{"name":"imlucas","email":"hrabovsky.lucas@gmail.com"}],"contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"homepage":"https://github.com/mongodb-js/compass","bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"dist":{"shasum":"859b97df1e4d7db9f89eccd121c576fbb8711fe6","tarball":"https://registry.npmjs.org/storage-mixin/-/storage-mixin-0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d.tgz","fileCount":22,"integrity":"sha512-uztBTgJr4RSvpP/QMSZs6v7cQf6fa+DcumnpzAXLFgb3/AHvCGM77/jpYtHDOwgI4bCDebkJL6VuIFCPUk9+IA==","signatures":[{"sig":"MEYCIQCLPSUzhGD/WHBZCYT3LZb5FDp3AE69x6iUnXFR3HL7WQIhAJV2+axfcwIIfYP7rT6JCvI8g7T1oYnktbkWbaG5k+EV","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85810},"main":"index.js","types":"index.d.ts","readme":"# storage-mixin [![][npm_img]][npm_url]\n\nPersist [Ampersand.js](https://ampersandjs.com/) models and collections to various storage backends.\n\n\n## Installation\n\n```\nnpm install --save storage-mixin\n```\n\n## Usage\n\nUse this mixin with any existing model and collection to easily persist\nthem to a number of different storage backends. The model needs\n- the mixin\n- `idAttribute` value (Ampersand's default is `id`)\n- `namespace` value\n- `storage` key to pass options to the mixin (see [Options](#usage-options))\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar Spaceship = Model.extend(storageMixin, {\n  idAttribute: 'name',\n  namespace: 'StorableModels',\n  storage: {\n    backend: 'disk',\n    basepath: '/tmp'\n  },\n  props: {\n    // your property definitions, will be persisted to storage\n    name: ['string', false, ''],\n    warpDrive: ['boolean', false, false]\n  },\n  session: {\n    // your session properties, will _not_ be persisted to storage\n  }\n  // ... other model methods\n});\n```\n\nNow you can call call the [`.save()`][ampersand-save] method on instantiated models.\n\n```js\nvar model = new StorableModel();\nmodel.save({name: 'Apollo 13', warpDrive: false});\n```\n\n### Options\n\nOptions are passed to the storage mixin via the `storage` key. If you only\nwant to choose which backend to use and don't need to pass any further options\nalong, the `storage` key can be a string with the backend name.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: 'disk',   // use disk storage with default basepath `.`\n  props: {\n    // ...\n  }\n});\n```\n\nIf you want to further customize the storage mixin, use an object and provide\nadditional options. The `backend` value is required, all other values are\noptional and backend-dependent.\n\n```js\nvar StorableModel = Model.extend(storageMixin, {\n  storage: {    // use disk storage with a custom basepath\n    backend: 'disk',   \n    basepath: '/tmp/myapp/storage'    \n  props: {\n    // ...\n  }\n});\n```\n\n### Backends\n\nThe following backends are currently supported: `local`, `disk`, `remote`, `null`,\n`secure`, `splice`.\n\nThe default is `local`.\n\n#### `local` Backend\n\nStores objects in local storage of the browser. Only works in a browser context.\nThe backend uses the [`localforage`][localforage] npm module under the hood and\nsupports IndexedDB, WebSQL and localStorage drivers. A separate instance of\nthe store is created for each `namespace`.\n\n###### Additional Options\n\n`driver`\n: The driver to be passed on to `localforage`. One of `INDEXEDDB`, `LOCALSTORAGE`\nor `WEBSQL`. The default is `INDEXEDDB`.\n\n`appName`\n: The name of the IndexedDB database (not the data store inside the database,\n  which is the model's `namespace`). Most users will never see this, but it's\n  best practice to use your application name here. Default is `storage-mixin`.\n\n\n#### `disk` Backend\n\nStores objects as `.json` files on disk. Only works in a node.js / server\ncontext, or in Electron renderer process where `remote` module is available\nto get access to the `fs` module.\n\nThe file location is `<basepath>/<namespace>/<id>.json`. `<basepath>` is\nprovided as option. The `<namespace>` is set on the model directly, and the\n`<id>` is the property of the model specified by `idAttribute`. The first\nexample on this page would be stored as:\n\n```\n/tmp/StorableModels/Apollo 13.json\n```\n\n###### Additional Options\n\n`basepath`\n: The base path for file storage. The default is `.`.\n\n#### `remote` Backend\n\nThis is a wrapper for [ampersand-sync][ampersand-sync], that stores and\nretrieves models to/from a remote server via asynchronous ajax / xhr requests.\nPass in the [`url`][ampersand-model-url] value as an option or set it\ndirectly on the model.\n\n###### Additional Options\n\n`url`\n: The url to fetch the model/collection, see [ampersand-model#url][ampersand-model-url].\n\n#### `null` Backend\n\nThis backend exists mostly for debugging and testing purposes. It does not\nstore anything but will return with successful callbacks on all method calls.\nFor reads, it will return an empty object `{}` for models, or an empty array\n`[]` for collections.\n\n#### `secure` Backend\n\nThe `secure` backend wraps the [`keytar`][keytar] module to persist data into\na secure keychain, keyring or password manager (works for OS X, Linux, Windows).\nThere are some limitations though as the interface does not allow to list all\nkeys in a given namespace. Therefore, to fetch a collection, it has to be\npre-populated with models containing the ids.\n\n```js\n// this won't work !\nvar collection = new StorableCollection();\ncollection.fetch();\n\n// do this instead\nvar collection = new StorableCollection([\n  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}\n], {parse: true});\ncollection.fetch();\n```\n\nThe static `.clear()` method that other storage backends possess is also\na no-op in the `secure` backend for the same reason. Keys have to be deleted\nmanually.\n\n\n###### Additional Options\n\n`appName`\n: Entries in the keychain have a key of `<appName>/<namespace>`. As this is\n  visible to the user, you should use your application name here. Default\n  is `storage-mixin`.\n\n#### `splice` Backend\n\nThis is a hybrid backend that consists of a `local` and `secure` backend\nunder the hood. It also receives a `secureCondition` function as an optional\nargument that takes a `value` and `key` and returns whether or not this key\nshould be stored in the `secure` or `local` backend. On retrieval, it merges\nthe two results from both backends together to form a complete object again.\n\nThis is particularly useful to store user-related data where some fields contain\nsensitive information and should not be stored as clear text, e.g. passwords.\n\n\n###### Additional Options\n\n`appName`\n: Passed to both the `local` and `secure` backends, that acts as a global\nscope (e.g. database name in IndexedDB, prefix in keychain keys). Use your\napplication name here. Default is `storage-mixin`.\n\n`secureCondition`\n: Function that decides which keys/values of a model should be stored in the\n`secure` backend vs. the `local` backend. The function takes a value and key\nand must return `true` for the keys that need to be stored securely. Default\nis:\n```js\nfunction(val, key) {\n  return key.match(/password/i);\n}\n```\n\n###### Example\n\n```js\nvar Model = require('ampersand-model');\nvar storageMixin = require('storage-mixin');\n\nvar User = Model.extend(storageMixin, {\n  idAttribute: 'id',\n  namespace: 'Users',\n  storage: {\n    backend: 'splice',\n    appName: 'My Cool App',\n    secureCondition: function(val, key) {\n      return key.match(/password/i);\n    }\n  },\n  props: {\n    id: 'string',            // stored in `local`\n    name: 'string',          // stored in `local`\n    email: 'string',         // stored in `local`\n    lastLogin: 'date',       // stored in `local`\n    password: 'string',      // stored in `secure`\n    oldPassword: 'string'    // stored in `secure`\n  }\n});\n\n```\n\n[npm_img]: https://img.shields.io/npm/v/storage-mixin.svg?style=flat-square\n[npm_url]: https://www.npmjs.org/package/storage-mixin\n[ampersand-sync]: https://github.com/AmpersandJS/ampersand-sync\n[ampersand-save]: https://ampersandjs.com/docs/#ampersand-model-save\n[ampersand-model-url]: https://github.com/AmpersandJS/ampersand-model#url-modelurl-or-modelurl\n[localforage]: http://mozilla.github.io/localForage/\n[keytar]: https://www.npmjs.com/package/keytar\n","gitHead":"71516462af839d62ee28dd99ff05de7ed4ce8d8d","scripts":{"lint":"eslint \"./{src,lib,test,bin}/**/*.{js,jsx,ts,tsx}\" \"./*.js\" --no-error-on-unmatched-pattern","test":"mocha --file ./test/setup-keychain.js","check":"npm run lint && npm run depcheck","test-ci":"npm run test","depcheck":"depcheck","test-electron":"xvfb-maybe electron-mocha --file ./test/setup-keychain.js --no-sandbox","test-ci-electron":"npm run test-electron"},"_npmUser":{"name":"mcasimir","email":"maurizio.cas@gmail.com"},"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"_npmVersion":"lerna/4.0.0/node@v16.17.0+x64 (linux)","description":"Ampersand model mixin to persist data via various storage backends","directories":{"test":"test"},"_nodeVersion":"16.17.0","compass:main":"index.js","dependencies":{"uuid":"^3.3.3","async":"^3.2.2","debug":"^4.2.0","keytar":"^7.9.0","lodash":"^4.17.21","hadron-ipc":"0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d","localforage":"^1.7.3","ampersand-model":"^8.0.1","write-file-atomic":"^3.0.1","ampersand-rest-collection":"^6.0.0","@mongodb-js/compass-logging":"0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"mocha":"^10.2.0","eslint":"^7.25.0","depcheck":"^1.4.1","electron":"^23.3.10","xvfb-maybe":"^0.2.1","electron-mocha":"^10.1.0","eslint-config-mongodb-js":"^5.0.3"},"_npmOperationalInternal":{"tmp":"tmp/storage-mixin_0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d_1690628772609_0.28869805990034747","host":"s3://npm-registry-packages"}}},"time":{"created":"2015-11-29T00:43:09.529Z","modified":"2026-07-15T15:36:30.094Z","0.0.1":"2015-11-29T00:43:09.529Z","0.0.2":"2015-11-29T00:43:49.517Z","0.0.3":"2015-11-29T00:47:29.949Z","0.1.0":"2015-11-29T06:55:16.859Z","0.2.0":"2015-11-30T07:21:36.071Z","0.2.1":"2015-11-30T07:30:50.474Z","0.3.0":"2015-11-30T08:47:52.692Z","0.3.1":"2015-11-30T12:21:24.950Z","0.4.0":"2015-12-01T01:56:42.590Z","0.5.0":"2015-12-01T05:39:36.423Z","0.5.1":"2015-12-03T09:41:43.390Z","0.6.0":"2016-04-25T01:50:43.445Z","0.6.1":"2016-04-28T00:17:07.786Z","0.6.2":"2016-06-17T17:54:00.504Z","0.7.1":"2016-06-27T18:06:58.934Z","0.7.2":"2016-06-27T18:12:22.402Z","0.8.0":"2016-07-26T09:49:49.484Z","0.8.1":"2016-11-23T04:42:40.111Z","1.0.0-beta.1":"2018-11-29T21:26:32.701Z","1.0.0":"2018-12-04T14:41:35.975Z","2.0.0":"2019-02-25T10:55:19.636Z","3.0.0":"2019-03-25T13:03:22.586Z","3.1.0":"2019-08-22T13:50:18.610Z","3.1.1":"2019-08-25T21:31:19.196Z","3.2.0":"2019-09-09T14:47:25.544Z","3.2.1":"2019-09-10T10:04:25.437Z","3.2.3":"2019-09-10T10:37:33.593Z","3.2.4":"2019-09-12T09:41:47.673Z","3.2.5":"2019-09-18T13:14:31.362Z","3.2.6":"2019-09-24T18:00:12.602Z","3.2.7":"2019-10-28T13:55:30.606Z","3.3.0":"2020-01-14T02:25:41.269Z","3.3.1":"2020-01-14T02:27:10.640Z","3.3.2":"2020-01-14T02:28:10.401Z","3.3.3":"2020-04-17T13:19:30.213Z","3.3.4":"2020-08-12T10:43:06.721Z","3.4.0":"2021-05-26T18:16:18.234Z","3.4.1":"2021-05-27T16:06:39.788Z","4.0.0":"2021-06-03T19:10:37.869Z","4.1.0":"2021-06-09T13:57:54.206Z","4.2.0":"2021-06-16T17:37:58.618Z","4.2.1":"2021-06-18T15:24:44.500Z","4.3.0":"2021-06-21T09:25:22.955Z","4.4.0":"2021-06-22T07:32:01.722Z","4.5.0":"2021-06-28T08:49:19.579Z","4.5.1":"2021-08-05T11:58:23.016Z","4.6.0":"2021-08-11T11:37:40.983Z","4.7.0":"2021-09-15T10:50:38.019Z","4.8.0":"2021-11-19T11:09:03.687Z","4.9.0":"2021-12-21T14:14:51.367Z","4.10.0":"2022-02-03T13:34:08.419Z","4.11.0":"2022-02-25T14:09:36.600Z","4.12.0":"2022-03-03T14:36:48.153Z","4.13.0":"2022-03-30T17:14:04.997Z","4.14.0":"2022-04-27T16:30:42.825Z","5.0.0":"2022-08-09T13:25:32.719Z","5.1.0":"2022-09-22T15:14:07.222Z","0.0.0-experimental-1c53312ce4905234885618d41ae95fde9c21aa18":"2022-09-26T13:17:02.645Z","0.0.0-next-e30a9e850a8a66b70770fbf6658a3e35cf1ff8b8":"2022-09-26T14:07:24.810Z","0.0.0-next-25b11de63d51aa4ca7fda0f3eae67999e3418ca5":"2022-09-28T16:53:55.984Z","0.0.0-next-dfa464112f63969f158bde32322e393fa2b77940":"2022-09-28T22:05:23.733Z","0.0.0-next-e42d58083be39ce9f112e6ec7f9fd1fdcb666e3e":"2022-09-29T16:07:31.348Z","0.0.0-next-5f69e8129e0242b4e507fee055188a8a83e1f1c1":"2022-10-05T11:10:47.940Z","0.0.0-next-823f55a862f13d28437b87fb594450b2208c0d4f":"2022-10-05T16:14:55.515Z","0.0.0-next-01a3ac56d52443bc859ccdcf7ed301ffbdea7a47":"2022-10-06T09:46:47.234Z","0.0.0-next-cd3c5c1303c464ef7900dc08adb8154d15c7f3a9":"2022-10-06T14:44:01.992Z","0.0.0-next-d9691f3c8230e21aeb2817ac2c984aba0d79f09c":"2022-10-07T19:44:36.688Z","0.0.0-next-1cb9ea1724d90e58422b33fe089df5b774e0be10":"2022-10-07T19:49:26.352Z","0.0.0-next-4216a27cdf41425fff35938bb42040bb93c2d246":"2022-10-07T20:00:12.994Z","0.0.0-next-e3d7e58db726184c34e0d2d9f3342595a865eb55":"2022-11-01T17:36:20.333Z","0.0.0-next-dd9be0f790095ebc62a3de5b5f33543ff3c55cf3":"2022-11-02T09:11:06.534Z","0.0.0-next-10815be8fd57f3bfd89d061e1592eb7136d4a0fb":"2022-11-02T11:30:46.186Z","0.0.0-next-59e1f6f134da2a3417bd69a71c7788320608ee5d":"2022-11-04T03:10:05.332Z","0.0.0-next-ea4f317e964c0504e54c01d83c385280a9135bba":"2022-11-04T03:18:12.477Z","0.0.0-next-bfa0f33f79b0349abe5ad03576e17682f507fe04":"2022-11-08T21:27:17.670Z","0.0.0-next-5f5cecf01c890c348e17907482b03cea2f8c5f21":"2022-11-09T23:44:26.066Z","0.0.0-next-51a8e00f16dc1652cb0f0674c540570614a8895e":"2022-11-09T23:50:11.339Z","0.0.0-next-6d1491390706ac21857752412a5e4d10e112a29a":"2022-11-09T23:54:25.379Z","0.0.0-next-44318443f2cd1088082181789b25fc26a7a11bb2":"2022-11-09T23:56:05.334Z","0.0.0-next-3b50f8232d3349fe79554f36417d7fbb45b6352a":"2022-11-10T00:00:27.322Z","0.0.0-next-47b085701d7c0b212b54bcac46f6106d34ec429e":"2022-11-10T12:45:59.539Z","0.0.0-next-9e3b266e199e346a30e2c20aac373d48c2ea9888":"2022-11-11T20:43:36.869Z","0.0.0-next-91daa029e219b08cf0b775b6648d35867f2272d0":"2022-11-16T23:12:32.034Z","0.0.0-next-27bdd4c654b0108a364c4bb3541996722734028c":"2022-11-17T02:40:48.193Z","0.0.0-next-7f1112246f97f222dc289edb7b9f0359d8f020cb":"2022-11-17T02:50:10.182Z","0.0.0-next-c12720c09369b6620405de027fa85d469db43e9c":"2022-11-18T04:59:41.511Z","0.0.0-next-2122563cf622c0d212372dee10ec2a4a664d8006":"2022-11-18T05:09:30.796Z","0.0.0-next-c31c6db319e5099ee073b5782609b1dcfa2370d8":"2022-11-19T06:50:14.709Z","0.0.0-next-981f8ae49e299320ca0add5ae8e58c8738baa699":"2022-11-19T07:03:55.341Z","0.0.0-next-6a646700444fec2ae51cd86f87f6a29e58f774b0":"2022-11-19T07:06:29.330Z","0.0.0-next-112bf8f8b20d7181824478f76e627ee32d6e03d7":"2022-11-19T20:42:34.254Z","0.0.0-next-19de7da29c34177349014132e37b723c1cb16ebd":"2022-11-19T22:16:56.273Z","0.0.0-next-1484036deb50fe0421bb8be4c48b2f9e56c17a46":"2022-11-22T02:40:45.825Z","0.0.0-next-6e34a0d07479c665cdfa3bddb6bfd864365f6b8a":"2022-11-22T02:41:35.488Z","0.0.0-next-31a3fe49cf0eba4c3afe85c4a4139ce198cb0e51":"2022-11-22T02:44:29.286Z","0.0.0-next-bb1a39e78c30cda5ef910174e54d2c9708186388":"2022-11-22T02:50:04.996Z","0.0.0-next-b5a88ca5d89936f4997a6df7c6e08614f25de0a1":"2022-11-22T02:52:11.460Z","0.0.0-next-9a3af5fc8cc6a9ccc96866e1b71d0a33c14d7c08":"2022-11-22T02:59:47.356Z","0.0.0-next-2cde0fe836b81baa0f68d274840a5f97b8dae0c6":"2022-11-22T03:04:59.652Z","0.0.0-next-feb0121be4234a831e6bce640173de34ce95dd7a":"2022-11-23T01:39:11.984Z","0.0.0-next-64ed9e6634006598c90fc79f71c554ec401bfc8e":"2022-11-23T02:15:53.671Z","0.0.0-next-a005ee4428ffd61a00127102fa0c29212a52fc83":"2022-11-24T03:21:56.439Z","0.0.0-next-e06434c386fd387cc5650fc9c0906b46cb4d6c34":"2022-11-24T03:35:42.064Z","0.0.0-next-8d44ba9084fbf5b834ca7df8b77135d3c8fc6896":"2022-11-24T20:19:57.444Z","0.0.0-next-74685ebe9d7b81dd4a870c8ffd51152622741526":"2022-11-24T20:26:24.490Z","0.0.0-next-92270b35885e90f6eb7b153275848f7a2be21278":"2022-11-25T10:01:29.016Z","0.0.0-next-f9347a106881d77aa4b1f7f37daed25d73c5f92c":"2022-11-25T22:47:19.941Z","0.0.0-next-94f03d5249971d1eea1868df296db6e766f40f9f":"2022-11-25T23:48:14.013Z","0.0.0-next-e3ac63bd187d674b27865523c639e78bf78ac7a1":"2022-11-28T22:09:50.495Z","0.0.0-next-449f5b693a70d24bf653fcbd3719d8d88d91d899":"2022-11-29T23:35:25.708Z","0.0.0-next-9ee9b0963df24390835a677f1a9081d9bc53ca2a":"2022-11-29T23:39:52.086Z","0.0.0-next-98550b9ab2651e46658429899a0b7353249a18c0":"2022-12-01T09:47:00.515Z","0.0.0-next-f5e96f4dde195c3f4c44fc6c373583df1178a29d":"2022-12-01T23:16:52.728Z","0.0.0-next-21edffba0b9d147d7a297a3e4a69d68cdca09b82":"2022-12-01T23:28:31.526Z","0.0.0-next-6a5d526328ecfce1da82bf064daeb19f1c2bf6a5":"2022-12-04T22:31:33.715Z","0.0.0-next-2f189f8218b434e8d36a7472a2ac843f17147b9b":"2022-12-06T00:52:22.449Z","0.0.0-next-faf899c161858cffa138dc64f4fbf9c0da2145e0":"2022-12-06T00:54:04.311Z","0.0.0-next-f5d7198f71e9d27890af5dc79d01c3950c637d49":"2022-12-07T17:14:03.910Z","0.0.0-next-1336f6ccd01a8b5f63ed6bea289fa9f8fc4d9557":"2022-12-09T02:44:20.265Z","0.0.0-next-d43728ce0cf99f511bd2d2aebad966bc49276179":"2022-12-09T02:46:46.239Z","0.0.0-next-0d9e77c42a99b49fd4ecc7167d0c769866f92ef2":"2022-12-09T02:56:25.344Z","0.0.0-next-7db57a9d912a713312c9f79acdfcde9e49b554d9":"2022-12-09T18:24:20.839Z","0.0.0-next-907430527b638cb96704541b347715ec1dcc648b":"2022-12-12T21:33:07.879Z","0.0.0-next-3888dd701d06bedcc2b043270c5dc626b9997eb0":"2022-12-12T21:38:08.298Z","0.0.0-next-dc4590988660016a4419dbc587f3182af207ed15":"2022-12-14T18:28:22.977Z","0.0.0-next-cbaa086f387b9c9b62aef9381297773a9794a200":"2023-01-13T15:10:48.335Z","0.0.0-next-cb3371cdb3289f37402f09c6388269e88c943a81":"2023-01-13T17:38:38.639Z","0.0.0-next-f6dcd616f47e1d3843402c3e0f47d541edec53f3":"2023-01-14T19:48:46.398Z","0.0.0-next-6900ac52ffc5e2e7ef959752bc33235dc12946e4":"2023-01-16T14:42:54.240Z","0.0.0-next-d09be9dbbff785d6692110b819e06b0186bd3ac7":"2023-01-16T21:59:30.248Z","0.0.0-next-b72d7d0f94c6cd6b83966a08494549408ed56560":"2023-01-20T15:15:04.695Z","0.0.0-next-288585a9b69e86c5bb1bfcf4b6df1f5db45ad7bf":"2023-01-26T02:24:28.539Z","0.0.0-next-9c2b4b0b01c61fc3051beeb16fa883130e745d9b":"2023-02-02T04:11:09.709Z","5.1.1":"2023-02-02T09:36:56.724Z","0.0.0-next-cfe9a829fd77fc84e090f2c7b38663167071ebc5":"2023-02-02T22:41:38.043Z","0.0.0-next-6e4c984eb458cbfc675ec138ae979303ef32bcb5":"2023-02-02T23:25:01.306Z","0.0.0-next-1638fa3a4f457428151ba0ef06b33cfc4a77c896":"2023-02-04T16:24:48.420Z","0.0.0-next-3e67b8063fbcd84b0bfd6451e2568968fbdba25a":"2023-02-06T20:34:37.787Z","0.0.0-next-920407d9fa8e9bc60bfc2577492e5be59254432e":"2023-02-06T20:35:16.181Z","0.0.0-next-7bfb57937adf16eda85ca92547ea5711d120b4c1":"2023-02-06T20:38:42.224Z","0.0.0-next-3b389244f7eb06219ec1e923cac29b45a6ec3e84":"2023-02-06T20:40:00.996Z","0.0.0-next-014cd3f52319f9c3e62d458f4c10e0af7ae98052":"2023-02-13T23:32:37.985Z","0.0.0-next-887a3dabb2b894331aec6aa894bc425e2dc591b5":"2023-02-15T00:05:13.434Z","0.0.0-next-c5eba7335c2da0b9754b4e52495c98f48ec15463":"2023-02-15T10:49:17.130Z","0.0.0-next-9acb1d074fcbf6aa34b275f617178f0f155ff495":"2023-02-20T21:34:03.426Z","5.1.2":"2023-02-24T20:46:40.169Z","0.0.0-next-7675c98b3881009dcc19690b66a6e63e65e1a13c":"2023-02-26T18:50:56.616Z","0.0.0-next-e5f447d1d4e3c5e91efdf6c7e380240ff610dc24":"2023-03-02T08:38:41.302Z","5.1.3":"2023-03-03T09:41:51.344Z","0.0.0-next-e0e7275f55471eecce19ff3b75439fb06dce1fad":"2023-03-03T12:29:16.833Z","0.0.0-next-04ba59a8ace9d68fd90d540d8a8936985115e22e":"2023-03-18T12:33:35.117Z","0.0.0-next-ed8f90bd71f084cb541f99b15caf3833ec6a953c":"2023-03-20T20:56:56.310Z","0.0.0-next-97c3945c3938ec09f9aa141b791f53d15bd47600":"2023-03-20T20:57:39.428Z","0.0.0-next-d4e65fe0ae295543658a34afcb1bd79b9b5ecd75":"2023-03-28T15:29:53.404Z","0.0.0-next-3904cf8445c3449f8f87362208a2b0448f57aded":"2023-03-28T19:35:43.785Z","0.0.0-next-a863ce6adfb98ced08f9644a294f5b63b110c7d8":"2023-03-28T19:41:06.725Z","0.0.0-next-c3291a871fc2c07d3e2038cc1ad275c102e1d321":"2023-03-30T09:35:23.318Z","0.0.0-next-da0d016fdae6992001ca3f3347c293c36815df43":"2023-03-31T20:57:36.520Z","0.0.0-next-76532b01c39fab29385234ef65aac28c9e7d3e9f":"2023-03-31T20:59:37.183Z","0.0.0-next-30478c108fea9fe7d84759fb032faee28e0bbfbb":"2023-04-19T12:30:49.606Z","0.0.0-next-1f064ba7669c838cc646f440aedd0cf45c4df973":"2023-04-19T20:52:31.460Z","0.0.0-next-259fb95ccf1d41c3210676266488d0705f9b544e":"2023-04-20T01:48:21.307Z","0.0.0-next-5e29b9ff5907de09aef425352f5bb129b192e22c":"2023-04-20T18:25:33.473Z","5.1.4":"2023-04-21T10:19:03.857Z","0.0.0-next-604fdbd72ed8b3cb7869997416b51ea07fd77400":"2023-04-26T09:23:17.048Z","0.0.0-next-35420eb38f659fbfc4bff9e72644deebafef275e":"2023-04-27T01:56:52.779Z","0.0.0-next-f8695ae3010acc2686c0a530f153ebb01ddb040a":"2023-04-27T09:19:15.413Z","0.0.0-next-5965a9bfaeadf7fcf283dfd3fe19aa58f68c5c1c":"2023-04-27T21:45:18.101Z","0.0.0-next-c7e6e3b221454842020aa1a9adedb2461878d995":"2023-04-27T22:12:29.017Z","0.0.0-next-07a892207f0c33a49a10f047b8e98d59fb1df676":"2023-05-03T06:04:05.738Z","0.0.0-next-3871489afff599d3c0e5827b05c6cd97787625bb":"2023-05-03T17:50:45.701Z","0.0.0-next-27b7937b9a9b4fc9415bbd7962fe0f6b00d4be5d":"2023-05-03T17:51:08.928Z","0.0.0-next-23c47176cb8ae215c36676e7e063cfda61b887ea":"2023-05-03T18:25:06.801Z","0.0.0-next-28d3c6ea9e684b19e4fcfd38c8b4e94fba06844f":"2023-05-04T07:28:18.488Z","0.0.0-next-6c80d388bff8033f8ad0136897982d9caae9b2d0":"2023-05-31T22:24:28.108Z","0.0.0-next-0189b6f6005b078db9424856c7565117e3b45ef3":"2023-06-02T23:41:27.597Z","0.0.0-next-2bd69249c64bee9c103212c46e5c582418f87054":"2023-06-02T23:43:05.831Z","0.0.0-next-e182f845553cf87006baf04d22367061288c5226":"2023-06-03T00:32:26.144Z","0.0.0-next-2d8cfc600e1d4de8c32643b601d0c021734b31ed":"2023-06-03T00:53:42.644Z","0.0.0-next-c2ee6dc98a012b4f4494e197ec69ca57d395b8fa":"2023-06-03T01:03:58.169Z","0.0.0-next-5d4d8579be24c292424443140492919b337a3b28":"2023-06-03T08:35:37.514Z","5.1.5":"2023-06-05T10:34:23.997Z","0.0.0-next-e3e38f7d039860a6114dcb42a77f550e236b18ba":"2023-06-06T08:37:07.102Z","0.0.0-next-5e0eb3ba4d40569bc6acb4383f7c85221ebc81fa":"2023-06-06T11:26:11.616Z","0.0.0-next-52e439f268b74410212a0d91a5ee39021eb44499":"2023-06-06T11:27:28.591Z","0.0.0-next-5dfa7c0dfa9690d09de616d9a4839fde1ab0e467":"2023-06-08T06:58:29.914Z","0.0.0-next-1d02bfb24078b4391bee7a83e34cb3d7da39a731":"2023-06-08T07:01:48.573Z","0.0.0-next-b2733835a3b65a4990e1af518669453fad1aba04":"2023-06-08T07:06:14.655Z","0.0.0-next-b308d1e92f7e65f426e7cdde2c630c5eb26cd4e1":"2023-06-08T08:10:36.627Z","0.0.0-next-a163d3eea7baaadc9ff00f56212f6befadf68cc1":"2023-06-10T02:50:44.258Z","0.0.0-next-e35a108a54700c3d0f1f8d937fe870db23cb1682":"2023-06-10T03:58:29.607Z","0.0.0-next-80a9e175edd3eabee53daee876d77943872e4205":"2023-06-12T22:53:06.682Z","0.0.0-next-707fe01258204f4be98f1b7a6cffef62deed0b66":"2023-06-13T10:09:28.899Z","0.0.0-next-58b07e3b9faef89f8f737552ca57d6db6e0ea503":"2023-06-14T23:06:08.780Z","0.0.0-next-a6a1fbc898ffbe115f44ef184f30cf0d9348f9c2":"2023-06-14T23:09:58.610Z","0.0.0-next-60cc295fd36171b66786a43c0396bcc8db207829":"2023-06-22T07:40:34.448Z","0.0.0-next-3ddf2b32a13c98a8713916c7c20185f8ae9a9327":"2023-06-24T03:39:22.658Z","0.0.0-next-f0a5a0fe0d39e23cbafd19676a6f8bc00f4480b5":"2023-06-24T03:41:57.858Z","0.0.0-next-99faf39dcaa3321ec39c2a4a4c7b67e04f3c753e":"2023-06-28T16:34:25.622Z","0.0.0-next-c584ad92337ea0098e7068e83ed68dd13565b7da":"2023-06-30T05:22:18.676Z","0.0.0-next-835937ee6a94b541fd12d3d0c54d829fb2d0e492":"2023-06-30T18:34:23.464Z","0.0.0-next-a7eb730693b63501028444f9ef6b634620af6e37":"2023-07-03T18:45:20.765Z","0.0.0-next-084f1c20551b15b25b3945fae7547f5321bc4128":"2023-07-03T18:47:24.648Z","0.0.0-next-9c1e839a379c1d7525de44084db049cc54c0b292":"2023-07-05T20:11:01.090Z","0.0.0-next-247cba5e738b47e2c433fd1bc2e3d0ed48142ca5":"2023-07-13T02:43:57.961Z","0.0.0-next-8c579fa95e9deb46d73653d702f7f3b0e41efeb8":"2023-07-21T02:41:43.742Z","0.0.0-next-1d0257ec5ae772888fbfb677bbacf8cd7dfb3127":"2023-07-21T03:23:48.794Z","0.0.0-next-5bb899576d8b95cb24b170e4fb80a7a4cc89beac":"2023-07-24T12:05:45.759Z","0.0.0-next-71516462af839d62ee28dd99ff05de7ed4ce8d8d":"2023-07-29T11:06:12.757Z"},"bugs":{"url":"https://jira.mongodb.org/projects/COMPASS/issues","email":"compass@mongodb.com"},"author":{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},"license":"SSPL","homepage":"https://github.com/mongodb-js/compass","keywords":["mongodb-js","preferences","settings","ampersand.js"],"repository":{"url":"git+https://github.com/mongodb-js/compass.git","type":"git"},"description":"Ampersand model mixin to persist data via various storage backends","contributors":[{"name":"Thomas Rueckstiess","email":"thomas@mongodb.com"},{"name":"Lucas Hrabovsky","email":"lucas@mongodb.com"}],"maintainers":[{"email":"satya@mongodb.com","name":"satyasinha"},{"email":"kristina.stefanova@mongodb.com","name":"kristina.stefano"},{"email":"nathan.smyth@10gen.com","name":"jarjee"},{"email":"iteng@mongodb.com","name":"devtoolsbot"},{"email":"james.wang@mongodb.com","name":"mongo-j"},{"email":"neal.beeken@mongodb.com","name":"nbbeeken"},{"email":"dbx-node@mongodb.com","name":"dbx-node"},{"email":"devtools-npm-user@mongodb.com","name":"devtools-npm-user"},{"email":"hrabovsky.lucas@gmail.com","name":"imlucas"},{"email":"me@tomr.au","name":"rueckstiess"},{"email":"dana.groff+mongodb-js@mongodb.com","name":"mongodb-js-user"},{"email":"durran@gmail.com","name":"durran"}],"readme":"","readmeFilename":""}